Are there any notable uses of m4 besides autoconf?

Does anyone know about any purpose of using m4 besides autoconf (preferably in ac or C ++), which is more than just academic excerise, because it helped solve a problem that would otherwise (for example, with "standard "preprocessor) was difficult to solve.

I ask about this because I think about how to make a C ++ project where I want to reduce or minimize redundancy using scripts, preprocessors, whatevers.

+7
source share
9 answers

I once used m4 to create a C ++ header file from a text file containing a simple version string (MAJOR.MINOR.MICRO-STATUS) and information from a disruptive program for a Windows Visual Studio project.

m4 was the smallest macro moderator that I could easily implement and use for this particular purpose.

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__ */ 

Despite the fact that it worked perfectly, it was really an experiment that I did not repeat, mainly because now I prefer to use the built-in CMake features to directly manage this material and create Visual Studio project files.

+5
source

GNU Bison uses it internally to generate C or C ++ parser files.

+5
source

I used m4 and was impressed with its capabilities, it must be a C preprocessor. I used it to generate GNU make files from simpler project descriptions.

+3
source

I once used it to create fragments of a diabolical SQL query. Printed, the request lasted almost 20 pages - about 1,200 lines, I think. I am pretty sure that I could not have done it without m4, and I am grateful that I will not have to do this anymore.


(Reply to comment ...)

IIRC (from 30 years ago), the request cited the report of the plaintiffs. Plaintiffs were classified by combinations of events in their history.

The SQL engine was unable to create a view in the view and did not support user-defined functions. Some long expressions for views, subqueries, etc., Either

  • should have been identical but not, or
  • should have been subtly different (you need a “-” instead of a “+” or a “shsapnm” instead of a “shsgpnm"), but were different in the wrong way.

The hard part was not programming.

The first difficult part was to figure out which of, say, three slightly different subtasks were correct, or do we really need three different ones, or do we really need the existing three plus one or two. (I think the answer ended up being “all of the above.”) The relevant reports needed some of these subqueries; m4 + ensure that they are the same.

The second difficult part was to create test data that could show that the request worked right in front of all the various complex plaintiff stories. I think that Joe Selco pushed me to some commercial software that Boeing used at that time - it required certain user criteria and formed a test harness and stubs for every possible combination or rearrangement. I do not remember his name.

+3
source

Sendmail provides an M4-based infrastructure for creating configuration files. Most sendmail installations I have worked with provide this as the recommended method for configuring sendmail.

+3
source

I used m4 to create C / C ++ files containing lists of struct declarations. Depending on how ugly the structure is, and if you do it right, m4 files can be easily read and edited than C / C ++ files.

+3
source

The official C ++ binding library for GTK +, gtkmm - a great project that provides the availability and accessibility of the GUK + GUI via -more-modern C ++ - uses m4 as part of its toolkit to easily create wrapper code.

(I have no connection with any G * project. I just like gtkmm and feel that it is not as well known as it could / should be, especially compared to some obvious alternatives. Also, I had no idea m4 was K & R, until I researched it for this! Neat.)

+1
source

I used M4 to automatically create DDL scripts to identify your SQL tables, C ++ code and headers to access them, and drivers to verify this. I think we also updated the scripts for backing up and refilling the tables at the same time, but 15 years have passed since I did this.

0
source

I used cpp and m4 to replace tokens in files and to create packaging files for different target platforms. now i will use ruby ​​erb for this. and while in the sun I used m4 to preprocess header files

0
source

All Articles