Are there noteworthy uses of m4 besides autoconf? [closed]
Asked Answered
C

9

10

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.

Carlie answered 18/2, 2011 at 12:53 Comment(1)
It was (maybe still is) used for sendmail configuration files. Which is probably an argument against both M4 and sendmail.Homans
O
5

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.

Octarchy answered 18/2, 2011 at 13:22 Comment(0)
T
5

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

Thach answered 18/2, 2011 at 18:27 Comment(0)
W
4

I once used it to generate pieces of a fiendish SQL query. Printed, the query ran to almost 20 pages--roughly 1200 lines, I think. I'm pretty sure I couldn't have done it without m4, and I'm thankful I won't have to do it ever again.


(Responding to a comment . . .)

IIRC (from 30 years ago), the query drove a report of plaintiffs. Plaintiffs were categorized by combinations of events their history.

The SQL engine couldn't build a view on a view, and didn't support user-defined functions. Some long expressions for derived tables, subselects, etc., either

  • should have been identical, but were not, or
  • should have been subtly different (needed '-' instead of '+', or 'shsapnm' instead of 'shsgpnm'), but were different in the wrong way.

The hard part wasn't the programming.

The first hard part was figuring out which of, say, three slightly different subselects was the right one, or whether we really needed three different ones, or whether we really needed the existing three plus one or two more. (I think the answer eventually turned out to be "all of the above".) Related reports needed some of the same subselects; m4 + make guaranteed they were the same.

The second hard part was building test data that could show the query was working right in the face of all the various, complex plaintiff histories. I think Joe Celko steered me toward some commercial software Boeing was using at the time--it took some user-defined criteria and and generated a test harness and stubs for every possible combination or permutation. I don't remember its name. (I think this is it: Logic Gem)

Wein answered 18/2, 2011 at 14:32 Comment(4)
the horror! is said query something that can be summarised in mere mortal words? ;-)Swingeing
@underscore_d: Not in a comment, but I expanded the answer.Maravedi
What a tale! I'd +1 again if I could. Thanks! I'll have to consider m4 and make more in the future; I bet several cases where I've used spreadsheet tables and formulae to generate batch files, SQL scripts, repetitive fragments of C++ (where its own macros didn't quite fit the bill), and so on might've been better served by something more like this. Still, it's definitely one of the only valid uses of spreadsheets IMO, heh.Swingeing
@Swingeing youtube.com/watch?v=RkGUowLRF5s , or to summarize, "The scariest query imaginable". That's all that really has to be said, "The scariest query imaginable" :)Sallie
P
3

I've used m4 and was impressed by its capabilities, this what C preprocessor should be. I used it to generate GNU makefiles from simpler project descriptions.

Pinon answered 18/2, 2011 at 13:59 Comment(0)
N
3

Sendmail provides an M4-based infrastructure for generating configuration files. Most sendmail installs I have worked with provide this as the recommended method of configuration sendmail.

Nodule answered 18/2, 2011 at 15:0 Comment(0)
C
3

I've used m4 to generate C/C++ files that contain lists of struct declarations. Depending on how ugly the struct is and if you do it right, the m4 files can be easier to read and edit than the C/C++ files.

Cafard answered 1/7, 2011 at 20:14 Comment(0)
S
1

The official C++ binding library for GTK+, gtkmm - an excellent project that makes the power and reach of the GTK+ GUI accessible via ever-more-modern C++ - uses m4 as part of its toolset for easily generating wrapping code.

(I have no affiliation with any G* project. I just like gtkmm a lot and feel it's not as well-known as it could/should be, especially versus certain obvious alternatives. Also, I had no idea m4 was K&R until I researched it for this! Neat.)

Swingeing answered 24/4, 2016 at 12:18 Comment(0)
R
0

I have used M4 to automatically generate DDL scripts to define your SQL tables, the C++ code and headers to access them, and the drivers to test this. I think we also updated the scripts to backup and re-populate the tables at the same time, but it has been 15+ years since I did this.

Remora answered 18/2, 2011 at 17:13 Comment(0)
O
0

I used both cpp and m4 to replace tokens in files and to generate packaging files for different target platforms. now I'll use ruby erb to do this. and while at sun I used m4 for preprocessing header files

Ostensorium answered 5/5, 2011 at 5:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.