m4 (computer language)
Paradigm | macro preprocessor |
---|---|
Designed by | Brian Kernighan, Dennis Ritchie. |
First appeared | 1977 |
Major implementations | |
GNU m4 |
m4 is a general-purpose macro processor designed by Brian Kernighan and Dennis Ritchie. m4 is an extension of an earlier macro processor m3, written by Ritchie for the AP-3 minicomputer.[1]
Use
All UNIXes make the m4 macro processor available, and POSIX has standardized it. Most users require m4 simply as a dependency of GNU autoconf, although the language is used in other contexts.
A macro processor (or a preprocessor) operates as a text-replacement tool. End-users often employ it to re-use text templates, typically in computer programming applications, but also in text editing and text-processing applications.
History
Macro processors became popular when programmers commonly used assembly language. In those early days of programming, programmers noted that much of their programs consisted of repeated text, and they invented simple means for reusing this text. Programmers soon discovered the advantages not only of reusing entire blocks of text, but also of substituting different values for similar parameters. This defined the usage range of macro processors.
Kernighan and Ritchie developed m4 in 1977, basing it on the ideas of Christopher Strachey. The distinguishing features of this style of macro preprocessing included:
- free-form syntax (not line-based like a typical macro preprocessor designed for assembly-language processing)
- the high degree of re-expansion (a macro's arguments get expanded twice: once during scanning and once at interpretation time)
The implementation of Rational Fortran used m4 as its macro engine from the beginning; and most Unix variants ship with it.
As of 2015 many applications continue to use m4 as part of the GNU Project's autoconf. It also appears in the configuration process of sendmail (a widespread mail transfer agent) and for generating footprints in the gEDA toolsuite. The SELinux Reference Policy relies heavily on the m4 macro processor.
m4 has many uses in code generation, but (as with any macro processor) problems can be hard to debug.[2]
Features
m4 offers these facilities:
- a free-form syntax, rather than line based syntax
- a high degree of macro expansion (arguments get expanded during scan and again during interpretation)
- text replacement
- parameter substitution
- file inclusion
- string manipulation
- conditional evaluation
- arithmetic expressions
- system interface
- programmer diagnostics
- programming language independent
- human language independent
- provides programming language capabilities
Unlike most earlier macro processors, m4 does not target any particular computer or human language; historically, however, its development originated for supporting the Ratfor dialect of Fortran. Unlike some other macro processors, m4 is Turing-complete as well as a practical programming language.
Unquoted identifiers which match defined macros are replaced with their definitions. Placing identifiers in quotes suppresses expansion until possibly later, such as when a quoted string is expanded as part of macro replacement. Unlike most languages, strings in m4 are quoted using the backtick (`) as the starting delimiter, and apostrophe (') as the ending delimiter. The use of separate starting and ending delimiters allows for the arbitrary nesting of quotation marks in strings, allowing a fine degree of control of how and when macro expansion takes place in different parts of a string.
Example
The following fragment gives a simple example that could form part of a library for generating HTML code. It defines a commented macro to number sections automatically:
divert(-1)
m4 has multiple output queues that can be manipulated with the
`divert' macro. Valid queues range from 0 to 10, inclusive, with
the default queue being 0.
Calling the `divert' macro with an invalid queue causes text to be
discarded until another call. Note that even while output is being
discarded, quotes around `divert' and other macros are needed to
prevent expansion.
# Macros aren't expanded within comments, meaning that keywords such
# as divert and other built-ins may be used without consequence.
# HTML utility macro:
define(`H2_COUNT', 0)
# The H2_COUNT macro is redefined every time the H2 macro is used:
define(`H2',
`define(`H2_COUNT', incr(H2_COUNT))<h2>H2_COUNT. $1</h2>')
divert(1)dnl
dnl
dnl The dnl macro causes m4 to discard the rest of the line, thus
dnl preventing unwanted blank lines from appearing in the output.
dnl
H2(First Section)
H2(Second Section)
H2(Conclusion)
dnl
divert(0)dnl
dnl
<HTML>
undivert(1)dnl One of the queues is being pushed to output.
</HTML>
Processing this code with m4 should generate the following text:
<HTML>
<h2>1. First Section</h2>
<h2>2. Second Section</h2>
<h2>3. Conclusion</h2>
</HTML>
Free software implementations
A GNU version of m4 exists.[3][4] FreeBSD, NetBSD, and OpenBSD also provide independent implementations of the m4 language. Furthermore, the Heirloom Project Development Tools includes a free version of the m4 language, derived from OpenSolaris.
See also
References
- ↑ Brian W. Kernighan and Dennis M. Ritchie. The m4 macro processor. Technical report, Bell Laboratories, Murray Hill, New Jersey, USA, 1977. pdf
- ↑ Kenneth J. Turner. Exploiting the m4 macro language. Technical Report CSM-126, Department of Computing Science and Mathematics, University of Stirling, Scotland, September 1994. pdf
- ↑ GNU m4 web site "GNU M4", accessed 7 Oct 2010.
- ↑ GNU m4 manual, online and for download in HTML, PDF, and other forms. "GNU M4 — GNU macro processor", accessed 7 Oct 2010.