Reputation: 1246
My program writes to a log and to stdout. Every message, however, has a certain priority and the user specifies in Preferences which priorities go to which stream (log or stdout).
unsigned short PRIO_HIGH = 0x0001;
unsigned short PRIO_NORMAL = 0x0002;
unsigned short PRIO_LOW = 0x0004;
The preferences is handled by some flags:
unsigned short PRIO_LOG = (PRIO_HIGH | PRIO_NORMAL);
unsigned short PRIO_STD = (PRIO_HIGH);
The write_log
function should work with the same parameters as the printf function, with the added parameter of unsigned short priority
.
write_log((PRIO_NORMAL|PRIO_LOW), "HELLO %s, take %d", "World", 1);
(Even if PRIO_NORMAL|PRIO_LOW
makes little sense...)
Checking the flags is easy: if(priority & PRIO_LOG)
(Returns >1 if any flag is set in both arguments)
I cannot however find out how I would go about passing the string literal and the format arguments to the printf function. Can anyone help or give me a pointer (possible to an alternative method that achieves the same effect)? It would be much appreciated.
Upvotes: 30
Views: 40656
Reputation: 9994
You want to call vprintf() instead of printf() using the variable arguments "varargs" capabilities of C.
#include <stdarg.h>
int write_log(int priority, const char *format, ...)
{
va_list args;
va_start(args, format);
if(priority & PRIO_LOG)
vprintf(format, args);
va_end(args);
}
For more information, see something along the lines of this.
Upvotes: 72
Reputation: 3366
If you want the PRIO_* definitions to be used as bit (using | and &), you must give each one of them its own bit:
unsigned short PRIO_HIGH = 0x0001;
unsigned short PRIO_NORMAL = 0x0002;
unsigned short PRIO_LOW = 0x0004;
The macro can be improved by using the do { } while (0) notation. It makes the calls to write_log act more like a statement.
#define write_log(priority,format,args...) do { \
if (priority & PRIO_LOG) { \
printf(format, ## args); \
} while(0)
Upvotes: 4
Reputation: 14203
I think Jeff's idea is the way to go, but you can also accomplish this with a macro without using vprintf. This might require gcc:
#define write_log(priority,format,args...) \
if (priority & PRIO_LOG) { \
printf(format, ## args); \
}
Check here for info about how this works.
Upvotes: 11