A common issue in writing C based test tools is the desire to be able to show a user a list of all enums. This, of course, is technically impossible, as the mapping from enum to int is one way only. However, the following trick lets you create a two dimensional character array who’s index is the enum (cast to int, to be pedantic) is an index to a string containing the name of the enum.
First, we have the header file containing a list of things to put in the enum. For example, let’s take the following constants, representing a function. We’ll further add that our coding standard tells us to define this enum’s elements as E_MODULE_FUNCTION<ENUM_NAME>
.
In functions.h
:
FUNCTION(foo)
FUNCTION(bar)
FUNCTION(funky_function)
We then create another file named foo.h
, which will contain our enum and an extern declaration for the string. To prevent the memory from being initialized multiple times, the actual array will be declared in a .c
file:
foo.h
:
#define MAX_FUNC_NAME_LENGTH 50
#undef FUNCTION
#define FUNCTION(x) E_MODULE_FUNCTION_##x,
typedef enum _FUNCTIONS {
E_MODULE_FUNCTION_FIRST,
#include "functions.h"
E_MODULE_FUNCTION_LAST
} FUNCTIONS;
extern char function_names[][MAX_FUNC_NAME_LENGTH];
One note. You don’t need the _FIRST or _LAST enums, but I find them useful. The _LAST enum in particular is nice because it lets us eliminate the comma from the last element (which is legal in C99, but not in ANSI C, IIRC).
In your foo.c
file, add the following:
#include "foo.h"
#undef STRINGIFY
#undef FUNCTION
#define STRINGIFY(x) #x
#define FUNCTION(x) STRINGIFY(E_MODULE_FUNCTION_##x),
char DSIM_function_names[][MAX_FUNC_NAME_LENGTH] = {
"E_MODULE_FUNCTION_FIRST",
#include "functions.h"
"E_MODULE_FUNCTION_LAST"
};
Note the use of a nested #define
. I’ll be writing another post to explain a little more about that later.