I applied X-macro mechanism to get enumeration-to-string relation.
#define CMD_TABLE \
X(cmd_A)\
X(cmd_B)\
////////////////////////////////////
typedef enum
{
EMPTY,
#define X(x) x,
CMD_TABLE
#undef X
}cmd_t;
////////////////////////////////////
const static struct
{
char* name;
cmd_t index;
} conversionMap[] = {
#define X(x) {#x, x},
CMD_TABLE
#undef X
};
Then, this function converts string to enum.
cmd_t str2enum(const char* str);
Finally, corresponding function is called by treating enum as the index of array.
(*func[index])();
This method has a big problem that it force programmer to remember enum-to-function mapping relationship.
In other words, in initialization stage, the order of following functions
void (*func[])(void) =
{
&cmd_A_function,
&cmd_B_function,
};
needs to be as same as that of CMD_TABLE.
Further, once CMD_TABLE grows, code is getting worse to maintain because
if a command is not going to support, people might delete wrong line in array of function pointer.
if I want to know what does
cmd_Zdo, I have to count up from 1 to 26.list of
CMD_TABLEandvoid (*func[])(void)will be far away from each other such that programmer needs to write code in two places in order to add one feature.
You have already used X-macro twice.
You can use it a third time.
Here is a proposal how to do that, using the ugly undef-using pattern you applied the first two times: