4

I have this:

#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION b
#define VERSION VERSION_MAJOR.VERSION_MINOR REVISION
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)
integer version_major = VERSION_MAJOR;
integer version_minor = VERSION_MINOR;
string revision = STRINGIFY(REVISION);
string version_string = STRINGIFY(VERSION);

However, this sets version_string to "1.0 b". I want to eliminate the space between VERSION_MINOR and REVISION. I've tried this:

#define VERSION VERSION_MAJOR.VERSION_MINOR##REVISION

but it produces "1.VERSION_MINORREVISION". Obviously, this doesn't work either:

#define VERSION VERSION_MAJOR.VERSION_MINORREVISION

Is it possible to concatenate the two preprocessor values without having a space in between?

Update: I changed the language because the question was about the preprocessor and not about the language. I actually needed it for LSL, even though I initially formulated the question with C syntax, which is familiar to more users, but LSL does not allow forming longer string literals by making them adjacent.

Pedro Gimeno
  • 2,837
  • 1
  • 25
  • 33

2 Answers2

7

After more digging, I found that it is indeed possible, and here's how.

#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION b
#define _STRINGIFY(x) #x
#define STRINGIFY(x) _STRINGIFY(x)

/* here's the magic */
#define _CONCAT(x,y) x##y
#define CONCAT(x,y) _CONCAT(x,y)
#define VERSION VERSION_MAJOR.CONCAT(VERSION_MINOR,REVISION)

integer version_major = VERSION_MAJOR;
integer version_minor = VERSION_MINOR;
string revision = STRINGIFY(REVISION);
string version_string = STRINGIFY(VERSION);

Like STRINGIFY, the macro CONCAT needs to be defined with two levels to make it work.

The output is:

integer version_major = 1;
integer version_minor = 0;
string revision = "b";
string version_string = "1.0b";

as expected.

Pedro Gimeno
  • 2,837
  • 1
  • 25
  • 33
2

Two strings that are next to each other in C are treated as a single string and automatically concatenated. So, if you have "abc" "def", this is the same as "abcdef". Likewise, if you have macros for A and B, then #A #B would concatenate them.

For example, this code should produce the version_string that you're seeking:

#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define REVISION b
#define STRINGIFY(x) #x
#define VERSION_STR(A,B,C) STRINGIFY(A) "." STRINGIFY(B) STRINGIFY(C)
char *version_string = VERSION_STR(VERSION_MAJOR, VERSION_MINOR, REVISION);
Charles Ofria
  • 1,936
  • 12
  • 24
  • I realize that I took out a level of indirection on the STRINGIFY; it's fine if you want to put that back in for other macros. – Charles Ofria Nov 19 '16 at 16:48