How to wrap printf() into a function or macro?

Viewed 93159

This might sound like an interview question but is actually a practical problem.

I am working with an embedded platform, and have available only the equivalents of those functions:

  • printf()
  • snprintf()

Furthermore, the printf() implementation (and signature) is likely to change in the near future, so calls to it have to reside in a separate module in order to be easy to migrate later.

Given that, can I wrap logging calls in some function or macro? The goal is that my source code calls THAT_MACRO("Number of bunnies: %d", numBunnies); in a thousand places, but calls to the above functions are seen only in a single place.

Compiler: arm-gcc -std=c99

Edit: just to mention, but post 2000 best practices and probably a lot earlier, inline functions are far better than macros for numerous reasons.

8 Answers

This is a slightly modified version of @ldav1's excellent answer which prints time before the log:

#define TM_PRINTF(f_, ...)                                                                            \
{                                                                                                 \
    struct tm _tm123_;                                                                            \
    struct timeval _xxtv123_;                                                                     \
    gettimeofday(&_xxtv123_, NULL);                                                               \
    localtime_r(&_xxtv123_.tv_sec, &_tm123_);                                                     \
    printf("%2d:%2d:%2d.%d\t", _tm123_.tm_hour, _tm123_.tm_min, _tm123_.tm_sec, _xxtv123_.tv_usec); \
    printf((f_), ##__VA_ARGS__);                                                                  \
};

Below is an example wrapper for the vsprintf() function, from https://www.cplusplus.com/reference/cstdio/vsprintf/:

#include <stdio.h>
#include <stdarg.h>

void PrintFError ( const char * format, ... )
{
   char buffer[256];
   va_list args;
   va_start (args, format);
   vsprintf (buffer,format, args);
   perror (buffer);
   va_end (args);
}

Following the example above, one can implement wrappers for other desired functions from <stdio.h>.

Related