I have
#file debug.h
#ifndef PDEBUG
#define PDEBUG(msg ...)\
logger_write(logger_stdout, (struct log) {\
.level_target = LOGLEV_DEBUG,\
.message = msg,\
.properties = strdict_make_from_va(__VA_ARGS__, 0)\
})
#endif
#include "err_multi.h"
and
#file err_multi.h
#ifdef PDEBUG
#define TRY(expr, ...) {\
maybe _err = (expr);\
switch(_err.code) {\
case ERR_OK: break;\
__VA_ARGS__ \
case ERR_UNKNOWN:\
default:\
PDEBUG(\
"Unhandled err, code {_err.code}: {_err.detail}",\
"_err.code", _err.code,\
"_err.detail", _err.detail\
);\
return _err;\
}\
}
#endif
This second file, err_multi.h, does not #include debug.h, which is why ifdef PDEBUG is there. err_multi.h does not have include guards, it's a file which only has #defines and is intended to be included multiple times to redefine the macros from site to site as desired. The file that #includes err_multi.h is allowed to provide (or not) its own PDEBUG.
Finally, I have debug.c which has the following:
#file debug.c
#include "debug.h"
void do_something(void) {
TRY(get_log_message( &fmsg, msg, properties ));
}
(since debug.h defines PDEBUG, err_multi.h receives that definition)
debug.c is expanding to
{
maybe _err = (get_log_message(&fmsg, msg, properties));
switch (_err.code) {
case ERR_OK:
break;
case ERR_UNKNOWN:
default:
(logger_write(
logger_stdout,
(struct log){.level_target = LOGLEV_DEBUG,
.message = "Unhandled err, code {_err.code}: {_err.detail}",
"_err.code", _err.code,
"_err.detail", _err.detail,
.properties = strdict_make_from_va(__VA_ARGS__, 0)}));
return _err;
}
}
The problem is on that last line there: When PDEBUG is expanding, __VA_ARGS__ is not getting replaced. What's up with that? Sorry, I know this is kind of a tangle of files.
struct log is:
#file debug.h
struct log {
uint64_t level_target;
char* message;
struct strdict properties;
};
struct strdict is:
#file dict1.h
struct strdict {
ptrdiff_t n;
char **keys;
char **vals;
};
struct strdict strdict_make_from_va(...);
#define PDEBUG(msg ...) needs to be #define PDEBUG(msg, ...). Note the comma
# define identifier lparen identifier-list , ... ) replacement-list new-line