X-Macro - conditional extern generation

Posted by Nick Cash on Mon 23 Feb 2009 04:02 PM — 4 posts, 20,994 views.

USA #0
Hello all!

I am working on a system in C to auto-generate some tables for me based off of some information I have in a header file. I have everything working just fine, except for this part. I need to get it to generate extern prototypes, but only if a callback function is present. If I put NULL in the macro definition in the other file I don't want anything to be generated. An example of what I'm doing is below:


#define MACRO(NAME, CB) extern void CB( int id, int value );
   #include "Handler_Definitions.h"
#undef MACRO


And in Handler_Definitions.h would be:

MACRO(Object1, Generic_Callback)
MACRO(Object2, NULL)


How can I make it conditional? I haven't found any way to get the preprocessor to make it work the way I want. The macro for Object1 works just fine, but quite obviously Object2 will break things.
Australia Forum Administrator #1
I'm not sure you can do it. A first pass that scans the appropriate file using Perl, Lua, or some other similar language, and converts "Handler_Definitions.h" appropriately might be your solution.
USA #2
I don't know how to put macros within macros -- that is, how to define a macro that uses more preprocessor definitions like #if statements inside the macro -- or even if it is indeed possible in the first place.

How is the .h file generated? If you know that you're putting in a NULL, can you not just put in nothing instead, or even omit the line entirely?

It might be easier to do as Nick suggested and write a simple filter in Perl that does this for you.

Actually, here is one that does just what you want:


#!/usr/bin/perl

while (<STDIN>) {
    if (/MACRO\((.*), (.*)\)/) {
        if ($2 ne "NULL") {
            print "extern void $2(int id, int value);\n"
        }
    } else {
        print;
    }
}



Running it:


$ cat Handler_Definitions.h

some_line;

MACRO(Object1, Generic_Callback)
MACRO(Object2, NULL)

some_other_line;

$ cat Handler_Definitions.h| perl filter.pl

some_line;

extern void Generic_Callback(int id, int value);

some_other_line;

$
USA #3
Thanks for the Perl script. However, we decided we didn't want another step in the process. The .h file with all of the macro definitions is created by hand, so we just made a second macro that doesn't provide a callback.