|
Unix Programming - Applying Minilanguages - Case Study: m4
Case Study: m4
The
m4(1)
macro processor interprets a declarative minilanguage for describing
transformations of text. An m4 program is
a set of macros that specifies ways to expand text strings into other
strings. Applying those declarations to an input text with m4
performs macro expansion and yields an output text. (The
C
preprocessor performs similar services for C compilers,
though in a rather different style.)
Example8.2 shows an
m4 macro that directs
m4 to expand each occurrence of the string
"OS" in its input into the string "operating system" on output. This
is a trivial example; m4 supports macros
with arguments that can be used to do more than transform one fixed
string into another. Typing info m4 at your shell
prompt will probably display on-line documentation for this
language.
Example8.2.A sample m4 macro.
define(`OS', `operating system')
The m4 macro language supports
conditionals and recursion. The combination can be used to implement
loops, and this was intended; m4 is
deliberately Turing-complete. But actually trying to use
m4 as a general-purpose language would be
deeply perverse.
The m4 macro processor is usually
employed as a preprocessor for minilanguages that lack a built-in
notion of named procedures or a built-in file-inclusion feature. It's
an easy way to extend the syntax of the base language so the
combination with m4 supports both these
features.
One well-known use of m4 has been to
clean up (or at least effectively hide) another minilanguage design
that was called out as a bad example earlier in this chapter. Most
system administrators now generate their
sendmail.cf configuration files using an
m4 macro package supplied with the
sendmail distribution. The macros
start from feature names (or name/value pairs) and generate the
corresponding (much uglier) strings in the
sendmail configuration language.
Use m4 with caution, however. Unix
experience has taught minilanguage designers to be wary of macro
expansion,[83] for reasons we'll discuss later in the chapter.
[an error occurred while processing this directive]
|