Reputation: 5054
I'm having a problem in a program I'm working on. I'm trying in --help to display which features are compiled in or not. However, there are quite alot of these and the "normal" way is too verbose. E.g.:
#ifdef HAVE_FOO
static const bool have_foo = true;
#else
static const bool have_foo = false;
#endif
printf("Support for foo: %s\n", have_foo ? "yes" : "no");
Now, since I have to do this basically for every feature, it will be loads of lines, which I do not want.
So I thought I'd write some macros for it:
#define _SUPP(X) #ifdef HAVE_##X \
static const bool _##X##_SUPP = true; \
#else \
static const bool _##X##_SUPP = false; \
#endif
#define _PRINTSUPP(var, name, desc) printf("\t%s - %s: %s\n", name, desc, _##var##_SUPP ? "yes" : "no")
However, there is an issue here. The macro will be expanded to a single line, and the preprocessor chokes on this. Is there a way to generate a macro with actual newlines inbetween, or is it possible to evaluate an #ifdef
on a single line?
Upvotes: 1
Views: 1363
Reputation: 84151
You cannot do this in C. The usual approach is to generate such a header from some textual description in, say, Perl or Python.
Upvotes: 2
Reputation: 363487
If, instead of not defining HAVE_FOO
, you define it to 0
, you can do:
const struct {
bool present;
const char *name;
} features[NFEATURES] = {
{HAVE_FOO, "foo"},
{HAVE_BAR, "bar"},
...
};
for (size_t i=0; i < NFEATURES; i++)
if (features[i].present)
printf(" ... and we've got: %s\n", features[i].name);
You'll have to check for #if HAVE_FOO
instead of #ifdef HAVE_FOO
then, and your --help
message may be displayed a bit slower if your number of features runs in the zillions (in which case I'd recommend a different architecture anyway).
Upvotes: 3
Reputation: 123458
You cannot use a macro to create another preprocessing directive. All preprocessing directives are recognized before macro expansion begins, so your macro will be interpreted as erroneous C code.
Upvotes: 0