Search code examples
c-preprocessorlinden-scripting-language

Concatenate preprocessor defines to form a string


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.


Solution

  • 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.