Search code examples
c++cpreprocessorautoconfm4

Are there noteworthy uses of m4 besides autoconf?


Does someone know of any uses of m4 besides autoconf (preferably in a c or c++ environment) that is more than just an academic excerise, because it helped solve a problem that would otherwise (for example with a 'standard' preprocessor) have been difficult to solve.

I ask this because I am thinking about a way to do a project in c++ where I want to reduce or minimize redundancies by using scripts, preprocessors, whatevers.


Solution

  • I have once used m4 to generate a C++ header file from a text file containing a simple version string (MAJOR.MINOR.MICRO-STATUS), and information from subversion, for a Windows Visual Studio project.

    m4 was the smallest macro engine that I could easily embed and use for this specific goal.

    It looked like this:

    #ifndef __VERSION_H__
    #define __VERSION_H__
    divert(-1)
    define(`CPP_DEFINE', `#define $1 $2')
    define(`VERSION', include(`version.txt'))
    define(`MY_SOFTWARE_MAJOR', regexp(VERSION, `\([0-9]+\)\.[0-9]+\.[0-9]+', `\1'))
    define(`MY_SOFTWARE_MINOR', regexp(VERSION, `[0-9]+\.\([0-9]\)+\.[0-9]+', `\1'))
    define(`MY_SOFTWARE_MICRO', regexp(VERSION, `[0-9]+\.[0-9]+\.\([0-9]\)+', `\1'))
    define(`MY_SOFTWARE_STATUS', regexp(VERSION, `\(-\w+\)', `\1'))
    define(`SVN_REV', `regexp(esyscmd(svnversion -n), `[0-9]+', `\&')')
    ifelse(len(SVN_REV), 0, `define(`NO_SVN')')
    divert
    CPP_DEFINE(MY_SOFTWARE_VERSION, format(`"%s.%s.%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO))
    CPP_DEFINE(PRODUCT_VERSION, format(`"%s.%s.%s%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO, MY_SOFTWARE_STATUS))
    CPP_DEFINE(COPYRIGHT_NOTICE, `"Copyright (C) 2008 - Me"')
    ifdef(`NO_SVN', `
    CPP_DEFINE(ABOUT_VERSION, format(`"My Software Version %s.%s.%s%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO, MY_SOFTWARE_STATUS))
    CPP_DEFINE(FILE_VERSION, format(`"%s.%s.%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO))
    CPP_DEFINE(INFO_VERSION, format(``%s,%s,%s,0'', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO))
    ', `
    CPP_DEFINE(ABOUT_VERSION, format(`"My Software Version %s.%s.%s.%s%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO, SVN_REV, MY_SOFTWARE_STATUS))
    CPP_DEFINE(FILE_VERSION, format(`"%s.%s.%s.%s"', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO, SVN_REV))
    CPP_DEFINE(INFO_VERSION, format(``%s,%s,%s,%s'', MY_SOFTWARE_MAJOR, MY_SOFTWARE_MINOR, MY_SOFTWARE_MICRO, SVN_REV))
    ')
    #endif /* __VERSION_H__ */
    

    Although it worked perfectly, this really was an experiment that I did not reiterate, mainly because I now prefer using CMake's builtin capabilities to handle that stuff directly and generate my Visual Studio project files.