CodeGeneration

Code generation in C with the pre-processor.

Applied X-Macros

include

define ERRORS(_) \

_(NO_ERROR, 0x00) \  
/* discontiguous  */ \  
_(EMPTY, 0x02) \  
_(OVERFLOW, 0x03) \  
_(TIMEOUT, 0x04) \  

/** X-Macro to define ERROR_ enum entries */

define AS_ENUM(name, ID) ERROR_##name = ID,

/** X-Macro to define {"ERROR_FOO", ID} struct table entries */

define AS_LIST(name, ID) {#name, ID},

/** Register Enum /
enum ERROR {
/
Generate enum elements with X-Macro */
ERRORS(AS_ENUM)

ERROR_MAX  

};

/**

  • Error List Generated by X-Macro @ref AS_LIST.
  • Works with non-contiguous sets.
    /
    static const struct ErrorEntry {
    char
    name;
    enum ERROR id;
    } ERROR_LIST[] = {
    ERRORS(AS_LIST)
    };

void PrintAll(void)
{
size_t idx = ;

for (idx = ;  
     idx < sizeof(ERROR_LIST)/sizeof(ERROR_LIST[]);  
     idx++)  
{  
    const struct ErrorEntry* reg = &ERROR_LIST[idx];  
    printf("Error message 0x%x is \"%s\"\n", reg->id, reg->name);  
}  

}

int main(void)
{
PrintAll();
}

$[Get Code]4

Method

  1. ERRORS(AS_ENUM) expands to enum ERROR {
    /* Generate enum elements with X-Macro */
    AS_ENUM(NO_ERROR, 0x00) \
    AS_ENUM(EMPTY, 0x02) \
    ...

    ERROR_MAX  
    

    };

    $[Get Code]5

  2. Each of these is then expanded again by the preprocessor to enum ERROR {
    ERROR_NO_ERROR = 0x00,
    ERROR_EMPTY = 0x02,
    ...

    ERROR_MAX  
    

    };

    $[Get Code]6

  3. Similar expansion applies for the ERROR_LIST struct list entries

Protocol Messages