0

I have a debug system where I want to use a function with a code number to be printed in Terminal using printf. Currently the function is like this:

#define DEBUG(args...) general_printf(CMT_Common_Debug,args)

void general_printf(int messageCat, __const char *__restrict __format, ...)
{
    printf("[%d]",messageCat);

    printf(__format);
}

So what this function does it to call a printf preceded by a identifier code in the format [code_here]. The problem I'm facing is that something might happen that makes some time pass between the two calls to printf leading to a broken message in Terminal; this means I'll have to do a single call to printf. Unfortunately joining both parts as the following didn't work:

printf("[%d]%s",messageCat,__format);

; the %d, %u and the like were not filled. And I wasn't able to find how could I pass the ... to printf.

I consulted another developer and he suggested somehow copying the data to a buffer, merging the two parts and then printing, but that would take too much processing; I'ld like a more straight forward method.

So how could I do this?

EDIT

My question isn't exactly unique compared to the possible duplicate case, but even if it is that thread doesn't give me the solution I need, namely, how to add the int messageCat to the same call of printf or similar function.

Momergil
  • 2,213
  • 5
  • 29
  • 59
  • I agree with the other developer. The functions you need are `vasprintf` if you have it, or `vsnprintf`. – user3386109 Nov 05 '15 at 18:58
  • 2
    Possible duplicate of [Passing variable number of arguments around](http://stackoverflow.com/questions/205529/passing-variable-number-of-arguments-around) – John Bollinger Nov 05 '15 at 19:18
  • 2
    Note that changing from multiple `printf` calls to a single `printf/vsnprintf` call does not guarantee that the output from different process/threads will not be interleaved. So even if you solve that varargs problem you will not really be solving the underlying problem that you are trying to address. – kaylum Nov 05 '15 at 19:53
  • @JohnBollinger the solution shown in the marked thread isn't complete for my case, despite the question being similar. Also I'm not being able to use even the partial solution: I get compiler errors when including `cstdarg` (Qt Creator finds it, but the compiler claims "no such file or directory"). – Momergil Nov 06 '15 at 10:15
  • @kaylum no problems: what I need is that the "id + message" goes together for each call of the function, independent of calls from different threads (this assuming I understood your point) – Momergil Nov 06 '15 at 10:18
  • @Momergil The point is that even if you put "id+message" into one `printf` there is no guarantee that the string will not be broken up by the output from other threads. `printf` makes no such guarantees. – kaylum Nov 06 '15 at 10:21
  • @kaylum Oh, OK. Is there any way I could counter that? (maybe a mutex inside my custom function?) – Momergil Nov 06 '15 at 12:40

1 Answers1

0

After searching the mentioned functions and the linked provided of the supposed duplicated question, I managed to find a way to do what I want:

void general_printfL(int messageCat, int saveInLog, __const char *__restrict __format, ...)
{
#if 0
    printf("[%d|%d]",messageCat,saveInLog);
    printf(__format);
#else
    char bufTemp[1];

    const int reqBuffSize = snprintf(bufTemp,0,__format);

    char buff[reqBuffSize + 5];

    sprintf(buff,"[%d|%d]",messageCat,saveInLog);

    va_list args;

    va_start(args,__format);

    vsprintf(&buff[6],__format,args);

    va_end(args);

    printf(buff);
#endif
}

The only problem is that it's not straightforward: it needs to do quite a lot of processing for a task that otherwise should be simple since it's just a matter of putting some formatted text before __format. In this case, better solutions are awaited.

Momergil
  • 2,213
  • 5
  • 29
  • 59