Code generation in C with the pre-processor.

Applied X-Macros

  • Based on luser-droog's answer on StackOverflow
  • Code generation with Meta-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(); }

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
    };



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

        ERROR_MAX
    };
  1. Similar expansion applies for the ERROR_LIST struct list entries

Protocol Messages