i would like to pass a string via a preprocessor macro to my source code.
The desired output is something like this:
$ cc -DFOO="hello world" test.c test
$ ./test
foo says: hello world
$ cc -DFOO="GNU/linux" test.c test
$ ./test
foo says: GNU/linux
my code looks like this:
#include <stdio.h>
#define STR(s) #s
#define STRINGIFY(s) STR(s)
int main() {
const char*foo = STRINGIFY(FOO);
printf("foo says: %s\n", foo);
return 0;
}
This works nicely for many strings:
$ cc -DFOO="hello world" test.c test
$ ./test
foo says: hello world
Unfortunately, the strings i need to pass contain words that are already defined by my compiler, notably "linux" (on my Linux system, obviously). in this case, the double macro expansion for the stringification will first expand any tokens that are defined as a macro:
$ cc -DFOO="GNU/linux" test.c test
$ ./test
foo says: GNU/1
the expansion works recursively as well:
$ cc -DX="linux" -DFOO="GNU/X" test.c test
$ ./test
foo says: GNU/1
not surprisingly, it only expands full words
$ cc -DFOO="linuxers use linux" test.c test
$ ./test
foo says: linuxers use 1
So: how can i stringify a macro that contains words that are defined otherwhere, without expanding these words?
note: my build-system is automake (so I try to avoid doing too much quoting).
note2: the actual strings i'm trying to pass are filename components. so why they won't contain any whitespace or slashes, I cannot really mangle them on the C-side (e.g. passing -DFOO=LINUX
and then lowercasing the term won't work; also, I cannot be sure that nobody will put a #define LINUX 42
somewhere)