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