user3817250
user3817250

Reputation: 1043

c Macro with multiple optional arguments

I'm trying to write a debug print macro that will print the function name with the option of including format/varargs to print the parameters as well.

I've set up my modules so that each has it's on print color by adding a style variable to the individual modules and using it in my print macro.

The working print macro is as follows

//myprint.h
...
#define STYLE_UNDERLINE "\033[4m"
#define STYLE_NORMAL    "\033[0m"

#define STYLE_BLUE      "\033[0;34m"
... // more colo(u)rs here

#define PRINTF(fmt, ...) printf("%s" fmt STYLE_NORMAL, style, ##__VA_ARGS__)
...

Usage:

//myfile.c
...
static char * style = STYLE_BLUE;

void myFunc(int i) {
    PRINTF("String with no params\n");
    PRINTF("i value %d\n", i);
}

I'd like to do something similar with a PRINT_FN macro that would be used as follows

//myfile.c
...

void myFunc(int i) {
    PRINT_FN();       // just print the function name
    // equivalent to
    PRINTF("%s%s()", STYLE_UNDERLINE, __func__);

    PRINT_FN("%d", i) // print the function name and parameter
    // equivalent to
    PRINTF("%s%s(%d)", STYLE_UNDERLINE, __func__, i);
}

I can figure out a macro that almost accomplishes this, the problem being that it requires you to minimally send an empty format string.

#define PRINT_FN(fmt, ...) printf("%s" STYLE_UNDERLINE "%s(" fmt ")" STYLE_NORMAL, \
                                  style, __func__, ##__VA_ARGS__)

Is there a way I can also make the fmt parameter optional?

Upvotes: 4

Views: 1400

Answers (1)

M Oehm
M Oehm

Reputation: 29126

Don't try to cram everything into one printf. Separate the adornments and the actual output:

#define PRINT_FN(...)                                   \
    do {                                                \
        printf("%s%s: ", STYLE_UNDERLINE, __func__);    \
        printf("" __VA_ARGS__);                         \
        printf("%s\n", STYLE_NORMAL);                   \
    } while (0)

Concatenating an empty string leads to an empty string if the format is empty or to the original format otherwise. gcc's -Wall setting warns about an empty format string, however.

The do ... while shold be compiled away and serves to make the macro behave as one statement. Maybe overkill in yor case, but still.

Upvotes: 2

Related Questions