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
};
- Similar expansion applies for the ERROR_LIST struct list entries
Protocol Messages
- Generate struct serialization/deserialization routines
- https://github.com/cognomen/C-MsgGen