1

I need to change a implementation of Macro(LOGGING_MACRO) printf into syslog.

Macro Usage :

LOGGING_MACRO(5,("Value of x,y=%d,%d\n",x,y));

Def1 :

#define LOGGING_MACRO(loglevel,str) printf str;

Def2 :

#define LOGGING_MACRO(loglevel,str) syslog(loglevel,str);

Note : I cannot change the macro format :(

Def2 throws error as syslog will not accept 'str'(2nd arg) with front & back braces. [But working fine in Def1 with printf ]

Kindly suggest how to remove the 1st & last braces from 'str' inside the macro before passing 'str' to syslog.

  • Give an example how you call your macro, because this approach `printf str;` is completelly failed. – tilz0R Apr 21 '17 at 07:01
  • @tilz0R that is given in the section "Macro Usage :" – Weather Vane Apr 21 '17 at 07:02
  • Hello DYZ . Paranthesis is passed when calling the Macro. – Balaganesh.V Apr 21 '17 at 07:04
  • This is not possible what you are asking directly, but if you use local variable then it can be done. Edit: No, it can't. You failed your usage. – tilz0R Apr 21 '17 at 07:05
  • Any other ways i can edit content of 'str' inside a macro ??? – Balaganesh.V Apr 21 '17 at 07:08
  • No. You could do this with extern variable for example, but this won't work in every situation properly. When you declared your macro you weren't thinking a bit about loglevel parameter in printf. If you would need to include it, you could see your usage limitation. – tilz0R Apr 21 '17 at 07:10
  • If you define a `printf`-like function (say, `char *foo(const char *format,...)` that takes a format string and all additional parameters and returns a formatted string, then you can `#define LOGGING_MACRO(loglevel,str) syslog(loglevel,foo str);` – DYZ Apr 21 '17 at 07:18
  • @DYZ: This can work as I thought too, but it won't allow you multitasking environment. You need then mutex for loggin function. – tilz0R Apr 21 '17 at 07:22
  • @tilz0R So what? Isn't `printf` using mutex, too? – DYZ Apr 21 '17 at 07:25
  • @DYZ You think your implementation is thread safe? – tilz0R Apr 21 '17 at 07:30
  • @tilz0R My implementation of the macro is as thread-safe as the implementation of `foo()`. – DYZ Apr 21 '17 at 07:32
  • @DYZ I do agree with you. Check my answer about thread safe implementation. – tilz0R Apr 21 '17 at 07:32

1 Answers1

2

Example below will work in single thread application:

char* custom_log(const char *fmt, ...) {
    static char outputString[200]; //Adjust your size for maximal log value
    va_list args;
    va_start(args, fmt);
    vsprintf(outputString, fmt, args);
    va_end(args);
    return outputString;
}

Then modify your macro to:

#define LOGGING_MACRO(loglevel,str) syslog(loglevel, custom_log str)

Remember, this works only in single-thread mode and make sure, custom_log function is visible where custom_log function is called.

For multi-thread, you might update it like this:

#define LOGGING_MACRO(loglevel,str) do {\
    mutex_lock(); /*Lock your mutex for debug print*/ \
    syslog(loglevel, custom_log str); /*Debug*/ \
    mutex_unlock(); /*Unlock mutex*/ \
} while (0)

Keep in mind that you have to write mutex_lock and mutex_unlock functions for your requirements in your system to lock only debug functions between multi threads.

tilz0R
  • 6,949
  • 2
  • 21
  • 37