Reputation: 23
I want to use the C preprocessor to generate an option list dependent on other compile options.
(Or I can ask how I can concatenate more than one string into one definition?)
Here I have an example (avr-gcc) for what I want to do but it does not work:
// C preprocessor get option list with concatenation
#include <stdint.h>
// #define CompileOption1 1 // first compile option
#define CompileOption2 1 // second compile option
static char options[20] = " "; // string of options
/**********************************************************/
void exec_command (uint8_t opt) {
switch (opt) {
#define MAIN_COMMAND "FirstDefinition"
#ifdef CompileOption1
case 'b':
#define MAIN_COMMAND (MAIN_COMMAND ## "b")
break;
#endif
#ifdef CompileOption2
case 't':
#define MAIN_COMMAND MAIN_COMMAND ## t
break;
case 'u':
#endif
case 's':
// #define MAIN_COMMAND (MAIN_COMMAND ## "s")
break;
case 'v':
// #define MAIN_COMMAND (MAIN_COMMAND ## v)
break;
case 'r':
// #define MAIN_COMMAND "Blabla"
break;
}
// #define MAIN_COMMAND "Testomat"
strcpy(options, MAIN_COMMAND);
}
/**********************************************************/
int main(void) {
while(1) {
exec_command('v');
// doing something with the options here
}
}
I want to get the correct list of "options" saved in the string.
Compiling shows these errors:
main.c: In function ‘exec_command’:
main.c:21:0: warning: "MAIN_COMMAND" redefined [enabled by default]
main.c:13:0: note: this is the location of the previous definition
main.c:36:2: warning: implicit declaration of function ‘strcpy’ [-Wimplicit-function-declaration]
main.c:36:2: warning: incompatible implicit declaration of built-in function ‘strcpy’ [enabled by default]
main.c:36:1: error: ‘MAIN_COMMANDt’ undeclared (first use in this function)
main.c:36:1: note: each undeclared identifier is reported only once for each function it appears in
As you can see I tried out many different ways to concatenate, but none of them worked.
Maybe there is another better way to generate such a string?
Upvotes: 1
Views: 290
Reputation: 754390
I think what you'll need is code more like:
#define B_OPT
#define T_OPT
#define S_OPT
#define V_OPT
void exec_command(uint8_t opt)
{
switch (opt)
{
#define MAIN_COMMAND "FirstDefinition"
#ifdef CompileOption1
case 'b':
#undef B_OPT
#define B_OPT "b"
break;
#endif
#ifdef CompileOption2
case 't':
#undef T_OPT
#define T_OPT "t"
break;
case 'u':
#endif
case 's':
#undef S_OPT
#define S_OPT "s"
break;
case 'v':
#undef V_OPT
#define V_OPT "v"
break;
…
}
strcpy(options, MAIN_COMMAND B_OPT T_OPT S_OPT V_OPT);
#undef B_OPT
#undef T_OPT
#undef S_OPT
#undef V_OPT
}
I'm not sure whether you would #undef MAIN_COMMAND
too. At one level, the final four #undef
operations are not necessary. You can redefine the value of MAIN_COMMAND too as required; the exact requirements aren't clear.
The key point is to define macro values for the components you wish to concatenate into the final string, and then rely on string concatenation to make one string out of the relevant parts.
I'm not entirely convinced that what you're trying to do is a good idea, but I think this is one way to achieve what you seem to want.
Upvotes: 1
Reputation: 53016
You need 2 macros one
#define MAIN_COMMAND "FirstDefinition"
And then
#define MAKE_COMMAND(command) MAIN_COMMAND#command
you can read here for more information, to use it you need to do this
const char *command;
case t:
command = MAKE_COMMAND(t);
break;
and at the end of your function, assuming you have declared options
and it fits the generated string, do
strcpy(options, command);
Upvotes: 0