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