4

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?

3
  • I'd just like to get down to calling it as PRINT_FN() rather than PRINT_FN("") Commented Sep 17, 2014 at 15:55
  • Makes no sense. It won't print you a newline. Commented Sep 17, 2014 at 16:12
  • @n.m. I can't make sense of your comment. Are you suggesting all print statements require newline's? In the end I added a newline to my PRINT_FN macro but certainly not to PRINTF. Commented Sep 17, 2014 at 17:28

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

+1. Alternatively, use snprintf for the __VA_ARGS__ and then print out the complete line with one printf.
Is the ## is still needed before __VA_ARGS__?
@user3817250: No, but the macro works only if the first argument, if any, is a string literal, but that's the common case for printf-like functions. (Some compilers even warn you if you don't specify a string literal.) The gcc extension , ##__VA_ARGS suppresses the comma if the variadic argument list is empty, but we want string concatenation here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.