Home > Mobile >  Look-up table of C macros
Look-up table of C macros

Time:12-09

I'm making look-up tables between 2 drivers. I use an enum starting at index 0, which is passed to a look-up table to return an integer. This works fine.

// In library
#define LIB_FEATURE_1 0x10
#define LIB_FEATURE_2 0x22
#define LIB_FEATURE_3 0x44
#define LIB_FEATURE_4 0x42

// In my costum driver
enum features_s {
    my_feature_a = 0,
    my_feature_b = 1,
    my_feature_c = 2
};

const int feature_tbl[] = {
    LIB_FEATURE_2,   // Maps my_feature_a to LIB_FEATURE_2
    0xFF,            // Maps my_feature_b to an error code because this  
                     //     feature is not present in library
    LIB_FEATURE_4    // Maps my_feature_c to LIB_FEATURE_4
};

// In app
int value = feature_tbl[my_feature_a];

The library contains some more complicated macros (setting registers in an embedded system) :

// In library
#define LIB_FEATURE_1 do {
                    //does black magic
                } while(0)

#define LIB_FEATURE_2 do {
                    //does white magic
                } while(0)

#define LIB_FEATURE_3 do {
                    //does yellow magic
                } while(0)

#define LIB_FEATURE_4 do {
                    //does purple magic
                } while(0)

// In my costum driver
enum features_s {
    my_feature_a = 0,
    my_feature_b = 1,
    my_feature_c = 2
};

/* 
 * something missing here. I want this mapping :
 * my_feature_a executes LIB_FEATURE_2();
 * my_feature_b executes nothing
 * my_feature_c executes LIB_FEATURE_4();
 */

// In app
SOME_KIND_OF_LOOK_UP_TABLE[my_feature_a](); 

Is it possible to create a const table, or a macro that takes an index as argument and executes the right feature?

I also tried macro concatenation, but it doesn't seem to work.

I tried using a const table, and a macro concatenations

CodePudding user response:

Runtime version:

//function prototype
typedef void (*my_lib_feature_function)();

//implement feature functions
//we need an address, therefore real functions instead of macros
static void my_lib_feature_function_1() { /* feature magic 1 */ }
static void my_lib_feature_function_2() { /* feature magic 2 */ }
static void my_lib_feature_function_3() { /* feature magic 3 */ }
static void my_lib_feature_function_4() { /* feature magic 4 */ }

//feature table (lookup table)
//organize as you see fit, extend or shorten it, but
//take care of the right indices (enum values)
static const my_lib_feature_function function_table[] = {
    my_lib_feature_function_2, //index 0 -> my_feature_a
    NULL,                      //index 1 -> my_feature_b
    my_lib_feature_function_4  //index 2 -> my_feature_c
};

//invoker
//param feature is the index to the lookup table
static void invoke_my_lib_feature(enum features_s feature)
{
    if (function_table[feature] != NULL) //if entry exists
        function_table[feature]();       //execute it
}

//In app
/*either*/ //invoke_my_lib_feature(my_feature_a);
/*and/or*/ //invoke_my_lib_feature(my_feature_b);
/*and/or*/ //invoke_my_lib_feature(my_feature_c);

Compiletime version:

//pp util (concatenation)
#define CAT(A,B) CAT_(A,B)
#define CAT_(A,B) A##B

//instead of enum (unfortunately, we can't use enum values here)
#define MY_FEATURE_A 0
#define MY_FEATURE_B 1
#define MY_FEATURE_C 2

//feature table
#define LIB_FEATURE_ENTRY_0 LIB_FEATURE_2 //-> MY_FEATURE_A
#define LIB_FEATURE_ENTRY_1 //empty       //-> MY_FEATURE_B
#define LIB_FEATURE_ENTRY_2 LIB_FEATURE_4 //-> MY_FEATURE_C

//invoker
#define INVOKE_LIB_FEATURE(IDX) CAT(LIB_FEATURE_ENTRY_,IDX)

//In App
/*either*/ //INVOKE_LIB_FEATURE(MY_FEATURE_A); //expands to text after LIB_FEATURE_2
/*and/or*/ //INVOKE_LIB_FEATURE(MY_FEATURE_B); //empty
/*and/or*/ //INVOKE_LIB_FEATURE(MY_FEATURE_C); //expands to text after LIB_FEATURE_4
  • Related