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