Few C programmers take advantage of the power of #undef
, specifically redefining a macro for your current purposes. This allows you to set up all of your data in a single readable table that can be updated and modified in 1 place.
#define FUNCTION_MAP { \
MAP(ID_NOP_FUNCTION, NULL), \
MAP(ID_PRINT_FUNCTION, Print), \
MAP(ID_READ_FUNCTION, Read), \
MAP(ID_WRITE_FUNCTION, Write), \
MAP(ID_PROCESS_FUNCTION, Process), \
}
#define MAP(x,y) x
enum function_enums FUNCTION_MAP;
#undef MAP
#define MAP(x,y) y
Function_Ptr Export_Function_Table[] = FUNCTION_MAP;
#undef MAP
but wait, there's more all for the low, low price of $0 with free S&H, you can do all of your function header mumbo jumbo all in 1 place.
#define FUNCTION_MAP \
/* ENUM Function, return, Arguments ... */ \
MAP(ID_PRINT_FUNCTION, Print, int, char *fmt, va_list *ap ) \
MAP(ID_READ_FUNCTION, Read, int, int fd, char *buf, size_t len) \
MAP(ID_WRITE_FUNCTION, Write, int, int fd, char *buf, size_t len) \
MAP(ID_PROCESS_FUNCTION, Process,int, int )
//function enums
#define MAP(x,y,...) x,
enum function_enums { FUNCTION_MAP };
#undef MAP
//function pre-definitions with unspecified number of args for function table
#define MAP(x,fn_name,ret,...) ret fn_name();
FUNCTION_MAP
#undef MAP
//function tables with unspecified number of arguments
#define MAP(x,y,...) y,
typedef int (*Function_Ptr)();
Function_Ptr Export_Function_Table[] = { FUNCTION_MAP };
#undef MAP
//function definitions with actual parameter types
#define MAP(x,fn_name,ret,...) ret fn_name(__VA_ARGS__);
FUNCTION_MAP
#undef MAP
//function strings ... just in case we want to print them
#define MAP(x,y,...) #y,
const char *function_strings[] = { FUNCTION_MAP };
#undef MAP
//function enum strings ... just in case we want to print them
#define MAP(x,y,...) #x,
const char *function_enum_strings[] = { FUNCTION_MAP };
#undef MAP
#undef FUNCTION_MAP
Now you can just add each new function in one place at the top of this header, preferably to the end of FUNCTION_MAP if you want to preserve backward compatibility as a library... otherwise you can just list them alphabetically.