7859 lines
293 KiB
Plaintext
7859 lines
293 KiB
Plaintext
This is m4.info, produced by makeinfo version 4.13 from m4.texinfo.
|
||
|
||
This manual (5 March 2009) is for GNU M4 (version 1.4.13), a package
|
||
containing an implementation of the m4 macro language.
|
||
|
||
Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2004, 2005, 2006,
|
||
2007, 2008, 2009 Free Software Foundation, Inc.
|
||
|
||
Permission is granted to copy, distribute and/or modify this
|
||
document under the terms of the GNU Free Documentation License,
|
||
Version 1.2 or any later version published by the Free Software
|
||
Foundation; with no Invariant Sections, no Front-Cover Texts, and
|
||
no Back-Cover Texts. A copy of the license is included in the
|
||
section entitled "GNU Free Documentation License."
|
||
|
||
INFO-DIR-SECTION Text creation and manipulation
|
||
START-INFO-DIR-ENTRY
|
||
* M4: (m4). A powerful macro processor.
|
||
END-INFO-DIR-ENTRY
|
||
|
||
|
||
File: m4.info, Node: Top, Next: Preliminaries, Up: (dir)
|
||
|
||
GNU M4
|
||
******
|
||
|
||
This manual (5 March 2009) is for GNU M4 (version 1.4.13), a package
|
||
containing an implementation of the m4 macro language.
|
||
|
||
Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2004, 2005, 2006,
|
||
2007, 2008, 2009 Free Software Foundation, Inc.
|
||
|
||
Permission is granted to copy, distribute and/or modify this
|
||
document under the terms of the GNU Free Documentation License,
|
||
Version 1.2 or any later version published by the Free Software
|
||
Foundation; with no Invariant Sections, no Front-Cover Texts, and
|
||
no Back-Cover Texts. A copy of the license is included in the
|
||
section entitled "GNU Free Documentation License."
|
||
|
||
GNU `m4' is an implementation of the traditional UNIX macro
|
||
processor. It is mostly SVR4 compatible, although it has some
|
||
extensions (for example, handling more than 9 positional parameters to
|
||
macros). `m4' also has builtin functions for including files, running
|
||
shell commands, doing arithmetic, etc. Autoconf needs GNU `m4' for
|
||
generating `configure' scripts, but not for running them.
|
||
|
||
GNU `m4' was originally written by Rene' Seindal, with subsequent
|
||
changes by Franc,ois Pinard and other volunteers on the Internet. All
|
||
names and email addresses can be found in the files `m4-1.4.13/AUTHORS'
|
||
and `m4-1.4.13/THANKS' from the GNU M4 distribution.
|
||
|
||
This is release 1.4.13. It is now considered stable: future
|
||
releases in the 1.4.x series are only meant to fix bugs, increase speed,
|
||
or improve documentation. However...
|
||
|
||
An experimental feature, which would improve `m4' usefulness, allows
|
||
for changing the syntax for what is a "word" in `m4'. You should use:
|
||
./configure --enable-changeword
|
||
if you want this feature compiled in. The current implementation
|
||
slows down `m4' considerably and is hardly acceptable. In the future,
|
||
`m4' 2.0 will come with a different set of new features that provide
|
||
similar capabilities, but without the inefficiencies, so changeword
|
||
will go away and _you should not count on it_.
|
||
|
||
* Menu:
|
||
|
||
* Preliminaries:: Introduction and preliminaries
|
||
* Invoking m4:: Invoking `m4'
|
||
* Syntax:: Lexical and syntactic conventions
|
||
|
||
* Macros:: How to invoke macros
|
||
* Definitions:: How to define new macros
|
||
* Conditionals:: Conditionals, loops, and recursion
|
||
|
||
* Debugging:: How to debug macros and input
|
||
|
||
* Input Control:: Input control
|
||
* File Inclusion:: File inclusion
|
||
* Diversions:: Diverting and undiverting output
|
||
|
||
* Text handling:: Macros for text handling
|
||
* Arithmetic:: Macros for doing arithmetic
|
||
* Shell commands:: Macros for running shell commands
|
||
* Miscellaneous:: Miscellaneous builtin macros
|
||
* Frozen files:: Fast loading of frozen state
|
||
|
||
* Compatibility:: Compatibility with other versions of `m4'
|
||
* Answers:: Correct version of some examples
|
||
|
||
* Copying This Package:: How to make copies of the overall M4 package
|
||
* Copying This Manual:: How to make copies of this manual
|
||
* Indices:: Indices of concepts and macros
|
||
|
||
--- The Detailed Node Listing ---
|
||
|
||
Introduction and preliminaries
|
||
|
||
* Intro:: Introduction to `m4'
|
||
* History:: Historical references
|
||
* Bugs:: Problems and bugs
|
||
* Manual:: Using this manual
|
||
|
||
Invoking `m4'
|
||
|
||
* Operation modes:: Command line options for operation modes
|
||
* Preprocessor features:: Command line options for preprocessor features
|
||
* Limits control:: Command line options for limits control
|
||
* Frozen state:: Command line options for frozen state
|
||
* Debugging options:: Command line options for debugging
|
||
* Command line files:: Specifying input files on the command line
|
||
|
||
Lexical and syntactic conventions
|
||
|
||
* Names:: Macro names
|
||
* Quoted strings:: Quoting input to `m4'
|
||
* Comments:: Comments in `m4' input
|
||
* Other tokens:: Other kinds of input tokens
|
||
* Input processing:: How `m4' copies input to output
|
||
|
||
How to invoke macros
|
||
|
||
* Invocation:: Macro invocation
|
||
* Inhibiting Invocation:: Preventing macro invocation
|
||
* Macro Arguments:: Macro arguments
|
||
* Quoting Arguments:: On Quoting Arguments to macros
|
||
* Macro expansion:: Expanding macros
|
||
|
||
How to define new macros
|
||
|
||
* Define:: Defining a new macro
|
||
* Arguments:: Arguments to macros
|
||
* Pseudo Arguments:: Special arguments to macros
|
||
* Undefine:: Deleting a macro
|
||
* Defn:: Renaming macros
|
||
* Pushdef:: Temporarily redefining macros
|
||
|
||
* Indir:: Indirect call of macros
|
||
* Builtin:: Indirect call of builtins
|
||
|
||
Conditionals, loops, and recursion
|
||
|
||
* Ifdef:: Testing if a macro is defined
|
||
* Ifelse:: If-else construct, or multibranch
|
||
* Shift:: Recursion in `m4'
|
||
* Forloop:: Iteration by counting
|
||
* Foreach:: Iteration by list contents
|
||
* Stacks:: Working with definition stacks
|
||
* Composition:: Building macros with macros
|
||
|
||
How to debug macros and input
|
||
|
||
* Dumpdef:: Displaying macro definitions
|
||
* Trace:: Tracing macro calls
|
||
* Debug Levels:: Controlling debugging output
|
||
* Debug Output:: Saving debugging output
|
||
|
||
Input control
|
||
|
||
* Dnl:: Deleting whitespace in input
|
||
* Changequote:: Changing the quote characters
|
||
* Changecom:: Changing the comment delimiters
|
||
* Changeword:: Changing the lexical structure of words
|
||
* M4wrap:: Saving text until end of input
|
||
|
||
File inclusion
|
||
|
||
* Include:: Including named files
|
||
* Search Path:: Searching for include files
|
||
|
||
Diverting and undiverting output
|
||
|
||
* Divert:: Diverting output
|
||
* Undivert:: Undiverting output
|
||
* Divnum:: Diversion numbers
|
||
* Cleardivert:: Discarding diverted text
|
||
|
||
Macros for text handling
|
||
|
||
* Len:: Calculating length of strings
|
||
* Index macro:: Searching for substrings
|
||
* Regexp:: Searching for regular expressions
|
||
* Substr:: Extracting substrings
|
||
* Translit:: Translating characters
|
||
* Patsubst:: Substituting text by regular expression
|
||
* Format:: Formatting strings (printf-like)
|
||
|
||
Macros for doing arithmetic
|
||
|
||
* Incr:: Decrement and increment operators
|
||
* Eval:: Evaluating integer expressions
|
||
|
||
Macros for running shell commands
|
||
|
||
* Platform macros:: Determining the platform
|
||
* Syscmd:: Executing simple commands
|
||
* Esyscmd:: Reading the output of commands
|
||
* Sysval:: Exit status
|
||
* Mkstemp:: Making temporary files
|
||
|
||
Miscellaneous builtin macros
|
||
|
||
* Errprint:: Printing error messages
|
||
* Location:: Printing current location
|
||
* M4exit:: Exiting from `m4'
|
||
|
||
Fast loading of frozen state
|
||
|
||
* Using frozen files:: Using frozen files
|
||
* Frozen file format:: Frozen file format
|
||
|
||
Compatibility with other versions of `m4'
|
||
|
||
* Extensions:: Extensions in GNU M4
|
||
* Incompatibilities:: Facilities in System V m4 not in GNU M4
|
||
* Other Incompatibilities:: Other incompatibilities
|
||
|
||
Correct version of some examples
|
||
|
||
* Improved exch:: Solution for `exch'
|
||
* Improved forloop:: Solution for `forloop'
|
||
* Improved foreach:: Solution for `foreach'
|
||
* Improved copy:: Solution for `copy'
|
||
* Improved m4wrap:: Solution for `m4wrap'
|
||
* Improved cleardivert:: Solution for `cleardivert'
|
||
* Improved capitalize:: Solution for `capitalize'
|
||
* Improved fatal_error:: Solution for `fatal_error'
|
||
|
||
How to make copies of the overall M4 package
|
||
|
||
* GNU General Public License:: License for copying the M4 package
|
||
|
||
How to make copies of this manual
|
||
|
||
* GNU Free Documentation License:: License for copying this manual
|
||
|
||
Indices of concepts and macros
|
||
|
||
* Macro index:: Index for all `m4' macros
|
||
* Concept index:: Index for many concepts
|
||
|
||
|
||
File: m4.info, Node: Preliminaries, Next: Invoking m4, Prev: Top, Up: Top
|
||
|
||
1 Introduction and preliminaries
|
||
********************************
|
||
|
||
This first chapter explains what GNU `m4' is, where `m4' comes from,
|
||
how to read and use this documentation, how to call the `m4' program,
|
||
and how to report bugs about it. It concludes by giving tips for
|
||
reading the remainder of the manual.
|
||
|
||
The following chapters then detail all the features of the `m4'
|
||
language.
|
||
|
||
* Menu:
|
||
|
||
* Intro:: Introduction to `m4'
|
||
* History:: Historical references
|
||
* Bugs:: Problems and bugs
|
||
* Manual:: Using this manual
|
||
|
||
|
||
File: m4.info, Node: Intro, Next: History, Up: Preliminaries
|
||
|
||
1.1 Introduction to `m4'
|
||
========================
|
||
|
||
`m4' is a macro processor, in the sense that it copies its input to the
|
||
output, expanding macros as it goes. Macros are either builtin or
|
||
user-defined, and can take any number of arguments. Besides just doing
|
||
macro expansion, `m4' has builtin functions for including named files,
|
||
running shell commands, doing integer arithmetic, manipulating text in
|
||
various ways, performing recursion, etc.... `m4' can be used either as
|
||
a front-end to a compiler, or as a macro processor in its own right.
|
||
|
||
The `m4' macro processor is widely available on all UNIXes, and has
|
||
been standardized by POSIX. Usually, only a small percentage of users
|
||
are aware of its existence. However, those who find it often become
|
||
committed users. The popularity of GNU Autoconf, which requires GNU
|
||
`m4' for _generating_ `configure' scripts, is an incentive for many to
|
||
install it, while these people will not themselves program in `m4'.
|
||
GNU `m4' is mostly compatible with the System V, Release 3 version,
|
||
except for some minor differences. *Note Compatibility::, for more
|
||
details.
|
||
|
||
Some people find `m4' to be fairly addictive. They first use `m4'
|
||
for simple problems, then take bigger and bigger challenges, learning
|
||
how to write complex sets of `m4' macros along the way. Once really
|
||
addicted, users pursue writing of sophisticated `m4' applications even
|
||
to solve simple problems, devoting more time debugging their `m4'
|
||
scripts than doing real work. Beware that `m4' may be dangerous for
|
||
the health of compulsive programmers.
|
||
|
||
|
||
File: m4.info, Node: History, Next: Bugs, Prev: Intro, Up: Preliminaries
|
||
|
||
1.2 Historical references
|
||
=========================
|
||
|
||
`GPM' was an important ancestor of `m4'. See C. Strachey: "A General
|
||
Purpose Macro generator", Computer Journal 8,3 (1965), pp. 225 ff.
|
||
`GPM' is also succinctly described into David Gries classic "Compiler
|
||
Construction for Digital Computers".
|
||
|
||
The classic B. Kernighan and P.J. Plauger: "Software Tools",
|
||
Addison-Wesley, Inc. (1976) describes and implements a Unix
|
||
macro-processor language, which inspired Dennis Ritchie to write `m3',
|
||
a macro processor for the AP-3 minicomputer.
|
||
|
||
Kernighan and Ritchie then joined forces to develop the original
|
||
`m4', as described in "The M4 Macro Processor", Bell Laboratories
|
||
(1977). It had only 21 builtin macros.
|
||
|
||
While `GPM' was more _pure_, `m4' is meant to deal with the true
|
||
intricacies of real life: macros can be recognized without being
|
||
pre-announced, skipping whitespace or end-of-lines is easier, more
|
||
constructs are builtin instead of derived, etc.
|
||
|
||
Originally, the Kernighan and Plauger macro-processor, and then
|
||
`m3', formed the engine for the Rational FORTRAN preprocessor, that is,
|
||
the `Ratfor' equivalent of `cpp'. Later, `m4' was used as a front-end
|
||
for `Ratfor', `C' and `Cobol'.
|
||
|
||
Rene' Seindal released his implementation of `m4', GNU `m4', in
|
||
1990, with the aim of removing the artificial limitations in many of
|
||
the traditional `m4' implementations, such as maximum line length,
|
||
macro size, or number of macros.
|
||
|
||
The late Professor A. Dain Samples described and implemented a
|
||
further evolution in the form of `M5': "User's Guide to the M5 Macro
|
||
Language: 2nd edition", Electronic Announcement on comp.compilers
|
||
newsgroup (1992).
|
||
|
||
Franc,ois Pinard took over maintenance of GNU `m4' in 1992, until
|
||
1994 when he released GNU `m4' 1.4, which was the stable release for 10
|
||
years. It was at this time that GNU Autoconf decided to require GNU
|
||
`m4' as its underlying engine, since all other implementations of `m4'
|
||
had too many limitations.
|
||
|
||
More recently, in 2004, Paul Eggert released 1.4.1 and 1.4.2 which
|
||
addressed some long standing bugs in the venerable 1.4 release. Then in
|
||
2005, Gary V. Vaughan collected together the many patches to GNU `m4'
|
||
1.4 that were floating around the net and released 1.4.3 and 1.4.4.
|
||
And in 2006, Eric Blake joined the team and prepared patches for the
|
||
release of 1.4.5, 1.4.6, 1.4.7, and 1.4.8. More bug fixes were
|
||
incorporated in 2007, with releases 1.4.9 and 1.4.10. Eric continued
|
||
with some portability fixes for 1.4.11 and 1.4.12 in 2008, and 1.4.13
|
||
in 2009.
|
||
|
||
Meanwhile, development has continued on new features for `m4', such
|
||
as dynamic module loading and additional builtins. When complete, GNU
|
||
`m4' 2.0 will start a new series of releases.
|
||
|
||
|
||
File: m4.info, Node: Bugs, Next: Manual, Prev: History, Up: Preliminaries
|
||
|
||
1.3 Problems and bugs
|
||
=====================
|
||
|
||
If you have problems with GNU M4 or think you've found a bug, please
|
||
report it. Before reporting a bug, make sure you've actually found a
|
||
real bug. Carefully reread the documentation and see if it really says
|
||
you can do what you're trying to do. If it's not clear whether you
|
||
should be able to do something or not, report that too; it's a bug in
|
||
the documentation!
|
||
|
||
Before reporting a bug or trying to fix it yourself, try to isolate
|
||
it to the smallest possible input file that reproduces the problem.
|
||
Then send us the input file and the exact results `m4' gave you. Also
|
||
say what you expected to occur; this will help us decide whether the
|
||
problem was really in the documentation.
|
||
|
||
Once you've got a precise problem, send e-mail to <bug-m4@gnu.org>.
|
||
Please include the version number of `m4' you are using. You can get
|
||
this information with the command `m4 --version'. Also provide details
|
||
about the platform you are executing on.
|
||
|
||
Non-bug suggestions are always welcome as well. If you have
|
||
questions about things that are unclear in the documentation or are
|
||
just obscure features, please report them too.
|
||
|
||
|
||
File: m4.info, Node: Manual, Prev: Bugs, Up: Preliminaries
|
||
|
||
1.4 Using this manual
|
||
=====================
|
||
|
||
This manual contains a number of examples of `m4' input and output, and
|
||
a simple notation is used to distinguish input, output and error
|
||
messages from `m4'. Examples are set out from the normal text, and
|
||
shown in a fixed width font, like this
|
||
|
||
This is an example of an example!
|
||
|
||
To distinguish input from output, all output from `m4' is prefixed
|
||
by the string `=>', and all error messages by the string `error-->'.
|
||
When showing how command line options affect matters, the command line
|
||
is shown with a prompt `$ like this', otherwise, you can assume that a
|
||
simple `m4' invocation will work. Thus:
|
||
|
||
$ command line to invoke m4
|
||
Example of input line
|
||
=>Output line from m4
|
||
error-->and an error message
|
||
|
||
The sequence `^D' in an example indicates the end of the input file.
|
||
The sequence `<NL>' refers to the newline character. The majority of
|
||
these examples are self-contained, and you can run them with similar
|
||
results by invoking `m4 -d'. In fact, the testsuite that is bundled in
|
||
the GNU M4 package consists of the examples in this document! Some of
|
||
the examples assume that your current directory is located where you
|
||
unpacked the installation, so if you plan on following along, you may
|
||
find it helpful to do this now:
|
||
|
||
$ cd m4-1.4.13
|
||
|
||
As each of the predefined macros in `m4' is described, a prototype
|
||
call of the macro will be shown, giving descriptive names to the
|
||
arguments, e.g.,
|
||
|
||
-- Composite: example (STRING, [COUNT = `1'], [ARGUMENT]...)
|
||
This is a sample prototype. There is not really a macro named
|
||
`example', but this documents that if there were, it would be a
|
||
Composite macro, rather than a Builtin. It requires at least one
|
||
argument, STRING. Remember that in `m4', there must not be a
|
||
space between the macro name and the opening parenthesis, unless
|
||
it was intended to call the macro without any arguments. The
|
||
brackets around COUNT and ARGUMENT show that these arguments are
|
||
optional. If COUNT is omitted, the macro behaves as if count were
|
||
`1', whereas if ARGUMENT is omitted, the macro behaves as if it
|
||
were the empty string. A blank argument is not the same as an
|
||
omitted argument. For example, `example(`a')', `example(`a',`1')',
|
||
and `example(`a',`1',)' would behave identically with COUNT set to
|
||
`1'; while `example(`a',)' and `example(`a',`')' would explicitly
|
||
pass the empty string for COUNT. The ellipses (`...') show that
|
||
the macro processes additional arguments after ARGUMENT, rather
|
||
than ignoring them.
|
||
|
||
All macro arguments in `m4' are strings, but some are given special
|
||
interpretation, e.g., as numbers, file names, regular expressions, etc.
|
||
The documentation for each macro will state how the parameters are
|
||
interpreted, and what happens if the argument cannot be parsed
|
||
according to the desired interpretation. Unless specified otherwise, a
|
||
parameter specified to be a number is parsed as a decimal, even if the
|
||
argument has leading zeros; and parsing the empty string as a number
|
||
results in 0 rather than an error, although a warning will be issued.
|
||
|
||
This document consistently writes and uses "builtin", without a
|
||
hyphen, as if it were an English word. This is how the `builtin'
|
||
primitive is spelled within `m4'.
|
||
|
||
|
||
File: m4.info, Node: Invoking m4, Next: Syntax, Prev: Preliminaries, Up: Top
|
||
|
||
2 Invoking `m4'
|
||
***************
|
||
|
||
The format of the `m4' command is:
|
||
|
||
`m4' [OPTION...] [FILE...]
|
||
|
||
All options begin with `-', or if long option names are used, with
|
||
`--'. A long option name need not be written completely, any
|
||
unambiguous prefix is sufficient. POSIX requires `m4' to recognize
|
||
arguments intermixed with files, even when `POSIXLY_CORRECT' is set in
|
||
the environment. Most options take effect at startup regardless of
|
||
their position, but some are documented below as taking effect after
|
||
any files that occurred earlier in the command line. The argument `--'
|
||
is a marker to denote the end of options.
|
||
|
||
With short options, options that do not take arguments may be
|
||
combined into a single command line argument with subsequent options,
|
||
options with mandatory arguments may be provided either as a single
|
||
command line argument or as two arguments, and options with optional
|
||
arguments must be provided as a single argument. In other words, `m4
|
||
-QPDfoo -d a -df' is equivalent to `m4 -Q -P -D foo -d -df -- ./a',
|
||
although the latter form is considered canonical.
|
||
|
||
With long options, options with mandatory arguments may be provided
|
||
with an equal sign (`=') in a single argument, or as two arguments, and
|
||
options with optional arguments must be provided as a single argument.
|
||
In other words, `m4 --def foo --debug a' is equivalent to `m4
|
||
--define=foo --debug= -- ./a', although the latter form is considered
|
||
canonical (not to mention more robust, in case a future version of `m4'
|
||
introduces an option named `--default').
|
||
|
||
`m4' understands the following options, grouped by functionality.
|
||
|
||
* Menu:
|
||
|
||
* Operation modes:: Command line options for operation modes
|
||
* Preprocessor features:: Command line options for preprocessor features
|
||
* Limits control:: Command line options for limits control
|
||
* Frozen state:: Command line options for frozen state
|
||
* Debugging options:: Command line options for debugging
|
||
* Command line files:: Specifying input files on the command line
|
||
|
||
|
||
File: m4.info, Node: Operation modes, Next: Preprocessor features, Up: Invoking m4
|
||
|
||
2.1 Command line options for operation modes
|
||
============================================
|
||
|
||
Several options control the overall operation of `m4':
|
||
|
||
`--help'
|
||
Print a help summary on standard output, then immediately exit
|
||
`m4' without reading any input files or performing any other
|
||
actions.
|
||
|
||
`--version'
|
||
Print the version number of the program on standard output, then
|
||
immediately exit `m4' without reading any input files or
|
||
performing any other actions.
|
||
|
||
`-E'
|
||
`--fatal-warnings'
|
||
Controls the effect of warnings. If unspecified, then execution
|
||
continues and exit status is unaffected when a warning is printed.
|
||
If specified exactly once, warnings become fatal; when one is
|
||
issued, execution continues, but the exit status will be non-zero.
|
||
If specified multiple times, then execution halts with non-zero
|
||
status the first time a warning is issued. The introduction of
|
||
behavior levels is new to M4 1.4.9; for behavior consistent with
|
||
earlier versions, you should specify `-E' twice.
|
||
|
||
`-i'
|
||
`--interactive'
|
||
`-e'
|
||
Makes this invocation of `m4' interactive. This means that all
|
||
output will be unbuffered, and interrupts will be ignored. The
|
||
spelling `-e' exists for compatibility with other `m4'
|
||
implementations, and issues a warning because it may be withdrawn
|
||
in a future version of GNU M4.
|
||
|
||
`-P'
|
||
`--prefix-builtins'
|
||
Internally modify _all_ builtin macro names so they all start with
|
||
the prefix `m4_'. For example, using this option, one should write
|
||
`m4_define' instead of `define', and `m4___file__' instead of
|
||
`__file__'. This option has no effect if `-R' is also specified.
|
||
|
||
`-Q'
|
||
`--quiet'
|
||
`--silent'
|
||
Suppress warnings, such as missing or superfluous arguments in
|
||
macro calls, or treating the empty string as zero.
|
||
|
||
`--warn-macro-sequence[=REGEXP]'
|
||
Issue a warning if the regular expression REGEXP has a non-empty
|
||
match in any macro definition (either by `define' or `pushdef').
|
||
Empty matches are ignored; therefore, supplying the empty string
|
||
as REGEXP disables any warning. If the optional REGEXP is not
|
||
supplied, then the default regular expression is
|
||
`\$\({[^}]*}\|[0-9][0-9]+\)' (a literal `$' followed by multiple
|
||
digits or by an open brace), since these sequences will change
|
||
semantics in the default operation of GNU M4 2.0 (due to a change
|
||
in how more than 9 arguments in a macro definition will be
|
||
handled, *note Arguments::). Providing an alternate regular
|
||
expression can provide a useful reverse lookup feature of finding
|
||
where a macro is defined to have a given definition.
|
||
|
||
`-W REGEXP'
|
||
`--word-regexp=REGEXP'
|
||
Use REGEXP as an alternative syntax for macro names. This
|
||
experimental option will not be present in all GNU `m4'
|
||
implementations (*note Changeword::).
|
||
|
||
|
||
File: m4.info, Node: Preprocessor features, Next: Limits control, Prev: Operation modes, Up: Invoking m4
|
||
|
||
2.2 Command line options for preprocessor features
|
||
==================================================
|
||
|
||
Several options allow `m4' to behave more like a preprocessor. Macro
|
||
definitions and deletions can be made on the command line, the search
|
||
path can be altered, and the output file can track where the input came
|
||
from. These features occur with the following options:
|
||
|
||
`-D NAME[=VALUE]'
|
||
`--define=NAME[=VALUE]'
|
||
This enters NAME into the symbol table. If `=VALUE' is missing,
|
||
the value is taken to be the empty string. The VALUE can be any
|
||
string, and the macro can be defined to take arguments, just as if
|
||
it was defined from within the input. This option may be given
|
||
more than once; order with respect to file names is significant,
|
||
and redefining the same NAME loses the previous value.
|
||
|
||
`-I DIRECTORY'
|
||
`--include=DIRECTORY'
|
||
Make `m4' search DIRECTORY for included files that are not found
|
||
in the current working directory. *Note Search Path::, for more
|
||
details. This option may be given more than once.
|
||
|
||
`-s'
|
||
`--synclines'
|
||
Generate synchronization lines, for use by the C preprocessor or
|
||
other similar tools. Order is significant with respect to file
|
||
names. This option is useful, for example, when `m4' is used as a
|
||
front end to a compiler. Source file name and line number
|
||
information is conveyed by directives of the form `#line LINENUM
|
||
"FILE"', which are inserted as needed into the middle of the
|
||
output. Such directives mean that the following line originated
|
||
or was expanded from the contents of input file FILE at line
|
||
LINENUM. The `"FILE"' part is often omitted when the file name
|
||
did not change from the previous directive.
|
||
|
||
Synchronization directives are always given on complete lines by
|
||
themselves. When a synchronization discrepancy occurs in the
|
||
middle of an output line, the associated synchronization directive
|
||
is delayed until the next newline that does not occur in the
|
||
middle of a quoted string or comment.
|
||
|
||
define(`twoline', `1
|
||
2')
|
||
=>#line 2 "stdin"
|
||
=>
|
||
changecom(`/*', `*/')
|
||
=>
|
||
define(`comment', `/*1
|
||
2*/')
|
||
=>#line 5
|
||
=>
|
||
dnl no line
|
||
hello
|
||
=>#line 7
|
||
=>hello
|
||
twoline
|
||
=>1
|
||
=>#line 8
|
||
=>2
|
||
comment
|
||
=>/*1
|
||
=>2*/
|
||
one comment `two
|
||
three'
|
||
=>#line 10
|
||
=>one /*1
|
||
=>2*/ two
|
||
=>three
|
||
goodbye
|
||
=>#line 12
|
||
=>goodbye
|
||
|
||
`-U NAME'
|
||
`--undefine=NAME'
|
||
This deletes any predefined meaning NAME might have. Obviously,
|
||
only predefined macros can be deleted in this way. This option
|
||
may be given more than once; undefining a NAME that does not have a
|
||
definition is silently ignored. Order is significant with respect
|
||
to file names.
|
||
|
||
|
||
File: m4.info, Node: Limits control, Next: Frozen state, Prev: Preprocessor features, Up: Invoking m4
|
||
|
||
2.3 Command line options for limits control
|
||
===========================================
|
||
|
||
There are some limits within `m4' that can be tuned. For
|
||
compatibility, `m4' also accepts some options that control limits in
|
||
other implementations, but which are automatically unbounded (limited
|
||
only by your hardware and operating system constraints) in GNU `m4'.
|
||
|
||
`-g'
|
||
`--gnu'
|
||
Enable all the extensions in this implementation. In this release
|
||
of M4, this option is always on by default; it is currently only
|
||
useful when overriding a prior use of `--traditional'. However,
|
||
having GNU behavior as default makes it impossible to write a
|
||
strictly POSIX-compliant client that avoids all incompatible GNU
|
||
M4 extensions, since such a client would have to use the non-POSIX
|
||
command-line option to force full POSIX behavior. Thus, a future
|
||
version of M4 will be changed to implicitly use the option
|
||
`--traditional' if the environment variable `POSIXLY_CORRECT' is
|
||
set. Projects that intentionally use GNU extensions should
|
||
consider using `--gnu' to state their intentions, so that the
|
||
project will not mysteriously break if the user upgrades to a
|
||
newer M4 and has `POSIXLY_CORRECT' set in their environment.
|
||
|
||
`-G'
|
||
`--traditional'
|
||
Suppress all the extensions made in this implementation, compared
|
||
to the System V version. *Note Compatibility::, for a list of
|
||
these.
|
||
|
||
`-H NUM'
|
||
`--hashsize=NUM'
|
||
Make the internal hash table for symbol lookup be NUM entries big.
|
||
For better performance, the number should be prime, but this is not
|
||
checked. The default is 509 entries. It should not be necessary
|
||
to increase this value, unless you define an excessive number of
|
||
macros.
|
||
|
||
`-L NUM'
|
||
`--nesting-limit=NUM'
|
||
Artificially limit the nesting of macro calls to NUM levels,
|
||
stopping program execution if this limit is ever exceeded. When
|
||
not specified, nesting defaults to unlimited on platforms that can
|
||
detect stack overflow, and to 1024 levels otherwise. A value of
|
||
zero means unlimited; but then heavily nested code could
|
||
potentially cause a stack overflow.
|
||
|
||
The precise effect of this option is more correctly associated
|
||
with textual nesting than dynamic recursion. It has been useful
|
||
when some complex `m4' input was generated by mechanical means, and
|
||
also in diagnosing recursive algorithms that do not scale well.
|
||
Most users never need to change this option from its default.
|
||
|
||
This option does _not_ have the ability to break endless
|
||
rescanning loops, since these do not necessarily consume much
|
||
memory or stack space. Through clever usage of rescanning loops,
|
||
one can request complex, time-consuming computations from `m4'
|
||
with useful results. Putting limitations in this area would break
|
||
`m4' power. There are many pathological cases:
|
||
`define(`a', `a')a' is only the simplest example (but *note
|
||
Compatibility::). Expecting GNU `m4' to detect these would be a
|
||
little like expecting a compiler system to detect and diagnose
|
||
endless loops: it is a quite _hard_ problem in general, if not
|
||
undecidable!
|
||
|
||
`-B NUM'
|
||
`-S NUM'
|
||
`-T NUM'
|
||
These options are present for compatibility with System V `m4', but
|
||
do nothing in this implementation. They may disappear in future
|
||
releases, and issue a warning to that effect.
|
||
|
||
`-N NUM'
|
||
`--diversions=NUM'
|
||
These options are present only for compatibility with previous
|
||
versions of GNU `m4', and were controlling the number of possible
|
||
diversions which could be used at the same time. They do nothing,
|
||
because there is no fixed limit anymore. They may disappear in
|
||
future releases, and issue a warning to that effect.
|
||
|
||
|
||
File: m4.info, Node: Frozen state, Next: Debugging options, Prev: Limits control, Up: Invoking m4
|
||
|
||
2.4 Command line options for frozen state
|
||
=========================================
|
||
|
||
GNU `m4' comes with a feature of freezing internal state (*note Frozen
|
||
files::). This can be used to speed up `m4' execution when reusing a
|
||
common initialization script.
|
||
|
||
`-F FILE'
|
||
`--freeze-state=FILE'
|
||
Once execution is finished, write out the frozen state on the
|
||
specified FILE. It is conventional, but not required, for FILE to
|
||
end in `.m4f'.
|
||
|
||
`-R FILE'
|
||
`--reload-state=FILE'
|
||
Before execution starts, recover the internal state from the
|
||
specified frozen FILE. The options `-D', `-U', and `-t' take
|
||
effect after state is reloaded, but before the input files are
|
||
read.
|
||
|
||
|
||
File: m4.info, Node: Debugging options, Next: Command line files, Prev: Frozen state, Up: Invoking m4
|
||
|
||
2.5 Command line options for debugging
|
||
======================================
|
||
|
||
Finally, there are several options for aiding in debugging `m4' scripts.
|
||
|
||
`-d[FLAGS]'
|
||
`--debug[=FLAGS]'
|
||
Set the debug-level according to the flags FLAGS. The debug-level
|
||
controls the format and amount of information presented by the
|
||
debugging functions. *Note Debug Levels::, for more details on
|
||
the format and meaning of FLAGS. If omitted, FLAGS defaults to
|
||
`aeq'.
|
||
|
||
`--debugfile[=FILE]'
|
||
`-o FILE'
|
||
`--error-output=FILE'
|
||
Redirect `dumpdef' output, debug messages, and trace output to the
|
||
named FILE. Warnings, error messages, and `errprint' output are
|
||
still printed to standard error. If these options are not used, or
|
||
if FILE is unspecified (only possible for `--debugfile'), debug
|
||
output goes to standard error; if FILE is the empty string, debug
|
||
output is discarded. *Note Debug Output::, for more details. The
|
||
option `--debugfile' may be given more than once, and order is
|
||
significant with respect to file names. The spellings `-o' and
|
||
`--error-output' are misleading and inconsistent with other GNU
|
||
tools; for now they are silently accepted as synonyms of
|
||
`--debugfile' and only recognized once, but in a future version of
|
||
M4, using them will cause a warning to be issued.
|
||
|
||
`-l NUM'
|
||
`--arglength=NUM'
|
||
Restrict the size of the output generated by macro tracing to NUM
|
||
characters per trace line. If unspecified or zero, output is
|
||
unlimited. *Note Debug Levels::, for more details.
|
||
|
||
`-t NAME'
|
||
`--trace=NAME'
|
||
This enables tracing for the macro NAME, at any point where it is
|
||
defined. NAME need not be defined when this option is given.
|
||
This option may be given more than once, and order is significant
|
||
with respect to file names. *Note Trace::, for more details.
|
||
|
||
|
||
File: m4.info, Node: Command line files, Prev: Debugging options, Up: Invoking m4
|
||
|
||
2.6 Specifying input files on the command line
|
||
==============================================
|
||
|
||
The remaining arguments on the command line are taken to be input file
|
||
names. If no names are present, standard input is read. A file name
|
||
of `-' is taken to mean standard input. It is conventional, but not
|
||
required, for input files to end in `.m4'.
|
||
|
||
The input files are read in the sequence given. Standard input can
|
||
be read more than once, so the file name `-' may appear multiple times
|
||
on the command line; this makes a difference when input is from a
|
||
terminal or other special file type. It is an error if an input file
|
||
ends in the middle of argument collection, a comment, or a quoted
|
||
string.
|
||
|
||
The options `--define' (`-D'), `--undefine' (`-U'), `--synclines'
|
||
(`-s'), and `--trace' (`-t') only take effect after processing input
|
||
from any file names that occur earlier on the command line. For
|
||
example, assume the file `foo' contains:
|
||
|
||
$ cat foo
|
||
bar
|
||
|
||
The text `bar' can then be redefined over multiple uses of `foo':
|
||
|
||
$ m4 -Dbar=hello foo -Dbar=world foo
|
||
=>hello
|
||
=>world
|
||
|
||
If none of the input files invoked `m4exit' (*note M4exit::), the
|
||
exit status of `m4' will be 0 for success, 1 for general failure (such
|
||
as problems with reading an input file), and 63 for version mismatch
|
||
(*note Using frozen files::).
|
||
|
||
If you need to read a file whose name starts with a `-', you can
|
||
specify it as `./-file', or use `--' to mark the end of options.
|
||
|
||
|
||
File: m4.info, Node: Syntax, Next: Macros, Prev: Invoking m4, Up: Top
|
||
|
||
3 Lexical and syntactic conventions
|
||
***********************************
|
||
|
||
As `m4' reads its input, it separates it into "tokens". A token is
|
||
either a name, a quoted string, or any single character, that is not a
|
||
part of either a name or a string. Input to `m4' can also contain
|
||
comments. GNU `m4' does not yet understand multibyte locales; all
|
||
operations are byte-oriented rather than character-oriented (although
|
||
if your locale uses a single byte encoding, such as ISO-8859-1, you
|
||
will not notice a difference). However, `m4' is eight-bit clean, so
|
||
you can use non-ASCII characters in quoted strings (*note
|
||
Changequote::), comments (*note Changecom::), and macro names (*note
|
||
Indir::), with the exception of the NUL character (the zero byte
|
||
`'\0'').
|
||
|
||
* Menu:
|
||
|
||
* Names:: Macro names
|
||
* Quoted strings:: Quoting input to `m4'
|
||
* Comments:: Comments in `m4' input
|
||
* Other tokens:: Other kinds of input tokens
|
||
* Input processing:: How `m4' copies input to output
|
||
|
||
|
||
File: m4.info, Node: Names, Next: Quoted strings, Up: Syntax
|
||
|
||
3.1 Macro names
|
||
===============
|
||
|
||
A name is any sequence of letters, digits, and the character `_'
|
||
(underscore), where the first character is not a digit. `m4' will use
|
||
the longest such sequence found in the input. If a name has a macro
|
||
definition, it will be subject to macro expansion (*note Macros::).
|
||
Names are case-sensitive.
|
||
|
||
Examples of legal names are: `foo', `_tmp', and `name01'.
|
||
|
||
|
||
File: m4.info, Node: Quoted strings, Next: Comments, Prev: Names, Up: Syntax
|
||
|
||
3.2 Quoting input to `m4'
|
||
=========================
|
||
|
||
A quoted string is a sequence of characters surrounded by quote
|
||
strings, defaulting to ``' and `'', where the nested begin and end
|
||
quotes within the string are balanced. The value of a string token is
|
||
the text, with one level of quotes stripped off. Thus
|
||
|
||
`'
|
||
=>
|
||
|
||
is the empty string, and double-quoting turns into single-quoting.
|
||
|
||
``quoted''
|
||
=>`quoted'
|
||
|
||
The quote characters can be changed at any time, using the builtin
|
||
macro `changequote'. *Note Changequote::, for more information.
|
||
|
||
|
||
File: m4.info, Node: Comments, Next: Other tokens, Prev: Quoted strings, Up: Syntax
|
||
|
||
3.3 Comments in `m4' input
|
||
==========================
|
||
|
||
Comments in `m4' are normally delimited by the characters `#' and
|
||
newline. All characters between the comment delimiters are ignored,
|
||
but the entire comment (including the delimiters) is passed through to
|
||
the output--comments are _not_ discarded by `m4'.
|
||
|
||
Comments cannot be nested, so the first newline after a `#' ends the
|
||
comment. The commenting effect of the begin-comment string can be
|
||
inhibited by quoting it.
|
||
|
||
$ m4
|
||
`quoted text' # `commented text'
|
||
=>quoted text # `commented text'
|
||
`quoting inhibits' `#' `comments'
|
||
=>quoting inhibits # comments
|
||
|
||
The comment delimiters can be changed to any string at any time,
|
||
using the builtin macro `changecom'. *Note Changecom::, for more
|
||
information.
|
||
|
||
|
||
File: m4.info, Node: Other tokens, Next: Input processing, Prev: Comments, Up: Syntax
|
||
|
||
3.4 Other kinds of input tokens
|
||
===============================
|
||
|
||
Any character, that is neither a part of a name, nor of a quoted string,
|
||
nor a comment, is a token by itself. When not in the context of macro
|
||
expansion, all of these tokens are just copied to output. However,
|
||
during macro expansion, whitespace characters (space, tab, newline,
|
||
formfeed, carriage return, vertical tab), parentheses (`(' and `)'),
|
||
comma (`,'), and dollar (`$') have additional roles, explained later.
|
||
|
||
|
||
File: m4.info, Node: Input processing, Prev: Other tokens, Up: Syntax
|
||
|
||
3.5 How `m4' copies input to output
|
||
===================================
|
||
|
||
As `m4' reads the input token by token, it will copy each token
|
||
directly to the output immediately.
|
||
|
||
The exception is when it finds a word with a macro definition. In
|
||
that case `m4' will calculate the macro's expansion, possibly reading
|
||
more input to get the arguments. It then inserts the expansion in front
|
||
of the remaining input. In other words, the resulting text from a macro
|
||
call will be read and parsed into tokens again.
|
||
|
||
`m4' expands a macro as soon as possible. If it finds a macro call
|
||
when collecting the arguments to another, it will expand the second call
|
||
first. This process continues until there are no more macro calls to
|
||
expand and all the input has been consumed.
|
||
|
||
For a running example, examine how `m4' handles this input:
|
||
|
||
format(`Result is %d', eval(`2**15'))
|
||
|
||
First, `m4' sees that the token `format' is a macro name, so it
|
||
collects the tokens `(', ``Result is %d'', `,', and ` ', before
|
||
encountering another potential macro. Sure enough, `eval' is a macro
|
||
name, so the nested argument collection picks up `(', ``2**15'', and
|
||
`)', invoking the eval macro with the lone argument of `2**15'. The
|
||
expansion of `eval(2**15)' is `32768', which is then rescanned as the
|
||
five tokens `3', `2', `7', `6', and `8'; and combined with the next
|
||
`)', the format macro now has all its arguments, as if the user had
|
||
typed:
|
||
|
||
format(`Result is %d', 32768)
|
||
|
||
The format macro expands to `Result is 32768', and we have another
|
||
round of scanning for the tokens `Result', ` ', `is', ` ', `3', `2',
|
||
`7', `6', and `8'. None of these are macros, so the final output is
|
||
|
||
=>Result is 32768
|
||
|
||
As a more complicated example, we will contrast an actual code
|
||
example from the Gnulib project(1), showing both a buggy approach and
|
||
the desired results. The user desires to output a shell assignment
|
||
statement that takes its argument and turns it into a shell variable by
|
||
converting it to uppercase and prepending a prefix. The original
|
||
attempt looks like this:
|
||
|
||
changequote([,])dnl
|
||
define([gl_STRING_MODULE_INDICATOR],
|
||
[
|
||
dnl comment
|
||
GNULIB_]translit([$1],[a-z],[A-Z])[=1
|
||
])dnl
|
||
gl_STRING_MODULE_INDICATOR([strcase])
|
||
=>
|
||
=> GNULIB_strcase=1
|
||
=>
|
||
|
||
Oops - the argument did not get capitalized. And although the manual
|
||
is not able to easily show it, both lines that appear empty actually
|
||
contain two trailing spaces. By stepping through the parse, it is easy
|
||
to see what happened. First, `m4' sees the token `changequote', which
|
||
it recognizes as a macro, followed by `(', `[', `,', `]', and `)' to
|
||
form the argument list. The macro expands to the empty string, but
|
||
changes the quoting characters to something more useful for generating
|
||
shell code (unbalanced ``' and `'' appear all the time in shell scripts,
|
||
but unbalanced `[]' tend to be rare). Also in the first line, `m4'
|
||
sees the token `dnl', which it recognizes as a builtin macro that
|
||
consumes the rest of the line, resulting in no output for that line.
|
||
|
||
The second line starts a macro definition. `m4' sees the token
|
||
`define', which it recognizes as a macro, followed by a `(',
|
||
`[gl_STRING_MODULE_INDICATOR]', and `,'. Because an unquoted comma was
|
||
encountered, the first argument is known to be the expansion of the
|
||
single-quoted string token, or `gl_STRING_MODULE_INDICATOR'. Next,
|
||
`m4' sees `<NL>', ` ', and ` ', but this whitespace is discarded as
|
||
part of argument collection. Then comes a rather lengthy single-quoted
|
||
string token, `[<NL> dnl comment<NL> GNULIB_]'. This is followed
|
||
by the token `translit', which `m4' recognizes as a macro name, so a
|
||
nested macro expansion has started.
|
||
|
||
The arguments to the `translit' are found by the tokens `(', `[$1]',
|
||
`,', `[a-z]', `,', `[A-Z]', and finally `)'. All three string
|
||
arguments are expanded (or in other words, the quotes are stripped),
|
||
and since neither `$' nor `1' need capitalization, the result of the
|
||
macro is `$1'. This expansion is rescanned, resulting in the two
|
||
literal characters `$' and `1'.
|
||
|
||
Scanning of the outer macro resumes, and picks up with `[=1<NL> ]',
|
||
and finally `)'. The collected pieces of expanded text are
|
||
concatenated, with the end result that the macro
|
||
`gl_STRING_MODULE_INDICATOR' is now defined to be the sequence `<NL>
|
||
dnl comment<NL> GNULIB_$1=1<NL> '. Once again, `dnl' is recognized
|
||
and avoids a newline in the output.
|
||
|
||
The final line is then parsed, beginning with ` ' and ` ' that are
|
||
output literally. Then `gl_STRING_MODULE_INDICATOR' is recognized as a
|
||
macro name, with an argument list of `(', `[strcase]', and `)'. Since
|
||
the definition of the macro contains the sequence `$1', that sequence
|
||
is replaced with the argument `strcase' prior to starting the rescan.
|
||
The rescan sees `<NL>' and four spaces, which are output literally, then
|
||
`dnl', which discards the text ` comment<NL>'. Next comes four more
|
||
spaces, also output literally, and the token `GNULIB_strcase', which
|
||
resulted from the earlier parameter substitution. Since that is not a
|
||
macro name, it is output literally, followed by the literal tokens `=',
|
||
`1', `<NL>', and two more spaces. Finally, the original `<NL>' seen
|
||
after the macro invocation is scanned and output literally.
|
||
|
||
Now for a corrected approach. This rearranges the use of newlines
|
||
and whitespace so that less whitespace is output (which, although
|
||
harmless to shell scripts, can be visually unappealing), and fixes the
|
||
quoting issues so that the capitalization occurs when the macro
|
||
`gl_STRING_MODULE_INDICATOR' is invoked, rather then when it is defined.
|
||
|
||
changequote([,])dnl
|
||
define([gl_STRING_MODULE_INDICATOR],
|
||
[dnl comment
|
||
GNULIB_[]translit([$1], [a-z], [A-Z])=1dnl
|
||
])dnl
|
||
gl_STRING_MODULE_INDICATOR([strcase])
|
||
=> GNULIB_STRCASE=1
|
||
|
||
The parsing of the first line is unchanged. The second line sees the
|
||
name of the macro to define, then sees the discarded `<NL>' and two
|
||
spaces, as before. But this time, the next token is `[dnl comment<NL>
|
||
GNULIB_[]translit([$1], [a-z], [A-Z])=1dnl<NL>]', which includes nested
|
||
quotes, followed by `)' to end the macro definition and `dnl' to skip
|
||
the newline. No early expansion of `translit' occurs, so the entire
|
||
string becomes the definition of the macro.
|
||
|
||
The final line is then parsed, beginning with two spaces that are
|
||
output literally, and an invocation of `gl_STRING_MODULE_INDICATOR'
|
||
with the argument `strcase'. Again, the `$1' in the macro definition
|
||
is substituted prior to rescanning. Rescanning first encounters `dnl',
|
||
and discards ` comment<NL>'. Then two spaces are output literally.
|
||
Next comes the token `GNULIB_', but that is not a macro, so it is
|
||
output literally. The token `[]' is an empty string, so it does not
|
||
affect output. Then the token `translit' is encountered.
|
||
|
||
This time, the arguments to `translit' are parsed as `(',
|
||
`[strcase]', `,', ` ', `[a-z]', `,', ` ', `[A-Z]', and `)'. The two
|
||
spaces are discarded, and the translit results in the desired result
|
||
`STRCASE'. This is rescanned, but since it is not a macro name, it is
|
||
output literally. Then the scanner sees `=' and `1', which are output
|
||
literally, followed by `dnl' which discards the rest of the definition
|
||
of `gl_STRING_MODULE_INDICATOR'. The newline at the end of output is
|
||
the literal `<NL>' that appeared after the invocation of the macro.
|
||
|
||
The order in which `m4' expands the macros can be further explored
|
||
using the trace facilities of GNU `m4' (*note Trace::).
|
||
|
||
---------- Footnotes ----------
|
||
|
||
(1) Derived from a patch in
|
||
`http://lists.gnu.org/archive/html/bug-gnulib/2007-01/msg00389.html',
|
||
and a followup patch in
|
||
`http://lists.gnu.org/archive/html/bug-gnulib/2007-02/msg00000.html'
|
||
|
||
|
||
File: m4.info, Node: Macros, Next: Definitions, Prev: Syntax, Up: Top
|
||
|
||
4 How to invoke macros
|
||
**********************
|
||
|
||
This chapter covers macro invocation, macro arguments and how macro
|
||
expansion is treated.
|
||
|
||
* Menu:
|
||
|
||
* Invocation:: Macro invocation
|
||
* Inhibiting Invocation:: Preventing macro invocation
|
||
* Macro Arguments:: Macro arguments
|
||
* Quoting Arguments:: On Quoting Arguments to macros
|
||
* Macro expansion:: Expanding macros
|
||
|
||
|
||
File: m4.info, Node: Invocation, Next: Inhibiting Invocation, Up: Macros
|
||
|
||
4.1 Macro invocation
|
||
====================
|
||
|
||
Macro invocations has one of the forms
|
||
|
||
name
|
||
|
||
which is a macro invocation without any arguments, or
|
||
|
||
name(arg1, arg2, ..., argN)
|
||
|
||
which is a macro invocation with N arguments. Macros can have any
|
||
number of arguments. All arguments are strings, but different macros
|
||
might interpret the arguments in different ways.
|
||
|
||
The opening parenthesis _must_ follow the NAME directly, with no
|
||
spaces in between. If it does not, the macro is called with no
|
||
arguments at all.
|
||
|
||
For a macro call to have no arguments, the parentheses _must_ be
|
||
left out. The macro call
|
||
|
||
name()
|
||
|
||
is a macro call with one argument, which is the empty string, not a call
|
||
with no arguments.
|
||
|
||
|
||
File: m4.info, Node: Inhibiting Invocation, Next: Macro Arguments, Prev: Invocation, Up: Macros
|
||
|
||
4.2 Preventing macro invocation
|
||
===============================
|
||
|
||
An innovation of the `m4' language, compared to some of its
|
||
predecessors (like Strachey's `GPM', for example), is the ability to
|
||
recognize macro calls without resorting to any special, prefixed
|
||
invocation character. While generally useful, this feature might
|
||
sometimes be the source of spurious, unwanted macro calls. So, GNU
|
||
`m4' offers several mechanisms or techniques for inhibiting the
|
||
recognition of names as macro calls.
|
||
|
||
First of all, many builtin macros cannot meaningfully be called
|
||
without arguments. As a GNU extension, for any of these macros,
|
||
whenever an opening parenthesis does not immediately follow their name,
|
||
the builtin macro call is not triggered. This solves the most usual
|
||
cases, like for `include' or `eval'. Later in this document, the
|
||
sentence "This macro is recognized only with parameters" refers to this
|
||
specific provision of GNU M4, also known as a blind builtin macro. For
|
||
the builtins defined by POSIX that bear this disclaimer, POSIX
|
||
specifically states that invoking those builtins without arguments is
|
||
unspecified, because many other implementations simply invoke the
|
||
builtin as though it were given one empty argument instead.
|
||
|
||
$ m4
|
||
eval
|
||
=>eval
|
||
eval(`1')
|
||
=>1
|
||
|
||
There is also a command line option (`--prefix-builtins', or `-P',
|
||
*note Invoking m4: Operation modes.) that renames all builtin macros
|
||
with a prefix of `m4_' at startup. The option has no effect whatsoever
|
||
on user defined macros. For example, with this option, one has to
|
||
write `m4_dnl' and even `m4_m4exit'. It also has no effect on whether
|
||
a macro requires parameters.
|
||
|
||
$ m4 -P
|
||
eval
|
||
=>eval
|
||
eval(`1')
|
||
=>eval(1)
|
||
m4_eval
|
||
=>m4_eval
|
||
m4_eval(`1')
|
||
=>1
|
||
|
||
Another alternative is to redefine problematic macros to a name less
|
||
likely to cause conflicts, *Note Definitions::.
|
||
|
||
If your version of GNU `m4' has the `changeword' feature compiled
|
||
in, it offers far more flexibility in specifying the syntax of macro
|
||
names, both builtin or user-defined. *Note Changeword::, for more
|
||
information on this experimental feature.
|
||
|
||
Of course, the simplest way to prevent a name from being interpreted
|
||
as a call to an existing macro is to quote it. The remainder of this
|
||
section studies a little more deeply how quoting affects macro
|
||
invocation, and how quoting can be used to inhibit macro invocation.
|
||
|
||
Even if quoting is usually done over the whole macro name, it can
|
||
also be done over only a few characters of this name (provided, of
|
||
course, that the unquoted portions are not also a macro). It is also
|
||
possible to quote the empty string, but this works only _inside_ the
|
||
name. For example:
|
||
|
||
`divert'
|
||
=>divert
|
||
`d'ivert
|
||
=>divert
|
||
di`ver't
|
||
=>divert
|
||
div`'ert
|
||
=>divert
|
||
|
||
all yield the string `divert'. While in both:
|
||
|
||
`'divert
|
||
=>
|
||
divert`'
|
||
=>
|
||
|
||
the `divert' builtin macro will be called, which expands to the empty
|
||
string.
|
||
|
||
The output of macro evaluations is always rescanned. In the
|
||
following example, the input `x`'y' yields the string `bCD', exactly as
|
||
if `m4' has been given `substr(ab`'cde, `1', `3')' as input:
|
||
|
||
define(`cde', `CDE')
|
||
=>
|
||
define(`x', `substr(ab')
|
||
=>
|
||
define(`y', `cde, `1', `3')')
|
||
=>
|
||
x`'y
|
||
=>bCD
|
||
|
||
Unquoted strings on either side of a quoted string are subject to
|
||
being recognized as macro names. In the following example, quoting the
|
||
empty string allows for the second `macro' to be recognized as such:
|
||
|
||
define(`macro', `m')
|
||
=>
|
||
macro(`m')macro
|
||
=>mmacro
|
||
macro(`m')`'macro
|
||
=>mm
|
||
|
||
Quoting may prevent recognizing as a macro name the concatenation of
|
||
a macro expansion with the surrounding characters. In this example:
|
||
|
||
define(`macro', `di$1')
|
||
=>
|
||
macro(`v')`ert'
|
||
=>divert
|
||
macro(`v')ert
|
||
=>
|
||
|
||
the input will produce the string `divert'. When the quotes were
|
||
removed, the `divert' builtin was called instead.
|
||
|
||
|
||
File: m4.info, Node: Macro Arguments, Next: Quoting Arguments, Prev: Inhibiting Invocation, Up: Macros
|
||
|
||
4.3 Macro arguments
|
||
===================
|
||
|
||
When a name is seen, and it has a macro definition, it will be expanded
|
||
as a macro.
|
||
|
||
If the name is followed by an opening parenthesis, the arguments
|
||
will be collected before the macro is called. If too few arguments are
|
||
supplied, the missing arguments are taken to be the empty string.
|
||
However, some builtins are documented to behave differently for a
|
||
missing optional argument than for an explicit empty string. If there
|
||
are too many arguments, the excess arguments are ignored. Unquoted
|
||
leading whitespace is stripped off all arguments, but whitespace
|
||
generated by a macro expansion or occurring after a macro that expanded
|
||
to an empty string remains intact. Whitespace includes space, tab,
|
||
newline, carriage return, vertical tab, and formfeed.
|
||
|
||
define(`macro', `$1')
|
||
=>
|
||
macro( unquoted leading space lost)
|
||
=>unquoted leading space lost
|
||
macro(` quoted leading space kept')
|
||
=> quoted leading space kept
|
||
macro(
|
||
divert `unquoted space kept after expansion')
|
||
=> unquoted space kept after expansion
|
||
macro(macro(`
|
||
')`whitespace from expansion kept')
|
||
=>
|
||
=>whitespace from expansion kept
|
||
macro(`unquoted trailing whitespace kept'
|
||
)
|
||
=>unquoted trailing whitespace kept
|
||
=>
|
||
|
||
Normally `m4' will issue warnings if a builtin macro is called with
|
||
an inappropriate number of arguments, but it can be suppressed with the
|
||
`--quiet' command line option (or `--silent', or `-Q', *note Invoking
|
||
m4: Operation modes.). For user defined macros, there is no check of
|
||
the number of arguments given.
|
||
|
||
$ m4
|
||
index(`abc')
|
||
error-->m4:stdin:1: Warning: too few arguments to builtin `index'
|
||
=>0
|
||
index(`abc',)
|
||
=>0
|
||
index(`abc', `b', `ignored')
|
||
error-->m4:stdin:3: Warning: excess arguments to builtin `index' ignored
|
||
=>1
|
||
|
||
$ m4 -Q
|
||
index(`abc')
|
||
=>0
|
||
index(`abc',)
|
||
=>0
|
||
index(`abc', `b', `ignored')
|
||
=>1
|
||
|
||
Macros are expanded normally during argument collection, and whatever
|
||
commas, quotes and parentheses that might show up in the resulting
|
||
expanded text will serve to define the arguments as well. Thus, if FOO
|
||
expands to `, b, c', the macro call
|
||
|
||
bar(a foo, d)
|
||
|
||
is a macro call with four arguments, which are `a ', `b', `c' and `d'.
|
||
To understand why the first argument contains whitespace, remember that
|
||
unquoted leading whitespace is never part of an argument, but trailing
|
||
whitespace always is.
|
||
|
||
It is possible for a macro's definition to change during argument
|
||
collection, in which case the expansion uses the definition that was in
|
||
effect at the time the opening `(' was seen.
|
||
|
||
define(`f', `1')
|
||
=>
|
||
f(define(`f', `2'))
|
||
=>1
|
||
f
|
||
=>2
|
||
|
||
It is an error if the end of file occurs while collecting arguments.
|
||
|
||
hello world
|
||
=>hello world
|
||
define(
|
||
^D
|
||
error-->m4:stdin:2: ERROR: end of file in argument list
|
||
|
||
|
||
File: m4.info, Node: Quoting Arguments, Next: Macro expansion, Prev: Macro Arguments, Up: Macros
|
||
|
||
4.4 On Quoting Arguments to macros
|
||
==================================
|
||
|
||
Each argument has unquoted leading whitespace removed. Within each
|
||
argument, all unquoted parentheses must match. For example, if FOO is
|
||
a macro,
|
||
|
||
foo(() (`(') `(')
|
||
|
||
is a macro call, with one argument, whose value is `() (() ('. Commas
|
||
separate arguments, except when they occur inside quotes, comments, or
|
||
unquoted parentheses. *Note Pseudo Arguments::, for examples.
|
||
|
||
It is common practice to quote all arguments to macros, unless you
|
||
are sure you want the arguments expanded. Thus, in the above example
|
||
with the parentheses, the `right' way to do it is like this:
|
||
|
||
foo(`() (() (')
|
||
|
||
It is, however, in certain cases necessary (because nested expansion
|
||
must occur to create the arguments for the outer macro) or convenient
|
||
(because it uses fewer characters) to leave out quotes for some
|
||
arguments, and there is nothing wrong in doing it. It just makes life a
|
||
bit harder, if you are not careful to follow a consistent quoting style.
|
||
For consistency, this manual follows the rule of thumb that each layer
|
||
of parentheses introduces another layer of single quoting, except when
|
||
showing the consequences of quoting rules. This is done even when the
|
||
quoted string cannot be a macro, such as with integers when you have not
|
||
changed the syntax via `changeword' (*note Changeword::).
|
||
|
||
The quoting rule of thumb of one level of quoting per parentheses
|
||
has a nice property: when a macro name appears inside parentheses, you
|
||
can determine when it will be expanded. If it is not quoted, it will be
|
||
expanded prior to the outer macro, so that its expansion becomes the
|
||
argument. If it is single-quoted, it will be expanded after the outer
|
||
macro. And if it is double-quoted, it will be used as literal text
|
||
instead of a macro name.
|
||
|
||
define(`active', `ACT, IVE')
|
||
=>
|
||
define(`show', `$1 $1')
|
||
=>
|
||
show(active)
|
||
=>ACT ACT
|
||
show(`active')
|
||
=>ACT, IVE ACT, IVE
|
||
show(``active'')
|
||
=>active active
|
||
|
||
|
||
File: m4.info, Node: Macro expansion, Prev: Quoting Arguments, Up: Macros
|
||
|
||
4.5 Macro expansion
|
||
===================
|
||
|
||
When the arguments, if any, to a macro call have been collected, the
|
||
macro is expanded, and the expansion text is pushed back onto the input
|
||
(unquoted), and reread. The expansion text from one macro call might
|
||
therefore result in more macros being called, if the calls are included,
|
||
completely or partially, in the first macro calls' expansion.
|
||
|
||
Taking a very simple example, if FOO expands to `bar', and BAR
|
||
expands to `Hello', the input
|
||
|
||
$ m4 -Dbar=Hello -Dfoo=bar
|
||
foo
|
||
=>Hello
|
||
|
||
will expand first to `bar', and when this is reread and expanded, into
|
||
`Hello'.
|
||
|
||
|
||
File: m4.info, Node: Definitions, Next: Conditionals, Prev: Macros, Up: Top
|
||
|
||
5 How to define new macros
|
||
**************************
|
||
|
||
Macros can be defined, redefined and deleted in several different ways.
|
||
Also, it is possible to redefine a macro without losing a previous
|
||
value, and bring back the original value at a later time.
|
||
|
||
* Menu:
|
||
|
||
* Define:: Defining a new macro
|
||
* Arguments:: Arguments to macros
|
||
* Pseudo Arguments:: Special arguments to macros
|
||
* Undefine:: Deleting a macro
|
||
* Defn:: Renaming macros
|
||
* Pushdef:: Temporarily redefining macros
|
||
|
||
* Indir:: Indirect call of macros
|
||
* Builtin:: Indirect call of builtins
|
||
|
||
|
||
File: m4.info, Node: Define, Next: Arguments, Up: Definitions
|
||
|
||
5.1 Defining a macro
|
||
====================
|
||
|
||
The normal way to define or redefine macros is to use the builtin
|
||
`define':
|
||
|
||
-- Builtin: define (NAME, [EXPANSION])
|
||
Defines NAME to expand to EXPANSION. If EXPANSION is not given,
|
||
it is taken to be empty.
|
||
|
||
The expansion of `define' is void. The macro `define' is
|
||
recognized only with parameters.
|
||
|
||
The following example defines the macro FOO to expand to the text
|
||
`Hello World.'.
|
||
|
||
define(`foo', `Hello world.')
|
||
=>
|
||
foo
|
||
=>Hello world.
|
||
|
||
The empty line in the output is there because the newline is not a
|
||
part of the macro definition, and it is consequently copied to the
|
||
output. This can be avoided by use of the macro `dnl'. *Note Dnl::,
|
||
for details.
|
||
|
||
The first argument to `define' should be quoted; otherwise, if the
|
||
macro is already defined, you will be defining a different macro. This
|
||
example shows the problems with underquoting, since we did not want to
|
||
redefine `one':
|
||
|
||
define(foo, one)
|
||
=>
|
||
define(foo, two)
|
||
=>
|
||
one
|
||
=>two
|
||
|
||
GNU `m4' normally replaces only the _topmost_ definition of a macro
|
||
if it has several definitions from `pushdef' (*note Pushdef::). Some
|
||
other implementations of `m4' replace all definitions of a macro with
|
||
`define'. *Note Incompatibilities::, for more details.
|
||
|
||
As a GNU extension, the first argument to `define' does not have to
|
||
be a simple word. It can be any text string, even the empty string. A
|
||
macro with a non-standard name cannot be invoked in the normal way, as
|
||
the name is not recognized. It can only be referenced by the builtins
|
||
`indir' (*note Indir::) and `defn' (*note Defn::).
|
||
|
||
Arrays and associative arrays can be simulated by using non-standard
|
||
macro names.
|
||
|
||
-- Composite: array (INDEX)
|
||
-- Composite: array_set (INDEX, [VALUE])
|
||
Provide access to entries within an array. `array' reads the entry
|
||
at location INDEX, and `array_set' assigns VALUE to location INDEX.
|
||
|
||
define(`array', `defn(format(``array[%d]'', `$1'))')
|
||
=>
|
||
define(`array_set', `define(format(``array[%d]'', `$1'), `$2')')
|
||
=>
|
||
array_set(`4', `array element no. 4')
|
||
=>
|
||
array_set(`17', `array element no. 17')
|
||
=>
|
||
array(`4')
|
||
=>array element no. 4
|
||
array(eval(`10 + 7'))
|
||
=>array element no. 17
|
||
|
||
Change the `%d' to `%s' and it is an associative array.
|
||
|
||
|
||
File: m4.info, Node: Arguments, Next: Pseudo Arguments, Prev: Define, Up: Definitions
|
||
|
||
5.2 Arguments to macros
|
||
=======================
|
||
|
||
Macros can have arguments. The Nth argument is denoted by `$n' in the
|
||
expansion text, and is replaced by the Nth actual argument, when the
|
||
macro is expanded. Replacement of arguments happens before rescanning,
|
||
regardless of how many nesting levels of quoting appear in the
|
||
expansion. Here is an example of a macro with two arguments.
|
||
|
||
-- Composite: exch (ARG1, ARG2)
|
||
Expands to ARG2 followed by ARG1, effectively exchanging their
|
||
order.
|
||
|
||
define(`exch', `$2, $1')
|
||
=>
|
||
exch(`arg1', `arg2')
|
||
=>arg2, arg1
|
||
|
||
This can be used, for example, if you like the arguments to `define'
|
||
to be reversed.
|
||
|
||
define(`exch', `$2, $1')
|
||
=>
|
||
define(exch(``expansion text'', ``macro''))
|
||
=>
|
||
macro
|
||
=>expansion text
|
||
|
||
*Note Quoting Arguments::, for an explanation of the double quotes.
|
||
(You should try and improve this example so that clients of `exch' do
|
||
not have to double quote; or *note Answers: Improved exch.).
|
||
|
||
As a special case, the zeroth argument, `$0', is always the name of
|
||
the macro being expanded.
|
||
|
||
define(`test', ``Macro name: $0'')
|
||
=>
|
||
test
|
||
=>Macro name: test
|
||
|
||
If you want quoted text to appear as part of the expansion text,
|
||
remember that quotes can be nested in quoted strings. Thus, in
|
||
|
||
define(`foo', `This is macro `foo'.')
|
||
=>
|
||
foo
|
||
=>This is macro foo.
|
||
|
||
The `foo' in the expansion text is _not_ expanded, since it is a quoted
|
||
string, and not a name.
|
||
|
||
GNU `m4' allows the number following the `$' to consist of one or
|
||
more digits, allowing macros to have any number of arguments. The
|
||
extension of accepting multiple digits is incompatible with POSIX, and
|
||
is different than traditional implementations of `m4', which only
|
||
recognize one digit. Therefore, future versions of GNU M4 will phase
|
||
out this feature. To portably access beyond the ninth argument, you
|
||
can use the `argn' macro documented later (*note Shift::).
|
||
|
||
POSIX also states that `$' followed immediately by `{' in a macro
|
||
definition is implementation-defined. This version of M4 passes the
|
||
literal characters `${' through unchanged, but M4 2.0 will implement an
|
||
optional feature similar to `sh', where `${11}' expands to the eleventh
|
||
argument, to replace the current recognition of `$11'. Meanwhile, if
|
||
you want to guarantee that you will get a literal `${' in output when
|
||
expanding a macro, even when you upgrade to M4 2.0, you can use nested
|
||
quoting to your advantage:
|
||
|
||
define(`foo', `single quoted $`'{1} output')
|
||
=>
|
||
define(`bar', ``double quoted $'`{2} output'')
|
||
=>
|
||
foo(`a', `b')
|
||
=>single quoted ${1} output
|
||
bar(`a', `b')
|
||
=>double quoted ${2} output
|
||
|
||
To help you detect places in your M4 input files that might change in
|
||
behavior due to the changed behavior of M4 2.0, you can use the
|
||
`--warn-macro-sequence' command-line option (*note Invoking m4:
|
||
Operation modes.) with the default regular expression. This will add a
|
||
warning any time a macro definition includes `$' followed by multiple
|
||
digits, or by `{'. The warning is not enabled by default, because it
|
||
triggers a number of warnings in Autoconf 2.61 (and Autoconf uses `-E'
|
||
to treat warnings as errors), and because it will still be possible to
|
||
restore older behavior in M4 2.0.
|
||
|
||
$ m4 --warn-macro-sequence
|
||
define(`foo', `$001 ${1} $1')
|
||
error-->m4:stdin:1: Warning: definition of `foo' contains sequence `$001'
|
||
error-->m4:stdin:1: Warning: definition of `foo' contains sequence `${1}'
|
||
=>
|
||
foo(`bar')
|
||
=>bar ${1} bar
|
||
|
||
|
||
File: m4.info, Node: Pseudo Arguments, Next: Undefine, Prev: Arguments, Up: Definitions
|
||
|
||
5.3 Special arguments to macros
|
||
===============================
|
||
|
||
There is a special notation for the number of actual arguments supplied,
|
||
and for all the actual arguments.
|
||
|
||
The number of actual arguments in a macro call is denoted by `$#' in
|
||
the expansion text.
|
||
|
||
-- Composite: nargs (...)
|
||
Expands to a count of the number of arguments supplied.
|
||
|
||
define(`nargs', `$#')
|
||
=>
|
||
nargs
|
||
=>0
|
||
nargs()
|
||
=>1
|
||
nargs(`arg1', `arg2', `arg3')
|
||
=>3
|
||
nargs(`commas can be quoted, like this')
|
||
=>1
|
||
nargs(arg1#inside comments, commas do not separate arguments
|
||
still arg1)
|
||
=>1
|
||
nargs((unquoted parentheses, like this, group arguments))
|
||
=>1
|
||
|
||
Remember that `#' defaults to the comment character; if you forget
|
||
quotes to inhibit the comment behavior, your macro definition may not
|
||
end where you expected.
|
||
|
||
dnl Attempt to define a macro to just `$#'
|
||
define(underquoted, $#)
|
||
oops)
|
||
=>
|
||
underquoted
|
||
=>0)
|
||
=>oops
|
||
|
||
The notation `$*' can be used in the expansion text to denote all
|
||
the actual arguments, unquoted, with commas in between. For example
|
||
|
||
define(`echo', `$*')
|
||
=>
|
||
echo(arg1, arg2, arg3 , arg4)
|
||
=>arg1,arg2,arg3 ,arg4
|
||
|
||
Often each argument should be quoted, and the notation `$@' handles
|
||
that. It is just like `$*', except that it quotes each argument. A
|
||
simple example of that is:
|
||
|
||
define(`echo', `$@')
|
||
=>
|
||
echo(arg1, arg2, arg3 , arg4)
|
||
=>arg1,arg2,arg3 ,arg4
|
||
|
||
Where did the quotes go? Of course, they were eaten, when the
|
||
expanded text were reread by `m4'. To show the difference, try
|
||
|
||
define(`echo1', `$*')
|
||
=>
|
||
define(`echo2', `$@')
|
||
=>
|
||
define(`foo', `This is macro `foo'.')
|
||
=>
|
||
echo1(foo)
|
||
=>This is macro This is macro foo..
|
||
echo1(`foo')
|
||
=>This is macro foo.
|
||
echo2(foo)
|
||
=>This is macro foo.
|
||
echo2(`foo')
|
||
=>foo
|
||
|
||
*Note Trace::, if you do not understand this. As another example of the
|
||
difference, remember that comments encountered in arguments are passed
|
||
untouched to the macro, and that quoting disables comments.
|
||
|
||
define(`echo1', `$*')
|
||
=>
|
||
define(`echo2', `$@')
|
||
=>
|
||
define(`foo', `bar')
|
||
=>
|
||
echo1(#foo'foo
|
||
foo)
|
||
=>#foo'foo
|
||
=>bar
|
||
echo2(#foo'foo
|
||
foo)
|
||
=>#foobar
|
||
=>bar'
|
||
|
||
A `$' sign in the expansion text, that is not followed by anything
|
||
`m4' understands, is simply copied to the macro expansion, as any other
|
||
text is.
|
||
|
||
define(`foo', `$$$ hello $$$')
|
||
=>
|
||
foo
|
||
=>$$$ hello $$$
|
||
|
||
If you want a macro to expand to something like `$12', the judicious
|
||
use of nested quoting can put a safe character between the `$' and the
|
||
next character, relying on the rescanning to remove the nested quote.
|
||
This will prevent `m4' from interpreting the `$' sign as a reference to
|
||
an argument.
|
||
|
||
define(`foo', `no nested quote: $1')
|
||
=>
|
||
foo(`arg')
|
||
=>no nested quote: arg
|
||
define(`foo', `nested quote around $: `$'1')
|
||
=>
|
||
foo(`arg')
|
||
=>nested quote around $: $1
|
||
define(`foo', `nested empty quote after $: $`'1')
|
||
=>
|
||
foo(`arg')
|
||
=>nested empty quote after $: $1
|
||
define(`foo', `nested quote around next character: $`1'')
|
||
=>
|
||
foo(`arg')
|
||
=>nested quote around next character: $1
|
||
define(`foo', `nested quote around both: `$1'')
|
||
=>
|
||
foo(`arg')
|
||
=>nested quote around both: arg
|
||
|
||
|
||
File: m4.info, Node: Undefine, Next: Defn, Prev: Pseudo Arguments, Up: Definitions
|
||
|
||
5.4 Deleting a macro
|
||
====================
|
||
|
||
A macro definition can be removed with `undefine':
|
||
|
||
-- Builtin: undefine (NAME...)
|
||
For each argument, remove the macro NAME. The macro names must
|
||
necessarily be quoted, since they will be expanded otherwise.
|
||
|
||
The expansion of `undefine' is void. The macro `undefine' is
|
||
recognized only with parameters.
|
||
|
||
foo bar blah
|
||
=>foo bar blah
|
||
define(`foo', `some')define(`bar', `other')define(`blah', `text')
|
||
=>
|
||
foo bar blah
|
||
=>some other text
|
||
undefine(`foo')
|
||
=>
|
||
foo bar blah
|
||
=>foo other text
|
||
undefine(`bar', `blah')
|
||
=>
|
||
foo bar blah
|
||
=>foo bar blah
|
||
|
||
Undefining a macro inside that macro's expansion is safe; the macro
|
||
still expands to the definition that was in effect at the `('.
|
||
|
||
define(`f', ``$0':$1')
|
||
=>
|
||
f(f(f(undefine(`f')`hello world')))
|
||
=>f:f:f:hello world
|
||
f(`bye')
|
||
=>f(bye)
|
||
|
||
It is not an error for NAME to have no macro definition. In that
|
||
case, `undefine' does nothing.
|
||
|
||
|
||
File: m4.info, Node: Defn, Next: Pushdef, Prev: Undefine, Up: Definitions
|
||
|
||
5.5 Renaming macros
|
||
===================
|
||
|
||
It is possible to rename an already defined macro. To do this, you need
|
||
the builtin `defn':
|
||
|
||
-- Builtin: defn (NAME...)
|
||
Expands to the _quoted definition_ of each NAME. If an argument
|
||
is not a defined macro, the expansion for that argument is empty.
|
||
|
||
If NAME is a user-defined macro, the quoted definition is simply
|
||
the quoted expansion text. If, instead, there is only one NAME
|
||
and it is a builtin, the expansion is a special token, which
|
||
points to the builtin's internal definition. This token is only
|
||
meaningful as the second argument to `define' (and `pushdef'), and
|
||
is silently converted to an empty string in most other contexts.
|
||
Combining a builtin with anything else is not supported; a warning
|
||
is issued and the builtin is omitted from the final expansion.
|
||
|
||
The macro `defn' is recognized only with parameters.
|
||
|
||
Its normal use is best understood through an example, which shows
|
||
how to rename `undefine' to `zap':
|
||
|
||
define(`zap', defn(`undefine'))
|
||
=>
|
||
zap(`undefine')
|
||
=>
|
||
undefine(`zap')
|
||
=>undefine(zap)
|
||
|
||
In this way, `defn' can be used to copy macro definitions, and also
|
||
definitions of builtin macros. Even if the original macro is removed,
|
||
the other name can still be used to access the definition.
|
||
|
||
The fact that macro definitions can be transferred also explains why
|
||
you should use `$0', rather than retyping a macro's name in its
|
||
definition:
|
||
|
||
define(`foo', `This is `$0'')
|
||
=>
|
||
define(`bar', defn(`foo'))
|
||
=>
|
||
bar
|
||
=>This is bar
|
||
|
||
Macros used as string variables should be referred through `defn',
|
||
to avoid unwanted expansion of the text:
|
||
|
||
define(`string', `The macro dnl is very useful
|
||
')
|
||
=>
|
||
string
|
||
=>The macro
|
||
defn(`string')
|
||
=>The macro dnl is very useful
|
||
=>
|
||
|
||
However, it is important to remember that `m4' rescanning is purely
|
||
textual. If an unbalanced end-quote string occurs in a macro
|
||
definition, the rescan will see that embedded quote as the termination
|
||
of the quoted string, and the remainder of the macro's definition will
|
||
be rescanned unquoted. Thus it is a good idea to avoid unbalanced
|
||
end-quotes in macro definitions or arguments to macros.
|
||
|
||
define(`foo', a'a)
|
||
=>
|
||
define(`a', `A')
|
||
=>
|
||
define(`echo', `$@')
|
||
=>
|
||
foo
|
||
=>A'A
|
||
defn(`foo')
|
||
=>aA'
|
||
echo(foo)
|
||
=>AA'
|
||
|
||
On the other hand, it is possible to exploit the fact that `defn'
|
||
can concatenate multiple macros prior to the rescanning phase, in order
|
||
to join the definitions of macros that, in isolation, have unbalanced
|
||
quotes. This is particularly useful when one has used several macros to
|
||
accumulate text that M4 should rescan as a whole. In the example below,
|
||
note how the use of `defn' on `l' in isolation opens a string, which is
|
||
not closed until the next line; but used on `l' and `r' together
|
||
results in nested quoting.
|
||
|
||
define(`l', `<[>')define(`r', `<]>')
|
||
=>
|
||
changequote(`[', `]')
|
||
=>
|
||
defn([l])defn([r])
|
||
])
|
||
=><[>]defn([r])
|
||
=>)
|
||
defn([l], [r])
|
||
=><[>][<]>
|
||
|
||
Using `defn' to generate special tokens for builtin macros outside
|
||
of expected contexts can sometimes trigger warnings. But most of the
|
||
time, such tokens are silently converted to the empty string.
|
||
|
||
$ m4 -d
|
||
defn(`defn')
|
||
=>
|
||
define(defn(`divnum'), `cannot redefine a builtin token')
|
||
error-->m4:stdin:2: Warning: define: invalid macro name ignored
|
||
=>
|
||
divnum
|
||
=>0
|
||
len(defn(`divnum'))
|
||
=>0
|
||
|
||
Also note that `defn' with multiple arguments can only join text
|
||
macros, not builtins, although a future version of GNU M4 may lift this
|
||
restriction.
|
||
|
||
$ m4 -d
|
||
define(`a', `A')define(`AA', `b')
|
||
=>
|
||
traceon(`defn', `define')
|
||
=>
|
||
defn(`a', `divnum', `a')
|
||
error-->m4:stdin:3: Warning: cannot concatenate builtin `divnum'
|
||
error-->m4trace: -1- defn(`a', `divnum', `a') -> ``A'`A''
|
||
=>AA
|
||
define(`mydivnum', defn(`divnum', `divnum'))mydivnum
|
||
error-->m4:stdin:4: Warning: cannot concatenate builtin `divnum'
|
||
error-->m4:stdin:4: Warning: cannot concatenate builtin `divnum'
|
||
error-->m4trace: -2- defn(`divnum', `divnum')
|
||
error-->m4trace: -1- define(`mydivnum', `')
|
||
=>
|
||
traceoff(`defn', `define')
|
||
=>
|
||
|
||
|
||
File: m4.info, Node: Pushdef, Next: Indir, Prev: Defn, Up: Definitions
|
||
|
||
5.6 Temporarily redefining macros
|
||
=================================
|
||
|
||
It is possible to redefine a macro temporarily, reverting to the
|
||
previous definition at a later time. This is done with the builtins
|
||
`pushdef' and `popdef':
|
||
|
||
-- Builtin: pushdef (NAME, [EXPANSION])
|
||
-- Builtin: popdef (NAME...)
|
||
Analogous to `define' and `undefine'.
|
||
|
||
These macros work in a stack-like fashion. A macro is temporarily
|
||
redefined with `pushdef', which replaces an existing definition of
|
||
NAME, while saving the previous definition, before the new one is
|
||
installed. If there is no previous definition, `pushdef' behaves
|
||
exactly like `define'.
|
||
|
||
If a macro has several definitions (of which only one is
|
||
accessible), the topmost definition can be removed with `popdef'.
|
||
If there is no previous definition, `popdef' behaves like
|
||
`undefine'.
|
||
|
||
The expansion of both `pushdef' and `popdef' is void. The macros
|
||
`pushdef' and `popdef' are recognized only with parameters.
|
||
|
||
define(`foo', `Expansion one.')
|
||
=>
|
||
foo
|
||
=>Expansion one.
|
||
pushdef(`foo', `Expansion two.')
|
||
=>
|
||
foo
|
||
=>Expansion two.
|
||
pushdef(`foo', `Expansion three.')
|
||
=>
|
||
pushdef(`foo', `Expansion four.')
|
||
=>
|
||
popdef(`foo')
|
||
=>
|
||
foo
|
||
=>Expansion three.
|
||
popdef(`foo', `foo')
|
||
=>
|
||
foo
|
||
=>Expansion one.
|
||
popdef(`foo')
|
||
=>
|
||
foo
|
||
=>foo
|
||
|
||
If a macro with several definitions is redefined with `define', the
|
||
topmost definition is _replaced_ with the new definition. If it is
|
||
removed with `undefine', _all_ the definitions are removed, and not
|
||
only the topmost one. However, POSIX allows other implementations that
|
||
treat `define' as replacing an entire stack of definitions with a
|
||
single new definition, so to be portable to other implementations, it
|
||
may be worth explicitly using `popdef' and `pushdef' rather than
|
||
relying on the GNU behavior of `define'.
|
||
|
||
define(`foo', `Expansion one.')
|
||
=>
|
||
foo
|
||
=>Expansion one.
|
||
pushdef(`foo', `Expansion two.')
|
||
=>
|
||
foo
|
||
=>Expansion two.
|
||
define(`foo', `Second expansion two.')
|
||
=>
|
||
foo
|
||
=>Second expansion two.
|
||
undefine(`foo')
|
||
=>
|
||
foo
|
||
=>foo
|
||
|
||
Local variables within macros are made with `pushdef' and `popdef'.
|
||
At the start of the macro a new definition is pushed, within the macro
|
||
it is manipulated and at the end it is popped, revealing the former
|
||
definition.
|
||
|
||
It is possible to temporarily redefine a builtin with `pushdef' and
|
||
`defn'.
|
||
|
||
|
||
File: m4.info, Node: Indir, Next: Builtin, Prev: Pushdef, Up: Definitions
|
||
|
||
5.7 Indirect call of macros
|
||
===========================
|
||
|
||
Any macro can be called indirectly with `indir':
|
||
|
||
-- Builtin: indir (NAME, [ARGS...])
|
||
Results in a call to the macro NAME, which is passed the rest of
|
||
the arguments ARGS. If NAME is not defined, an error message is
|
||
printed, and the expansion is void.
|
||
|
||
The macro `indir' is recognized only with parameters.
|
||
|
||
This can be used to call macros with computed or "invalid" names
|
||
(`define' allows such names to be defined):
|
||
|
||
define(`$$internal$macro', `Internal macro (name `$0')')
|
||
=>
|
||
$$internal$macro
|
||
=>$$internal$macro
|
||
indir(`$$internal$macro')
|
||
=>Internal macro (name $$internal$macro)
|
||
|
||
The point is, here, that larger macro packages can have private
|
||
macros defined, that will not be called by accident. They can _only_ be
|
||
called through the builtin `indir'.
|
||
|
||
One other point to observe is that argument collection occurs before
|
||
`indir' invokes NAME, so if argument collection changes the value of
|
||
NAME, that will be reflected in the final expansion. This is different
|
||
than the behavior when invoking macros directly, where the definition
|
||
that was in effect before argument collection is used.
|
||
|
||
$ m4 -d
|
||
define(`f', `1')
|
||
=>
|
||
f(define(`f', `2'))
|
||
=>1
|
||
indir(`f', define(`f', `3'))
|
||
=>3
|
||
indir(`f', undefine(`f'))
|
||
error-->m4:stdin:4: undefined macro `f'
|
||
=>
|
||
|
||
When handed the result of `defn' (*note Defn::) as one of its
|
||
arguments, `indir' defers to the invoked NAME for whether a token
|
||
representing a builtin is recognized or flattened to the empty string.
|
||
|
||
$ m4 -d
|
||
indir(defn(`defn'), `divnum')
|
||
error-->m4:stdin:1: Warning: indir: invalid macro name ignored
|
||
=>
|
||
indir(`define', defn(`defn'), `divnum')
|
||
error-->m4:stdin:2: Warning: define: invalid macro name ignored
|
||
=>
|
||
indir(`define', `foo', defn(`divnum'))
|
||
=>
|
||
foo
|
||
=>0
|
||
indir(`divert', defn(`foo'))
|
||
error-->m4:stdin:5: empty string treated as 0 in builtin `divert'
|
||
=>
|
||
|
||
|
||
File: m4.info, Node: Builtin, Prev: Indir, Up: Definitions
|
||
|
||
5.8 Indirect call of builtins
|
||
=============================
|
||
|
||
Builtin macros can be called indirectly with `builtin':
|
||
|
||
-- Builtin: builtin (NAME, [ARGS...])
|
||
Results in a call to the builtin NAME, which is passed the rest of
|
||
the arguments ARGS. If NAME does not name a builtin, an error
|
||
message is printed, and the expansion is void.
|
||
|
||
The macro `builtin' is recognized only with parameters.
|
||
|
||
This can be used even if NAME has been given another definition that
|
||
has covered the original, or been undefined so that no macro maps to
|
||
the builtin.
|
||
|
||
pushdef(`define', `hidden')
|
||
=>
|
||
undefine(`undefine')
|
||
=>
|
||
define(`foo', `bar')
|
||
=>hidden
|
||
foo
|
||
=>foo
|
||
builtin(`define', `foo', defn(`divnum'))
|
||
=>
|
||
foo
|
||
=>0
|
||
builtin(`define', `foo', `BAR')
|
||
=>
|
||
foo
|
||
=>BAR
|
||
undefine(`foo')
|
||
=>undefine(foo)
|
||
foo
|
||
=>BAR
|
||
builtin(`undefine', `foo')
|
||
=>
|
||
foo
|
||
=>foo
|
||
|
||
The NAME argument only matches the original name of the builtin,
|
||
even when the `--prefix-builtins' option (or `-P', *note Invoking m4:
|
||
Operation modes.) is in effect. This is different from `indir', which
|
||
only tracks current macro names.
|
||
|
||
$ m4 -P
|
||
m4_builtin(`divnum')
|
||
=>0
|
||
m4_builtin(`m4_divnum')
|
||
error-->m4:stdin:2: undefined builtin `m4_divnum'
|
||
=>
|
||
m4_indir(`divnum')
|
||
error-->m4:stdin:3: undefined macro `divnum'
|
||
=>
|
||
m4_indir(`m4_divnum')
|
||
=>0
|
||
|
||
Note that `indir' and `builtin' can be used to invoke builtins
|
||
without arguments, even when they normally require parameters to be
|
||
recognized; but it will provoke a warning, and result in a void
|
||
expansion.
|
||
|
||
builtin
|
||
=>builtin
|
||
builtin()
|
||
error-->m4:stdin:2: undefined builtin `'
|
||
=>
|
||
builtin(`builtin')
|
||
error-->m4:stdin:3: Warning: too few arguments to builtin `builtin'
|
||
=>
|
||
builtin(`builtin',)
|
||
error-->m4:stdin:4: undefined builtin `'
|
||
=>
|
||
builtin(`builtin', ``'
|
||
')
|
||
error-->m4:stdin:5: undefined builtin ``'
|
||
error-->'
|
||
=>
|
||
indir(`index')
|
||
error-->m4:stdin:7: Warning: too few arguments to builtin `index'
|
||
=>
|
||
|
||
|
||
File: m4.info, Node: Conditionals, Next: Debugging, Prev: Definitions, Up: Top
|
||
|
||
6 Conditionals, loops, and recursion
|
||
************************************
|
||
|
||
Macros, expanding to plain text, perhaps with arguments, are not quite
|
||
enough. We would like to have macros expand to different things, based
|
||
on decisions taken at run-time. For that, we need some kind of
|
||
conditionals. Also, we would like to have some kind of loop construct,
|
||
so we could do something a number of times, or while some condition is
|
||
true.
|
||
|
||
* Menu:
|
||
|
||
* Ifdef:: Testing if a macro is defined
|
||
* Ifelse:: If-else construct, or multibranch
|
||
* Shift:: Recursion in `m4'
|
||
* Forloop:: Iteration by counting
|
||
* Foreach:: Iteration by list contents
|
||
* Stacks:: Working with definition stacks
|
||
* Composition:: Building macros with macros
|
||
|
||
|
||
File: m4.info, Node: Ifdef, Next: Ifelse, Up: Conditionals
|
||
|
||
6.1 Testing if a macro is defined
|
||
=================================
|
||
|
||
There are two different builtin conditionals in `m4'. The first is
|
||
`ifdef':
|
||
|
||
-- Builtin: ifdef (NAME, STRING-1, [STRING-2])
|
||
If NAME is defined as a macro, `ifdef' expands to STRING-1,
|
||
otherwise to STRING-2. If STRING-2 is omitted, it is taken to be
|
||
the empty string (according to the normal rules).
|
||
|
||
The macro `ifdef' is recognized only with parameters.
|
||
|
||
ifdef(`foo', ``foo' is defined', ``foo' is not defined')
|
||
=>foo is not defined
|
||
define(`foo', `')
|
||
=>
|
||
ifdef(`foo', ``foo' is defined', ``foo' is not defined')
|
||
=>foo is defined
|
||
ifdef(`no_such_macro', `yes', `no', `extra argument')
|
||
error-->m4:stdin:4: Warning: excess arguments to builtin `ifdef' ignored
|
||
=>no
|
||
|
||
|
||
File: m4.info, Node: Ifelse, Next: Shift, Prev: Ifdef, Up: Conditionals
|
||
|
||
6.2 If-else construct, or multibranch
|
||
=====================================
|
||
|
||
The other conditional, `ifelse', is much more powerful. It can be used
|
||
as a way to introduce a long comment, as an if-else construct, or as a
|
||
multibranch, depending on the number of arguments supplied:
|
||
|
||
-- Builtin: ifelse (COMMENT)
|
||
-- Builtin: ifelse (STRING-1, STRING-2, EQUAL, [NOT-EQUAL])
|
||
-- Builtin: ifelse (STRING-1, STRING-2, EQUAL-1, STRING-3, STRING-4,
|
||
EQUAL-2, ..., [NOT-EQUAL])
|
||
Used with only one argument, the `ifelse' simply discards it and
|
||
produces no output.
|
||
|
||
If called with three or four arguments, `ifelse' expands into
|
||
EQUAL, if STRING-1 and STRING-2 are equal (character for
|
||
character), otherwise it expands to NOT-EQUAL. A final fifth
|
||
argument is ignored, after triggering a warning.
|
||
|
||
If called with six or more arguments, and STRING-1 and STRING-2
|
||
are equal, `ifelse' expands into EQUAL-1, otherwise the first
|
||
three arguments are discarded and the processing starts again.
|
||
|
||
The macro `ifelse' is recognized only with parameters.
|
||
|
||
Using only one argument is a common `m4' idiom for introducing a
|
||
block comment, as an alternative to repeatedly using `dnl'. This
|
||
special usage is recognized by GNU `m4', so that in this case, the
|
||
warning about missing arguments is never triggered.
|
||
|
||
ifelse(`some comments')
|
||
=>
|
||
ifelse(`foo', `bar')
|
||
error-->m4:stdin:2: Warning: too few arguments to builtin `ifelse'
|
||
=>
|
||
|
||
Using three or four arguments provides decision points.
|
||
|
||
ifelse(`foo', `bar', `true')
|
||
=>
|
||
ifelse(`foo', `foo', `true')
|
||
=>true
|
||
define(`foo', `bar')
|
||
=>
|
||
ifelse(foo, `bar', `true', `false')
|
||
=>true
|
||
ifelse(foo, `foo', `true', `false')
|
||
=>false
|
||
|
||
Notice how the first argument was used unquoted; it is common to
|
||
compare the expansion of a macro with a string. With this macro, you
|
||
can now reproduce the behavior of blind builtins, where the macro is
|
||
recognized only with arguments.
|
||
|
||
define(`foo', `ifelse(`$#', `0', ``$0'', `arguments:$#')')
|
||
=>
|
||
foo
|
||
=>foo
|
||
foo()
|
||
=>arguments:1
|
||
foo(`a', `b', `c')
|
||
=>arguments:3
|
||
|
||
For an example of a way to make defining blind macros easier, see
|
||
*note Composition::.
|
||
|
||
The macro `ifelse' can take more than four arguments. If given more
|
||
than four arguments, `ifelse' works like a `case' or `switch' statement
|
||
in traditional programming languages. If STRING-1 and STRING-2 are
|
||
equal, `ifelse' expands into EQUAL-1, otherwise the procedure is
|
||
repeated with the first three arguments discarded. This calls for an
|
||
example:
|
||
|
||
ifelse(`foo', `bar', `third', `gnu', `gnats')
|
||
error-->m4:stdin:1: Warning: excess arguments to builtin `ifelse' ignored
|
||
=>gnu
|
||
ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth')
|
||
=>
|
||
ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth', `seventh')
|
||
=>seventh
|
||
ifelse(`foo', `bar', `3', `gnu', `gnats', `6', `7', `8')
|
||
error-->m4:stdin:4: Warning: excess arguments to builtin `ifelse' ignored
|
||
=>7
|
||
|
||
Naturally, the normal case will be slightly more advanced than these
|
||
examples. A common use of `ifelse' is in macros implementing loops of
|
||
various kinds.
|
||
|
||
|
||
File: m4.info, Node: Shift, Next: Forloop, Prev: Ifelse, Up: Conditionals
|
||
|
||
6.3 Recursion in `m4'
|
||
=====================
|
||
|
||
There is no direct support for loops in `m4', but macros can be
|
||
recursive. There is no limit on the number of recursion levels, other
|
||
than those enforced by your hardware and operating system.
|
||
|
||
Loops can be programmed using recursion and the conditionals
|
||
described previously.
|
||
|
||
There is a builtin macro, `shift', which can, among other things, be
|
||
used for iterating through the actual arguments to a macro:
|
||
|
||
-- Builtin: shift (ARG1, ...)
|
||
Takes any number of arguments, and expands to all its arguments
|
||
except ARG1, separated by commas, with each argument quoted.
|
||
|
||
The macro `shift' is recognized only with parameters.
|
||
|
||
shift
|
||
=>shift
|
||
shift(`bar')
|
||
=>
|
||
shift(`foo', `bar', `baz')
|
||
=>bar,baz
|
||
|
||
An example of the use of `shift' is this macro:
|
||
|
||
-- Composite: reverse (...)
|
||
Takes any number of arguments, and reverses their order.
|
||
|
||
It is implemented as:
|
||
|
||
define(`reverse', `ifelse(`$#', `0', , `$#', `1', ``$1'',
|
||
`reverse(shift($@)), `$1'')')
|
||
=>
|
||
reverse
|
||
=>
|
||
reverse(`foo')
|
||
=>foo
|
||
reverse(`foo', `bar', `gnats', `and gnus')
|
||
=>and gnus, gnats, bar, foo
|
||
|
||
While not a very interesting macro, it does show how simple loops
|
||
can be made with `shift', `ifelse' and recursion. It also shows that
|
||
`shift' is usually used with `$@'. Another example of this is an
|
||
implementation of a short-circuiting conditional operator.
|
||
|
||
-- Composite: cond (TEST-1, STRING-1, EQUAL-1, [TEST-2], [STRING-2],
|
||
[EQUAL-2], ..., [NOT-EQUAL])
|
||
Similar to `ifelse', where an equal comparison between the first
|
||
two strings results in the third, otherwise the first three
|
||
arguments are discarded and the process repeats. The difference
|
||
is that each TEST-<N> is expanded only when it is encountered.
|
||
This means that every third argument to `cond' is normally given
|
||
one more level of quoting than the corresponding argument to
|
||
`ifelse'.
|
||
|
||
Here is the implementation of `cond', along with a demonstration of
|
||
how it can short-circuit the side effects in `side'. Notice how all
|
||
the unquoted side effects happen regardless of how many comparisons are
|
||
made with `ifelse', compared with only the relevant effects with `cond'.
|
||
|
||
define(`cond',
|
||
`ifelse(`$#', `1', `$1',
|
||
`ifelse($1, `$2', `$3',
|
||
`$0(shift(shift(shift($@))))')')')dnl
|
||
define(`side', `define(`counter', incr(counter))$1')dnl
|
||
define(`example1',
|
||
`define(`counter', `0')dnl
|
||
ifelse(side(`$1'), `yes', `one comparison: ',
|
||
side(`$1'), `no', `two comparisons: ',
|
||
side(`$1'), `maybe', `three comparisons: ',
|
||
`side(`default answer: ')')counter')dnl
|
||
define(`example2',
|
||
`define(`counter', `0')dnl
|
||
cond(`side(`$1')', `yes', `one comparison: ',
|
||
`side(`$1')', `no', `two comparisons: ',
|
||
`side(`$1')', `maybe', `three comparisons: ',
|
||
`side(`default answer: ')')counter')dnl
|
||
example1(`yes')
|
||
=>one comparison: 3
|
||
example1(`no')
|
||
=>two comparisons: 3
|
||
example1(`maybe')
|
||
=>three comparisons: 3
|
||
example1(`feeling rather indecisive today')
|
||
=>default answer: 4
|
||
example2(`yes')
|
||
=>one comparison: 1
|
||
example2(`no')
|
||
=>two comparisons: 2
|
||
example2(`maybe')
|
||
=>three comparisons: 3
|
||
example2(`feeling rather indecisive today')
|
||
=>default answer: 4
|
||
|
||
Another common task that requires iteration is joining a list of
|
||
arguments into a single string.
|
||
|
||
-- Composite: join ([SEPARATOR], [ARGS...])
|
||
-- Composite: joinall ([SEPARATOR], [ARGS...])
|
||
Generate a single-quoted string, consisting of each ARG separated
|
||
by SEPARATOR. While `joinall' always outputs a SEPARATOR between
|
||
arguments, `join' avoids the SEPARATOR for an empty ARG.
|
||
|
||
Here are some examples of its usage, based on the implementation
|
||
`m4-1.4.13/examples/join.m4' distributed in this package:
|
||
|
||
$ m4 -I examples
|
||
include(`join.m4')
|
||
=>
|
||
join,join(`-'),join(`-', `'),join(`-', `', `')
|
||
=>,,,
|
||
joinall,joinall(`-'),joinall(`-', `'),joinall(`-', `', `')
|
||
=>,,,-
|
||
join(`-', `1')
|
||
=>1
|
||
join(`-', `1', `2', `3')
|
||
=>1-2-3
|
||
join(`', `1', `2', `3')
|
||
=>123
|
||
join(`-', `', `1', `', `', `2', `')
|
||
=>1-2
|
||
joinall(`-', `', `1', `', `', `2', `')
|
||
=>-1---2-
|
||
join(`,', `1', `2', `3')
|
||
=>1,2,3
|
||
define(`nargs', `$#')dnl
|
||
nargs(join(`,', `1', `2', `3'))
|
||
=>1
|
||
|
||
Examining the implementation shows some interesting points about
|
||
several m4 programming idioms.
|
||
|
||
$ m4 -I examples
|
||
undivert(`join.m4')dnl
|
||
=>divert(`-1')
|
||
=># join(sep, args) - join each non-empty ARG into a single
|
||
=># string, with each element separated by SEP
|
||
=>define(`join',
|
||
=>`ifelse(`$#', `2', ``$2'',
|
||
=> `ifelse(`$2', `', `', ``$2'_')$0(`$1', shift(shift($@)))')')
|
||
=>define(`_join',
|
||
=>`ifelse(`$#$2', `2', `',
|
||
=> `ifelse(`$2', `', `', ``$1$2'')$0(`$1', shift(shift($@)))')')
|
||
=># joinall(sep, args) - join each ARG, including empty ones,
|
||
=># into a single string, with each element separated by SEP
|
||
=>define(`joinall', ``$2'_$0(`$1', shift($@))')
|
||
=>define(`_joinall',
|
||
=>`ifelse(`$#', `2', `', ``$1$3'$0(`$1', shift(shift($@)))')')
|
||
=>divert`'dnl
|
||
|
||
First, notice that this implementation creates helper macros `_join'
|
||
and `_joinall'. This division of labor makes it easier to output the
|
||
correct number of SEPARATOR instances: `join' and `joinall' are
|
||
responsible for the first argument, without a separator, while `_join'
|
||
and `_joinall' are responsible for all remaining arguments, always
|
||
outputting a separator when outputting an argument.
|
||
|
||
Next, observe how `join' decides to iterate to itself, because the
|
||
first ARG was empty, or to output the argument and swap over to
|
||
`_join'. If the argument is non-empty, then the nested `ifelse'
|
||
results in an unquoted `_', which is concatenated with the `$0' to form
|
||
the next macro name to invoke. The `joinall' implementation is simpler
|
||
since it does not have to suppress empty ARG; it always executes once
|
||
then defers to `_joinall'.
|
||
|
||
Another important idiom is the idea that SEPARATOR is reused for
|
||
each iteration. Each iteration has one less argument, but rather than
|
||
discarding `$1' by iterating with `$0(shift($@))', the macro discards
|
||
`$2' by using `$0(`$1', shift(shift($@)))'.
|
||
|
||
Next, notice that it is possible to compare more than one condition
|
||
in a single `ifelse' test. The test of `$#$2' against `2' allows
|
||
`_join' to iterate for two separate reasons--either there are still
|
||
more than two arguments, or there are exactly two arguments but the
|
||
last argument is not empty.
|
||
|
||
Finally, notice that these macros require exactly two arguments to
|
||
terminate recursion, but that they still correctly result in empty
|
||
output when given no ARGS (i.e., zero or one macro argument). On the
|
||
first pass when there are too few arguments, the `shift' results in no
|
||
output, but leaves an empty string to serve as the required second
|
||
argument for the second pass. Put another way, ``$1', shift($@)' is
|
||
not the same as `$@', since only the former guarantees at least two
|
||
arguments.
|
||
|
||
Sometimes, a recursive algorithm requires adding quotes to each
|
||
element, or treating multiple arguments as a single element:
|
||
|
||
-- Composite: quote (...)
|
||
-- Composite: dquote (...)
|
||
-- Composite: dquote_elt (...)
|
||
Takes any number of arguments, and adds quoting. With `quote',
|
||
only one level of quoting is added, effectively removing whitespace
|
||
after commas and turning multiple arguments into a single string.
|
||
With `dquote', two levels of quoting are added, one around each
|
||
element, and one around the list. And with `dquote_elt', two
|
||
levels of quoting are added around each element.
|
||
|
||
An actual implementation of these three macros is distributed as
|
||
`m4-1.4.13/examples/quote.m4' in this package. First, let's examine
|
||
their usage:
|
||
|
||
$ m4 -I examples
|
||
include(`quote.m4')
|
||
=>
|
||
-quote-dquote-dquote_elt-
|
||
=>----
|
||
-quote()-dquote()-dquote_elt()-
|
||
=>--`'-`'-
|
||
-quote(`1')-dquote(`1')-dquote_elt(`1')-
|
||
=>-1-`1'-`1'-
|
||
-quote(`1', `2')-dquote(`1', `2')-dquote_elt(`1', `2')-
|
||
=>-1,2-`1',`2'-`1',`2'-
|
||
define(`n', `$#')dnl
|
||
-n(quote(`1', `2'))-n(dquote(`1', `2'))-n(dquote_elt(`1', `2'))-
|
||
=>-1-1-2-
|
||
dquote(dquote_elt(`1', `2'))
|
||
=>``1'',``2''
|
||
dquote_elt(dquote(`1', `2'))
|
||
=>``1',`2''
|
||
|
||
The last two lines show that when given two arguments, `dquote'
|
||
results in one string, while `dquote_elt' results in two. Now, examine
|
||
the implementation. Note that `quote' and `dquote_elt' make decisions
|
||
based on their number of arguments, so that when called without
|
||
arguments, they result in nothing instead of a quoted empty string;
|
||
this is so that it is possible to distinguish between no arguments and
|
||
an empty first argument. `dquote', on the other hand, results in a
|
||
string no matter what, since it is still possible to tell whether it
|
||
was invoked without arguments based on the resulting string.
|
||
|
||
$ m4 -I examples
|
||
undivert(`quote.m4')dnl
|
||
=>divert(`-1')
|
||
=># quote(args) - convert args to single-quoted string
|
||
=>define(`quote', `ifelse(`$#', `0', `', ``$*'')')
|
||
=># dquote(args) - convert args to quoted list of quoted strings
|
||
=>define(`dquote', ``$@'')
|
||
=># dquote_elt(args) - convert args to list of double-quoted strings
|
||
=>define(`dquote_elt', `ifelse(`$#', `0', `', `$#', `1', ```$1''',
|
||
=> ```$1'',$0(shift($@))')')
|
||
=>divert`'dnl
|
||
|
||
It is worth pointing out that `quote(ARGS)' is more efficient than
|
||
`joinall(`,', ARGS)' for producing the same output.
|
||
|
||
One more useful macro based on `shift' allows portably selecting an
|
||
arbitrary argument (usually greater than the ninth argument), without
|
||
relying on the GNU extension of multi-digit arguments (*note
|
||
Arguments::).
|
||
|
||
-- Composite: argn (N, ...)
|
||
Expands to argument N out of the remaining arguments. N must be a
|
||
positive number. Usually invoked as `argn(`N',$@)'.
|
||
|
||
It is implemented as:
|
||
|
||
define(`argn', `ifelse(`$1', 1, ``$2'',
|
||
`argn(decr(`$1'), shift(shift($@)))')')
|
||
=>
|
||
argn(`1', `a')
|
||
=>a
|
||
define(`foo', `argn(`11', $@)')
|
||
=>
|
||
foo(`a', `b', `c', `d', `e', `f', `g', `h', `i', `j', `k', `l')
|
||
=>k
|
||
|
||
|
||
File: m4.info, Node: Forloop, Next: Foreach, Prev: Shift, Up: Conditionals
|
||
|
||
6.4 Iteration by counting
|
||
=========================
|
||
|
||
Here is an example of a loop macro that implements a simple for loop.
|
||
|
||
-- Composite: forloop (ITERATOR, START, END, TEXT)
|
||
Takes the name in ITERATOR, which must be a valid macro name, and
|
||
successively assign it each integer value from START to END,
|
||
inclusive. For each assignment to ITERATOR, append TEXT to the
|
||
expansion of the `forloop'. TEXT may refer to ITERATOR. Any
|
||
definition of ITERATOR prior to this invocation is restored.
|
||
|
||
It can, for example, be used for simple counting:
|
||
|
||
$ m4 -I examples
|
||
include(`forloop.m4')
|
||
=>
|
||
forloop(`i', `1', `8', `i ')
|
||
=>1 2 3 4 5 6 7 8
|
||
|
||
For-loops can be nested, like:
|
||
|
||
$ m4 -I examples
|
||
include(`forloop.m4')
|
||
=>
|
||
forloop(`i', `1', `4', `forloop(`j', `1', `8', ` (i, j)')
|
||
')
|
||
=> (1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8)
|
||
=> (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8)
|
||
=> (3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8)
|
||
=> (4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8)
|
||
=>
|
||
|
||
The implementation of the `forloop' macro is fairly straightforward.
|
||
The `forloop' macro itself is simply a wrapper, which saves the
|
||
previous definition of the first argument, calls the internal macro
|
||
`_forloop', and re-establishes the saved definition of the first
|
||
argument.
|
||
|
||
The macro `_forloop' expands the fourth argument once, and tests to
|
||
see if the iterator has reached the final value. If it has not
|
||
finished, it increments the iterator (using the predefined macro
|
||
`incr', *note Incr::), and recurses.
|
||
|
||
Here is an actual implementation of `forloop', distributed as
|
||
`m4-1.4.13/examples/forloop.m4' in this package:
|
||
|
||
$ m4 -I examples
|
||
undivert(`forloop.m4')dnl
|
||
=>divert(`-1')
|
||
=># forloop(var, from, to, stmt) - simple version
|
||
=>define(`forloop', `pushdef(`$1', `$2')_forloop($@)popdef(`$1')')
|
||
=>define(`_forloop',
|
||
=> `$4`'ifelse($1, `$3', `', `define(`$1', incr($1))$0($@)')')
|
||
=>divert`'dnl
|
||
|
||
Notice the careful use of quotes. Certain macro arguments are left
|
||
unquoted, each for its own reason. Try to find out _why_ these
|
||
arguments are left unquoted, and see what happens if they are quoted.
|
||
(As presented, these two macros are useful but not very robust for
|
||
general use. They lack even basic error handling for cases like START
|
||
less than END, END not numeric, or ITERATOR not being a macro name.
|
||
See if you can improve these macros; or *note Answers: Improved
|
||
forloop.).
|
||
|
||
|
||
File: m4.info, Node: Foreach, Next: Stacks, Prev: Forloop, Up: Conditionals
|
||
|
||
6.5 Iteration by list contents
|
||
==============================
|
||
|
||
Here is an example of a loop macro that implements list iteration.
|
||
|
||
-- Composite: foreach (ITERATOR, PAREN-LIST, TEXT)
|
||
-- Composite: foreachq (ITERATOR, QUOTE-LIST, TEXT)
|
||
Takes the name in ITERATOR, which must be a valid macro name, and
|
||
successively assign it each value from PAREN-LIST or QUOTE-LIST.
|
||
In `foreach', PAREN-LIST is a comma-separated list of elements
|
||
contained in parentheses. In `foreachq', QUOTE-LIST is a
|
||
comma-separated list of elements contained in a quoted string.
|
||
For each assignment to ITERATOR, append TEXT to the overall
|
||
expansion. TEXT may refer to ITERATOR. Any definition of
|
||
ITERATOR prior to this invocation is restored.
|
||
|
||
As an example, this displays each word in a list inside of a
|
||
sentence, using an implementation of `foreach' distributed as
|
||
`m4-1.4.13/examples/foreach.m4', and `foreachq' in
|
||
`m4-1.4.13/examples/foreachq.m4'.
|
||
|
||
$ m4 -I examples
|
||
include(`foreach.m4')
|
||
=>
|
||
foreach(`x', (foo, bar, foobar), `Word was: x
|
||
')dnl
|
||
=>Word was: foo
|
||
=>Word was: bar
|
||
=>Word was: foobar
|
||
include(`foreachq.m4')
|
||
=>
|
||
foreachq(`x', `foo, bar, foobar', `Word was: x
|
||
')dnl
|
||
=>Word was: foo
|
||
=>Word was: bar
|
||
=>Word was: foobar
|
||
|
||
It is possible to be more complex; each element of the PAREN-LIST or
|
||
QUOTE-LIST can itself be a list, to pass as further arguments to a
|
||
helper macro. This example generates a shell case statement:
|
||
|
||
$ m4 -I examples
|
||
include(`foreach.m4')
|
||
=>
|
||
define(`_case', ` $1)
|
||
$2=" $1";;
|
||
')dnl
|
||
define(`_cat', `$1$2')dnl
|
||
case $`'1 in
|
||
=>case $1 in
|
||
foreach(`x', `(`(`a', `vara')', `(`b', `varb')', `(`c', `varc')')',
|
||
`_cat(`_case', x)')dnl
|
||
=> a)
|
||
=> vara=" a";;
|
||
=> b)
|
||
=> varb=" b";;
|
||
=> c)
|
||
=> varc=" c";;
|
||
esac
|
||
=>esac
|
||
|
||
The implementation of the `foreach' macro is a bit more involved; it
|
||
is a wrapper around two helper macros. First, `_arg1' is needed to
|
||
grab the first element of a list. Second, `_foreach' implements the
|
||
recursion, successively walking through the original list. Here is a
|
||
simple implementation of `foreach':
|
||
|
||
$ m4 -I examples
|
||
undivert(`foreach.m4')dnl
|
||
=>divert(`-1')
|
||
=># foreach(x, (item_1, item_2, ..., item_n), stmt)
|
||
=># parenthesized list, simple version
|
||
=>define(`foreach', `pushdef(`$1')_foreach($@)popdef(`$1')')
|
||
=>define(`_arg1', `$1')
|
||
=>define(`_foreach', `ifelse(`$2', `()', `',
|
||
=> `define(`$1', _arg1$2)$3`'$0(`$1', (shift$2), `$3')')')
|
||
=>divert`'dnl
|
||
|
||
Unfortunately, that implementation is not robust to macro names as
|
||
list elements. Each iteration of `_foreach' is stripping another layer
|
||
of quotes, leading to erratic results if list elements are not already
|
||
fully expanded. The first cut at implementing `foreachq' takes this
|
||
into account. Also, when using quoted elements in a PAREN-LIST, the
|
||
overall list must be quoted. A QUOTE-LIST has the nice property of
|
||
requiring fewer characters to create a list containing the same quoted
|
||
elements. To see the difference between the two macros, we attempt to
|
||
pass double-quoted macro names in a list, expecting the macro name on
|
||
output after one layer of quotes is removed during list iteration and
|
||
the final layer removed during the final rescan:
|
||
|
||
$ m4 -I examples
|
||
define(`a', `1')define(`b', `2')define(`c', `3')
|
||
=>
|
||
include(`foreach.m4')
|
||
=>
|
||
include(`foreachq.m4')
|
||
=>
|
||
foreach(`x', `(``a'', ``(b'', ``c)'')', `x
|
||
')
|
||
=>1
|
||
=>(2)1
|
||
=>
|
||
=>, x
|
||
=>)
|
||
foreachq(`x', ```a'', ``(b'', ``c)''', `x
|
||
')dnl
|
||
=>a
|
||
=>(b
|
||
=>c)
|
||
|
||
Obviously, `foreachq' did a better job; here is its implementation:
|
||
|
||
$ m4 -I examples
|
||
undivert(`foreachq.m4')dnl
|
||
=>include(`quote.m4')dnl
|
||
=>divert(`-1')
|
||
=># foreachq(x, `item_1, item_2, ..., item_n', stmt)
|
||
=># quoted list, simple version
|
||
=>define(`foreachq', `pushdef(`$1')_foreachq($@)popdef(`$1')')
|
||
=>define(`_arg1', `$1')
|
||
=>define(`_foreachq', `ifelse(quote($2), `', `',
|
||
=> `define(`$1', `_arg1($2)')$3`'$0(`$1', `shift($2)', `$3')')')
|
||
=>divert`'dnl
|
||
|
||
Notice that `_foreachq' had to use the helper macro `quote' defined
|
||
earlier (*note Shift::), to ensure that the embedded `ifelse' call does
|
||
not go haywire if a list element contains a comma. Unfortunately, this
|
||
implementation of `foreachq' has its own severe flaw. Whereas the
|
||
`foreach' implementation was linear, this macro is quadratic in the
|
||
number of list elements, and is much more likely to trip up the limit
|
||
set by the command line option `--nesting-limit' (or `-L', *note
|
||
Invoking m4: Limits control.). Additionally, this implementation does
|
||
not expand `defn(`ITERATOR')' very well, when compared with `foreach'.
|
||
|
||
$ m4 -I examples
|
||
include(`foreach.m4')include(`foreachq.m4')
|
||
=>
|
||
foreach(`name', `(`a', `b')', ` defn(`name')')
|
||
=> a b
|
||
foreachq(`name', ``a', `b'', ` defn(`name')')
|
||
=> _arg1(`a', `b') _arg1(shift(`a', `b'))
|
||
|
||
It is possible to have robust iteration with linear behavior and sane
|
||
ITERATOR contents for either list style. See if you can learn from the
|
||
best elements of both of these implementations to create robust macros
|
||
(or *note Answers: Improved foreach.).
|
||
|
||
|
||
File: m4.info, Node: Stacks, Next: Composition, Prev: Foreach, Up: Conditionals
|
||
|
||
6.6 Working with definition stacks
|
||
==================================
|
||
|
||
Thanks to `pushdef', manipulation of a stack is an intrinsic operation
|
||
in `m4'. Normally, only the topmost definition in a stack is
|
||
important, but sometimes, it is desirable to manipulate the entire
|
||
definition stack.
|
||
|
||
-- Composite: stack_foreach (MACRO, ACTION)
|
||
-- Composite: stack_foreach_lifo (MACRO, ACTION)
|
||
For each of the `pushdef' definitions associated with MACRO,
|
||
invoke the macro ACTION with a single argument of that definition.
|
||
`stack_foreach' visits the oldest definition first, while
|
||
`stack_foreach_lifo' visits the current definition first. ACTION
|
||
should not modify or dereference MACRO. There are a few special
|
||
macros, such as `defn', which cannot be used as the MACRO
|
||
parameter.
|
||
|
||
A sample implementation of these macros is distributed in the file
|
||
`m4-1.4.13/examples/stack.m4'.
|
||
|
||
$ m4 -I examples
|
||
include(`stack.m4')
|
||
=>
|
||
pushdef(`a', `1')pushdef(`a', `2')pushdef(`a', `3')
|
||
=>
|
||
define(`show', ``$1'
|
||
')
|
||
=>
|
||
stack_foreach(`a', `show')dnl
|
||
=>1
|
||
=>2
|
||
=>3
|
||
stack_foreach_lifo(`a', `show')dnl
|
||
=>3
|
||
=>2
|
||
=>1
|
||
|
||
Now for the implementation. Note the definition of a helper macro,
|
||
`_stack_reverse', which destructively swaps the contents of one stack
|
||
of definitions into the reverse order in the temporary macro `tmp-$1'.
|
||
By calling the helper twice, the original order is restored back into
|
||
the macro `$1'; since the operation is destructive, this explains why
|
||
`$1' must not be modified or dereferenced during the traversal. The
|
||
caller can then inject additional code to pass the definition currently
|
||
being visited to `$2'. The choice of helper names is intentional;
|
||
since `-' is not valid as part of a macro name, there is no risk of
|
||
conflict with a valid macro name, and the code is guaranteed to use
|
||
`defn' where necessary. Finally, note that any macro used in the
|
||
traversal of a `pushdef' stack, such as `pushdef' or `defn', cannot be
|
||
handled by `stack_foreach', since the macro would temporarily be
|
||
undefined during the algorithm.
|
||
|
||
$ m4 -I examples
|
||
undivert(`stack.m4')dnl
|
||
=>divert(`-1')
|
||
=># stack_foreach(macro, action)
|
||
=># Invoke ACTION with a single argument of each definition
|
||
=># from the definition stack of MACRO, starting with the oldest.
|
||
=>define(`stack_foreach',
|
||
=>`_stack_reverse(`$1', `tmp-$1')'dnl
|
||
=>`_stack_reverse(`tmp-$1', `$1', `$2(defn(`$1'))')')
|
||
=># stack_foreach_lifo(macro, action)
|
||
=># Invoke ACTION with a single argument of each definition
|
||
=># from the definition stack of MACRO, starting with the newest.
|
||
=>define(`stack_foreach_lifo',
|
||
=>`_stack_reverse(`$1', `tmp-$1', `$2(defn(`$1'))')'dnl
|
||
=>`_stack_reverse(`tmp-$1', `$1')')
|
||
=>define(`_stack_reverse',
|
||
=>`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0($@)')')
|
||
=>divert`'dnl
|
||
|
||
|
||
File: m4.info, Node: Composition, Prev: Stacks, Up: Conditionals
|
||
|
||
6.7 Building macros with macros
|
||
===============================
|
||
|
||
Since m4 is a macro language, it is possible to write macros that can
|
||
build other macros. First on the list is a way to automate the
|
||
creation of blind macros.
|
||
|
||
-- Composite: define_blind (NAME, [VALUE])
|
||
Defines NAME as a blind macro, such that NAME will expand to VALUE
|
||
only when given explicit arguments. VALUE should not be the
|
||
result of `defn' (*note Defn::). This macro is only recognized
|
||
with parameters, and results in an empty string.
|
||
|
||
Defining a macro to define another macro can be a bit tricky. We
|
||
want to use a literal `$#' in the argument to the nested `define'.
|
||
However, if `$' and `#' are adjacent in the definition of
|
||
`define_blind', then it would be expanded as the number of arguments to
|
||
`define_blind' rather than the intended number of arguments to NAME.
|
||
The solution is to pass the difficult characters through extra
|
||
arguments to a helper macro `_define_blind'. When composing macros, it
|
||
is a common idiom to need a helper macro to concatenate text that forms
|
||
parameters in the composed macro, rather than interpreting the text as
|
||
a parameter of the composing macro.
|
||
|
||
As for the limitation against using `defn', there are two reasons.
|
||
If a macro was previously defined with `define_blind', then it can
|
||
safely be renamed to a new blind macro using plain `define'; using
|
||
`define_blind' to rename it just adds another layer of `ifelse',
|
||
occupying memory and slowing down execution. And if a macro is a
|
||
builtin, then it would result in an attempt to define a macro
|
||
consisting of both text and a builtin token; this is not supported, and
|
||
the builtin token is flattened to an empty string.
|
||
|
||
With that explanation, here's the definition, and some sample usage.
|
||
Notice that `define_blind' is itself a blind macro.
|
||
|
||
$ m4 -d
|
||
define(`define_blind', `ifelse(`$#', `0', ``$0'',
|
||
`_$0(`$1', `$2', `$'`#', `$'`0')')')
|
||
=>
|
||
define(`_define_blind', `define(`$1',
|
||
`ifelse(`$3', `0', ``$4'', `$2')')')
|
||
=>
|
||
define_blind
|
||
=>define_blind
|
||
define_blind(`foo', `arguments were $*')
|
||
=>
|
||
foo
|
||
=>foo
|
||
foo(`bar')
|
||
=>arguments were bar
|
||
define(`blah', defn(`foo'))
|
||
=>
|
||
blah
|
||
=>blah
|
||
blah(`a', `b')
|
||
=>arguments were a,b
|
||
defn(`blah')
|
||
=>ifelse(`$#', `0', ``$0'', `arguments were $*')
|
||
|
||
Another interesting composition tactic is argument "currying", or
|
||
factoring a macro that takes multiple arguments for use in a context
|
||
that provides exactly one argument.
|
||
|
||
-- Composite: curry (MACRO, ...)
|
||
Expand to a macro call that takes exactly one argument, then
|
||
appends that argument to the original arguments and invokes MACRO
|
||
with the resulting list of arguments.
|
||
|
||
A demonstration of currying makes the intent of this macro a little
|
||
more obvious. The macro `stack_foreach' mentioned earlier is an example
|
||
of a context that provides exactly one argument to a macro name. But
|
||
coupled with currying, we can invoke `reverse' with two arguments for
|
||
each definition of a macro stack. This example uses the file
|
||
`m4-1.4.13/examples/curry.m4' included in the distribution.
|
||
|
||
$ m4 -I examples
|
||
include(`curry.m4')include(`stack.m4')
|
||
=>
|
||
define(`reverse', `ifelse(`$#', `0', , `$#', `1', ``$1'',
|
||
`reverse(shift($@)), `$1'')')
|
||
=>
|
||
pushdef(`a', `1')pushdef(`a', `2')pushdef(`a', `3')
|
||
=>
|
||
stack_foreach(`a', `:curry(`reverse', `4')')
|
||
=>:1, 4:2, 4:3, 4
|
||
curry(`curry', `reverse', `1')(`2')(`3')
|
||
=>3, 2, 1
|
||
|
||
Now for the implementation. Notice how `curry' leaves off with a
|
||
macro name but no open parenthesis, while still in the middle of
|
||
collecting arguments for `$1'. The macro `_curry' is the helper macro
|
||
that takes one argument, then adds it to the list and finally supplies
|
||
the closing parenthesis. The use of a comma inside the `shift' call
|
||
allows currying to also work for a macro that takes one argument,
|
||
although it often makes more sense to invoke that macro directly rather
|
||
than going through `curry'.
|
||
|
||
$ m4 -I examples
|
||
undivert(`curry.m4')dnl
|
||
=>divert(`-1')
|
||
=># curry(macro, args)
|
||
=># Expand to a macro call that takes one argument, then invoke
|
||
=># macro(args, extra).
|
||
=>define(`curry', `$1(shift($@,)_$0')
|
||
=>define(`_curry', ``$1')')
|
||
=>divert`'dnl
|
||
|
||
Unfortunately, with M4 1.4.x, `curry' is unable to handle builtin
|
||
tokens, which are silently flattened to the empty string when passed
|
||
through another text macro. This limitation will be lifted in a future
|
||
release of M4.
|
||
|
||
Putting the last few concepts together, it is possible to copy or
|
||
rename an entire stack of macro definitions.
|
||
|
||
-- Composite: copy (SOURCE, DEST)
|
||
-- Composite: rename (SOURCE, DEST)
|
||
Ensure that DEST is undefined, then define it to the same stack of
|
||
definitions currently in SOURCE. `copy' leaves SOURCE unchanged,
|
||
while `rename' undefines SOURCE. There are only a few macros,
|
||
such as `copy' or `defn', which cannot be copied via this macro.
|
||
|
||
The implementation is relatively straightforward (although since it
|
||
uses `curry', it is unable to copy builtin macros, such as the second
|
||
definition of `a' as a synonym for `divnum'. See if you can design a
|
||
version that works around this limitation, or *note Answers: Improved
|
||
copy.).
|
||
|
||
$ m4 -I examples
|
||
include(`curry.m4')include(`stack.m4')
|
||
=>
|
||
define(`rename', `copy($@)undefine(`$1')')dnl
|
||
define(`copy', `ifdef(`$2', `errprint(`$2 already defined
|
||
')m4exit(`1')',
|
||
`stack_foreach(`$1', `curry(`pushdef', `$2')')')')dnl
|
||
pushdef(`a', `1')pushdef(`a', defn(`divnum'))pushdef(`a', `2')
|
||
=>
|
||
copy(`a', `b')
|
||
=>
|
||
rename(`b', `c')
|
||
=>
|
||
a b c
|
||
=>2 b 2
|
||
popdef(`a', `c')c a
|
||
=> 0
|
||
popdef(`a', `c')a c
|
||
=>1 1
|
||
|
||
|
||
File: m4.info, Node: Debugging, Next: Input Control, Prev: Conditionals, Up: Top
|
||
|
||
7 How to debug macros and input
|
||
*******************************
|
||
|
||
When writing macros for `m4', they often do not work as intended on the
|
||
first try (as is the case with most programming languages).
|
||
Fortunately, there is support for macro debugging in `m4'.
|
||
|
||
* Menu:
|
||
|
||
* Dumpdef:: Displaying macro definitions
|
||
* Trace:: Tracing macro calls
|
||
* Debug Levels:: Controlling debugging output
|
||
* Debug Output:: Saving debugging output
|
||
|
||
|
||
File: m4.info, Node: Dumpdef, Next: Trace, Up: Debugging
|
||
|
||
7.1 Displaying macro definitions
|
||
================================
|
||
|
||
If you want to see what a name expands into, you can use the builtin
|
||
`dumpdef':
|
||
|
||
-- Builtin: dumpdef ([NAMES...])
|
||
Accepts any number of arguments. If called without any arguments,
|
||
it displays the definitions of all known names, otherwise it
|
||
displays the definitions of the NAMES given. The output is
|
||
printed to the current debug file (usually standard error), and is
|
||
sorted by name. If an unknown name is encountered, a warning is
|
||
printed.
|
||
|
||
The expansion of `dumpdef' is void.
|
||
|
||
$ m4 -d
|
||
define(`foo', `Hello world.')
|
||
=>
|
||
dumpdef(`foo')
|
||
error-->foo: `Hello world.'
|
||
=>
|
||
dumpdef(`define')
|
||
error-->define: <define>
|
||
=>
|
||
|
||
The last example shows how builtin macros definitions are displayed.
|
||
The definition that is dumped corresponds to what would occur if the
|
||
macro were to be called at that point, even if other definitions are
|
||
still live due to redefining a macro during argument collection.
|
||
|
||
$ m4 -d
|
||
pushdef(`f', ``$0'1')pushdef(`f', ``$0'2')
|
||
=>
|
||
f(popdef(`f')dumpdef(`f'))
|
||
error-->f: ``$0'1'
|
||
=>f2
|
||
f(popdef(`f')dumpdef(`f'))
|
||
error-->m4:stdin:3: undefined macro `f'
|
||
=>f1
|
||
|
||
*Note Debug Levels::, for information on controlling the details of
|
||
the display.
|
||
|
||
|
||
File: m4.info, Node: Trace, Next: Debug Levels, Prev: Dumpdef, Up: Debugging
|
||
|
||
7.2 Tracing macro calls
|
||
=======================
|
||
|
||
It is possible to trace macro calls and expansions through the builtins
|
||
`traceon' and `traceoff':
|
||
|
||
-- Builtin: traceon ([NAMES...])
|
||
-- Builtin: traceoff ([NAMES...])
|
||
When called without any arguments, `traceon' and `traceoff' will
|
||
turn tracing on and off, respectively, for all currently defined
|
||
macros.
|
||
|
||
When called with arguments, only the macros listed in NAMES are
|
||
affected, whether or not they are currently defined.
|
||
|
||
The expansion of `traceon' and `traceoff' is void.
|
||
|
||
Whenever a traced macro is called and the arguments have been
|
||
collected, the call is displayed. If the expansion of the macro call
|
||
is not void, the expansion can be displayed after the call. The output
|
||
is printed to the current debug file (defaulting to standard error,
|
||
*note Debug Output::).
|
||
|
||
$ m4 -d
|
||
define(`foo', `Hello World.')
|
||
=>
|
||
define(`echo', `$@')
|
||
=>
|
||
traceon(`foo', `echo')
|
||
=>
|
||
foo
|
||
error-->m4trace: -1- foo -> `Hello World.'
|
||
=>Hello World.
|
||
echo(`gnus', `and gnats')
|
||
error-->m4trace: -1- echo(`gnus', `and gnats') -> ``gnus',`and gnats''
|
||
=>gnus,and gnats
|
||
|
||
The number between dashes is the depth of the expansion. It is one
|
||
most of the time, signifying an expansion at the outermost level, but it
|
||
increases when macro arguments contain unquoted macro calls. The
|
||
maximum number that will appear between dashes is controlled by the
|
||
option `--nesting-limit' (or `-L', *note Invoking m4: Limits control.).
|
||
Additionally, the option `--trace' (or `-t') can be used to invoke
|
||
`traceon(NAME)' before parsing input.
|
||
|
||
$ m4 -L 3 -t ifelse
|
||
ifelse(`one level')
|
||
error-->m4trace: -1- ifelse
|
||
=>
|
||
ifelse(ifelse(ifelse(`three levels')))
|
||
error-->m4trace: -3- ifelse
|
||
error-->m4trace: -2- ifelse
|
||
error-->m4trace: -1- ifelse
|
||
=>
|
||
ifelse(ifelse(ifelse(ifelse(`four levels'))))
|
||
error-->m4:stdin:3: recursion limit of 3 exceeded, use -L<N> to change it
|
||
|
||
Tracing by name is an attribute that is preserved whether the macro
|
||
is defined or not. This allows the selection of macros to trace before
|
||
those macros are defined.
|
||
|
||
$ m4 -d
|
||
traceoff(`foo')
|
||
=>
|
||
traceon(`foo')
|
||
=>
|
||
foo
|
||
=>foo
|
||
defn(`foo')
|
||
=>
|
||
define(`foo', `bar')
|
||
=>
|
||
foo
|
||
error-->m4trace: -1- foo -> `bar'
|
||
=>bar
|
||
undefine(`foo')
|
||
=>
|
||
ifdef(`foo', `yes', `no')
|
||
=>no
|
||
indir(`foo')
|
||
error-->m4:stdin:9: undefined macro `foo'
|
||
=>
|
||
define(`foo', `blah')
|
||
=>
|
||
foo
|
||
error-->m4trace: -1- foo -> `blah'
|
||
=>blah
|
||
traceoff
|
||
=>
|
||
foo
|
||
=>blah
|
||
|
||
Tracing even works on builtins. However, `defn' (*note Defn::) does
|
||
not transfer tracing status.
|
||
|
||
$ m4 -d
|
||
traceon(`traceon')
|
||
=>
|
||
traceon(`traceoff')
|
||
error-->m4trace: -1- traceon(`traceoff')
|
||
=>
|
||
traceoff(`traceoff')
|
||
error-->m4trace: -1- traceoff(`traceoff')
|
||
=>
|
||
traceoff(`traceon')
|
||
=>
|
||
traceon(`eval', `m4_divnum')
|
||
=>
|
||
define(`m4_eval', defn(`eval'))
|
||
=>
|
||
define(`m4_divnum', defn(`divnum'))
|
||
=>
|
||
eval(divnum)
|
||
error-->m4trace: -1- eval(`0') -> `0'
|
||
=>0
|
||
m4_eval(m4_divnum)
|
||
error-->m4trace: -2- m4_divnum -> `0'
|
||
=>0
|
||
|
||
*Note Debug Levels::, for information on controlling the details of
|
||
the display. The format of the trace output is not specified by POSIX,
|
||
and varies between implementations of `m4'.
|
||
|
||
|
||
File: m4.info, Node: Debug Levels, Next: Debug Output, Prev: Trace, Up: Debugging
|
||
|
||
7.3 Controlling debugging output
|
||
================================
|
||
|
||
The `-d' option to `m4' (or `--debug', *note Invoking m4: Debugging
|
||
options.) controls the amount of details presented in three categories
|
||
of output. Trace output is requested by `traceon' (*note Trace::), and
|
||
each line is prefixed by `m4trace:' in relation to a macro invocation.
|
||
Debug output tracks useful events not associated with a macro
|
||
invocation, and each line is prefixed by `m4debug:'. Finally,
|
||
`dumpdef' (*note Dumpdef::) output is affected, with no prefix added to
|
||
the output lines.
|
||
|
||
The FLAGS following the option can be one or more of the following:
|
||
|
||
`a'
|
||
In trace output, show the actual arguments that were collected
|
||
before invoking the macro. This applies to all macro calls if the
|
||
`t' flag is used, otherwise only the macros covered by calls of
|
||
`traceon'. Arguments are subject to length truncation specified by
|
||
the command line option `--arglength' (or `-l').
|
||
|
||
`c'
|
||
In trace output, show several trace lines for each macro call. A
|
||
line is shown when the macro is seen, but before the arguments are
|
||
collected; a second line when the arguments have been collected
|
||
and a third line after the call has completed.
|
||
|
||
`e'
|
||
In trace output, show the expansion of each macro call, if it is
|
||
not void. This applies to all macro calls if the `t' flag is used,
|
||
otherwise only the macros covered by calls of `traceon'. The
|
||
expansion is subject to length truncation specified by the command
|
||
line option `--arglength' (or `-l').
|
||
|
||
`f'
|
||
In debug and trace output, include the name of the current input
|
||
file in the output line.
|
||
|
||
`i'
|
||
In debug output, print a message each time the current input file
|
||
is changed.
|
||
|
||
`l'
|
||
In debug and trace output, include the current input line number
|
||
in the output line.
|
||
|
||
`p'
|
||
In debug output, print a message when a named file is found
|
||
through the path search mechanism (*note Search Path::), giving
|
||
the actual file name used.
|
||
|
||
`q'
|
||
In trace and dumpdef output, quote actual arguments and macro
|
||
expansions in the display with the current quotes. This is useful
|
||
in connection with the `a' and `e' flags above.
|
||
|
||
`t'
|
||
In trace output, trace all macro calls made in this invocation of
|
||
`m4', regardless of the settings of `traceon'.
|
||
|
||
`x'
|
||
In trace output, add a unique `macro call id' to each line of the
|
||
trace output. This is useful in connection with the `c' flag
|
||
above.
|
||
|
||
`V'
|
||
A shorthand for all of the above flags.
|
||
|
||
If no flags are specified with the `-d' option, the default is
|
||
`aeq'. The examples throughout this manual assume the default flags.
|
||
|
||
There is a builtin macro `debugmode', which allows on-the-fly
|
||
control of the debugging output format:
|
||
|
||
-- Builtin: debugmode ([FLAGS])
|
||
The argument FLAGS should be a subset of the letters listed above.
|
||
As special cases, if the argument starts with a `+', the flags are
|
||
added to the current debug flags, and if it starts with a `-', they
|
||
are removed. If no argument is present, all debugging flags are
|
||
cleared (as if no `-d' was given), and with an empty argument the
|
||
flags are reset to the default of `aeq'.
|
||
|
||
The expansion of `debugmode' is void.
|
||
|
||
$ m4
|
||
define(`foo', `FOO')
|
||
=>
|
||
traceon(`foo')
|
||
=>
|
||
debugmode()
|
||
=>
|
||
foo
|
||
error-->m4trace: -1- foo -> `FOO'
|
||
=>FOO
|
||
debugmode
|
||
=>
|
||
foo
|
||
error-->m4trace: -1- foo
|
||
=>FOO
|
||
debugmode(`+l')
|
||
=>
|
||
foo
|
||
error-->m4trace:8: -1- foo
|
||
=>FOO
|
||
|
||
The following example demonstrates the behavior of length truncation,
|
||
when specified on the command line. Note that each argument and the
|
||
final result are individually truncated. Also, the special tokens for
|
||
builtin functions are not truncated.
|
||
|
||
$ m4 -d -l 6
|
||
define(`echo', `$@')debugmode(`+t')
|
||
=>
|
||
echo(`1', `long string')
|
||
error-->m4trace: -1- echo(`1', `long s...') -> ``1',`l...'
|
||
=>1,long string
|
||
indir(`echo', defn(`changequote'))
|
||
error-->m4trace: -2- defn(`change...')
|
||
error-->m4trace: -1- indir(`echo', <changequote>) -> ``''
|
||
=>
|
||
|
||
This example shows the effects of the debug flags that are not
|
||
related to macro tracing.
|
||
|
||
$ m4 -dip -I examples
|
||
error-->m4debug: input read from stdin
|
||
include(`foo')dnl
|
||
error-->m4debug: path search for `foo' found `examples/foo'
|
||
error-->m4debug: input read from examples/foo
|
||
=>bar
|
||
error-->m4debug: input reverted to stdin, line 1
|
||
^D
|
||
error-->m4debug: input exhausted
|
||
|
||
|
||
File: m4.info, Node: Debug Output, Prev: Debug Levels, Up: Debugging
|
||
|
||
7.4 Saving debugging output
|
||
===========================
|
||
|
||
Debug and tracing output can be redirected to files using either the
|
||
`--debugfile' option to `m4' (*note Invoking m4: Debugging options.),
|
||
or with the builtin macro `debugfile':
|
||
|
||
-- Builtin: debugfile ([FILE])
|
||
Sends all further debug and trace output to FILE, opened in append
|
||
mode. If FILE is the empty string, debug and trace output are
|
||
discarded. If `debugfile' is called without any arguments, debug
|
||
and trace output are sent to standard error. This does not affect
|
||
warnings, error messages, or `errprint' output, which are always
|
||
sent to standard error. If FILE cannot be opened, the current
|
||
debug file is unchanged, and an error is issued.
|
||
|
||
The expansion of `debugfile' is void.
|
||
|
||
$ m4 -d
|
||
traceon(`divnum')
|
||
=>
|
||
divnum(`extra')
|
||
error-->m4:stdin:2: Warning: excess arguments to builtin `divnum' ignored
|
||
error-->m4trace: -1- divnum(`extra') -> `0'
|
||
=>0
|
||
debugfile()
|
||
=>
|
||
divnum(`extra')
|
||
error-->m4:stdin:4: Warning: excess arguments to builtin `divnum' ignored
|
||
=>0
|
||
debugfile
|
||
=>
|
||
divnum
|
||
error-->m4trace: -1- divnum -> `0'
|
||
=>0
|
||
|
||
|
||
File: m4.info, Node: Input Control, Next: File Inclusion, Prev: Debugging, Up: Top
|
||
|
||
8 Input control
|
||
***************
|
||
|
||
This chapter describes various builtin macros for controlling the input
|
||
to `m4'.
|
||
|
||
* Menu:
|
||
|
||
* Dnl:: Deleting whitespace in input
|
||
* Changequote:: Changing the quote characters
|
||
* Changecom:: Changing the comment delimiters
|
||
* Changeword:: Changing the lexical structure of words
|
||
* M4wrap:: Saving text until end of input
|
||
|
||
|
||
File: m4.info, Node: Dnl, Next: Changequote, Up: Input Control
|
||
|
||
8.1 Deleting whitespace in input
|
||
================================
|
||
|
||
The builtin `dnl' stands for "Discard to Next Line":
|
||
|
||
-- Builtin: dnl
|
||
All characters, up to and including the next newline, are discarded
|
||
without performing any macro expansion. A warning is issued if
|
||
the end of the file is encountered without a newline.
|
||
|
||
The expansion of `dnl' is void.
|
||
|
||
It is often used in connection with `define', to remove the newline
|
||
that follows the call to `define'. Thus
|
||
|
||
define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
|
||
foo
|
||
=>Macro foo.
|
||
|
||
The input up to and including the next newline is discarded, as
|
||
opposed to the way comments are treated (*note Comments::).
|
||
|
||
Usually, `dnl' is immediately followed by an end of line or some
|
||
other whitespace. GNU `m4' will produce a warning diagnostic if `dnl'
|
||
is followed by an open parenthesis. In this case, `dnl' will collect
|
||
and process all arguments, looking for a matching close parenthesis.
|
||
All predictable side effects resulting from this collection will take
|
||
place. `dnl' will return no output. The input following the matching
|
||
close parenthesis up to and including the next newline, on whatever
|
||
line containing it, will still be discarded.
|
||
|
||
dnl(`args are ignored, but side effects occur',
|
||
define(`foo', `like this')) while this text is ignored: undefine(`foo')
|
||
error-->m4:stdin:1: Warning: excess arguments to builtin `dnl' ignored
|
||
See how `foo' was defined, foo?
|
||
=>See how foo was defined, like this?
|
||
|
||
If the end of file is encountered without a newline character, a
|
||
warning is issued and dnl stops consuming input.
|
||
|
||
m4wrap(`m4wrap(`2 hi
|
||
')0 hi dnl 1 hi')
|
||
=>
|
||
define(`hi', `HI')
|
||
=>
|
||
^D
|
||
error-->m4:stdin:1: Warning: end of file treated as newline
|
||
=>0 HI 2 HI
|
||
|
||
|
||
File: m4.info, Node: Changequote, Next: Changecom, Prev: Dnl, Up: Input Control
|
||
|
||
8.2 Changing the quote characters
|
||
=================================
|
||
|
||
The default quote delimiters can be changed with the builtin
|
||
`changequote':
|
||
|
||
-- Builtin: changequote ([START = ``'], [END = `''])
|
||
This sets START as the new begin-quote delimiter and END as the
|
||
new end-quote delimiter. If both arguments are missing, the
|
||
default quotes (``' and `'') are used. If START is void, then
|
||
quoting is disabled. Otherwise, if END is missing or void, the
|
||
default end-quote delimiter (`'') is used. The quote delimiters
|
||
can be of any length.
|
||
|
||
The expansion of `changequote' is void.
|
||
|
||
changequote(`[', `]')
|
||
=>
|
||
define([foo], [Macro [foo].])
|
||
=>
|
||
foo
|
||
=>Macro foo.
|
||
|
||
The quotation strings can safely contain eight-bit characters. If
|
||
no single character is appropriate, START and END can be of any length.
|
||
Other implementations cap the delimiter length to five characters, but
|
||
GNU has no inherent limit.
|
||
|
||
changequote(`[[[', `]]]')
|
||
=>
|
||
define([[[foo]]], [[[Macro [[[[[foo]]]]].]]])
|
||
=>
|
||
foo
|
||
=>Macro [[foo]].
|
||
|
||
Calling `changequote' with START as the empty string will
|
||
effectively disable the quoting mechanism, leaving no way to quote text.
|
||
However, using an empty string is not portable, as some other
|
||
implementations of `m4' revert to the default quoting, while others
|
||
preserve the prior non-empty delimiter. If START is not empty, then an
|
||
empty END will use the default end-quote delimiter of `'', as
|
||
otherwise, it would be impossible to end a quoted string. Again, this
|
||
is not portable, as some other `m4' implementations reuse START as the
|
||
end-quote delimiter, while others preserve the previous non-empty
|
||
value. Omitting both arguments restores the default begin-quote and
|
||
end-quote delimiters; fortunately this behavior is portable to all
|
||
implementations of `m4'.
|
||
|
||
define(`foo', `Macro `FOO'.')
|
||
=>
|
||
changequote(`', `')
|
||
=>
|
||
foo
|
||
=>Macro `FOO'.
|
||
`foo'
|
||
=>`Macro `FOO'.'
|
||
changequote(`,)
|
||
=>
|
||
foo
|
||
=>Macro FOO.
|
||
|
||
There is no way in `m4' to quote a string containing an unmatched
|
||
begin-quote, except using `changequote' to change the current quotes.
|
||
|
||
If the quotes should be changed from, say, `[' to `[[', temporary
|
||
quote characters have to be defined. To achieve this, two calls of
|
||
`changequote' must be made, one for the temporary quotes and one for
|
||
the new quotes.
|
||
|
||
Macros are recognized in preference to the begin-quote string, so if
|
||
a prefix of START can be recognized as part of a potential macro name,
|
||
the quoting mechanism is effectively disabled. Unless you use
|
||
`changeword' (*note Changeword::), this means that START should not
|
||
begin with a letter, digit, or `_' (underscore). However, even though
|
||
quoted strings are not recognized, the quote characters can still be
|
||
discerned in macro expansion and in trace output.
|
||
|
||
define(`echo', `$@')
|
||
=>
|
||
define(`hi', `HI')
|
||
=>
|
||
changequote(`q', `Q')
|
||
=>
|
||
q hi Q hi
|
||
=>q HI Q HI
|
||
echo(hi)
|
||
=>qHIQ
|
||
changequote
|
||
=>
|
||
changequote(`-', `EOF')
|
||
=>
|
||
- hi EOF hi
|
||
=> hi HI
|
||
changequote
|
||
=>
|
||
changequote(`1', `2')
|
||
=>
|
||
hi1hi2
|
||
=>hi1hi2
|
||
hi 1hi2
|
||
=>HI hi
|
||
|
||
Quotes are recognized in preference to argument collection. In
|
||
particular, if START is a single `(', then argument collection is
|
||
effectively disabled. For portability with other implementations, it
|
||
is a good idea to avoid `(', `,', and `)' as the first character in
|
||
START.
|
||
|
||
define(`echo', `$#:$@:')
|
||
=>
|
||
define(`hi', `HI')
|
||
=>
|
||
changequote(`(',`)')
|
||
=>
|
||
echo(hi)
|
||
=>0::hi
|
||
changequote
|
||
=>
|
||
changequote(`((', `))')
|
||
=>
|
||
echo(hi)
|
||
=>1:HI:
|
||
echo((hi))
|
||
=>0::hi
|
||
changequote
|
||
=>
|
||
changequote(`,', `)')
|
||
=>
|
||
echo(hi,hi)bye)
|
||
=>1:HIhibye:
|
||
|
||
However, if you are not worried about portability, using `(' and `)'
|
||
as quoting characters has an interesting property--you can use it to
|
||
compute a quoted string containing the expansion of any quoted text, as
|
||
long as the expansion results in both balanced quotes and balanced
|
||
parentheses. The trick is realizing `expand' uses `$1' unquoted, to
|
||
trigger its expansion using the normal quoting characters, but uses
|
||
extra parentheses to group unquoted commas that occur in the expansion
|
||
without consuming whitespace following those commas. Then `_expand'
|
||
uses `changequote' to convert the extra parentheses back into quoting
|
||
characters. Note that it takes two more `changequote' invocations to
|
||
restore the original quotes. Contrast the behavior on whitespace when
|
||
using `$*', via `quote', to attempt the same task.
|
||
|
||
changequote(`[', `]')dnl
|
||
define([a], [1, (b)])dnl
|
||
define([b], [2])dnl
|
||
define([quote], [[$*]])dnl
|
||
define([expand], [_$0(($1))])dnl
|
||
define([_expand],
|
||
[changequote([(], [)])$1changequote`'changequote(`[', `]')])dnl
|
||
expand([a, a, [a, a], [[a, a]]])
|
||
=>1, (2), 1, (2), a, a, [a, a]
|
||
quote(a, a, [a, a], [[a, a]])
|
||
=>1,(2),1,(2),a, a,[a, a]
|
||
|
||
If END is a prefix of START, the end-quote will be recognized in
|
||
preference to a nested begin-quote. In particular, changing the quotes
|
||
to have the same string for START and END disables nesting of quotes.
|
||
When quote nesting is disabled, it is impossible to double-quote
|
||
strings across macro expansions, so using the same string is not done
|
||
very often.
|
||
|
||
define(`hi', `HI')
|
||
=>
|
||
changequote(`""', `"')
|
||
=>
|
||
""hi"""hi"
|
||
=>hihi
|
||
""hi" ""hi"
|
||
=>hi hi
|
||
""hi"" "hi"
|
||
=>hi" "HI"
|
||
changequote
|
||
=>
|
||
`hi`hi'hi'
|
||
=>hi`hi'hi
|
||
changequote(`"', `"')
|
||
=>
|
||
"hi"hi"hi"
|
||
=>hiHIhi
|
||
|
||
It is an error if the end of file occurs within a quoted string.
|
||
|
||
`hello world'
|
||
=>hello world
|
||
`dangling quote
|
||
^D
|
||
error-->m4:stdin:2: ERROR: end of file in string
|
||
|
||
ifelse(`dangling quote
|
||
^D
|
||
error-->m4:stdin:1: ERROR: end of file in string
|
||
|
||
|
||
File: m4.info, Node: Changecom, Next: Changeword, Prev: Changequote, Up: Input Control
|
||
|
||
8.3 Changing the comment delimiters
|
||
===================================
|
||
|
||
The default comment delimiters can be changed with the builtin macro
|
||
`changecom':
|
||
|
||
-- Builtin: changecom ([START], [END = `<NL>'])
|
||
This sets START as the new begin-comment delimiter and END as the
|
||
new end-comment delimiter. If both arguments are missing, or
|
||
START is void, then comments are disabled. Otherwise, if END is
|
||
missing or void, the default end-comment delimiter of newline is
|
||
used. The comment delimiters can be of any length.
|
||
|
||
The expansion of `changecom' is void.
|
||
|
||
define(`comment', `COMMENT')
|
||
=>
|
||
# A normal comment
|
||
=># A normal comment
|
||
changecom(`/*', `*/')
|
||
=>
|
||
# Not a comment anymore
|
||
=># Not a COMMENT anymore
|
||
But: /* this is a comment now */ while this is not a comment
|
||
=>But: /* this is a comment now */ while this is not a COMMENT
|
||
|
||
Note how comments are copied to the output, much as if they were
|
||
quoted strings. If you want the text inside a comment expanded, quote
|
||
the begin-comment delimiter.
|
||
|
||
Calling `changecom' without any arguments, or with START as the
|
||
empty string, will effectively disable the commenting mechanism. To
|
||
restore the original comment start of `#', you must explicitly ask for
|
||
it. If START is not empty, then an empty END will use the default
|
||
end-comment delimiter of newline, as otherwise, it would be impossible
|
||
to end a comment. However, this is not portable, as some other `m4'
|
||
implementations preserve the previous non-empty delimiters instead.
|
||
|
||
define(`comment', `COMMENT')
|
||
=>
|
||
changecom
|
||
=>
|
||
# Not a comment anymore
|
||
=># Not a COMMENT anymore
|
||
changecom(`#', `')
|
||
=>
|
||
# comment again
|
||
=># comment again
|
||
|
||
The comment strings can safely contain eight-bit characters. If no
|
||
single character is appropriate, START and END can be of any length.
|
||
Other implementations cap the delimiter length to five characters, but
|
||
GNU has no inherent limit.
|
||
|
||
Comments are recognized in preference to macros. However, this is
|
||
not compatible with other implementations, where macros and even quoting
|
||
takes precedence over comments, so it may change in a future release.
|
||
For portability, this means that START should not begin with a letter,
|
||
digit, or `_' (underscore), and that neither the start-quote nor the
|
||
start-comment string should be a prefix of the other.
|
||
|
||
define(`hi', `HI')
|
||
=>
|
||
define(`hi1hi2', `hello')
|
||
=>
|
||
changecom(`q', `Q')
|
||
=>
|
||
q hi Q hi
|
||
=>q hi Q HI
|
||
changecom(`1', `2')
|
||
=>
|
||
hi1hi2
|
||
=>hello
|
||
hi 1hi2
|
||
=>HI 1hi2
|
||
|
||
Comments are recognized in preference to argument collection. In
|
||
particular, if START is a single `(', then argument collection is
|
||
effectively disabled. For portability with other implementations, it
|
||
is a good idea to avoid `(', `,', and `)' as the first character in
|
||
START.
|
||
|
||
define(`echo', `$#:$*:$@:')
|
||
=>
|
||
define(`hi', `HI')
|
||
=>
|
||
changecom(`(',`)')
|
||
=>
|
||
echo(hi)
|
||
=>0:::(hi)
|
||
changecom
|
||
=>
|
||
changecom(`((', `))')
|
||
=>
|
||
echo(hi)
|
||
=>1:HI:HI:
|
||
echo((hi))
|
||
=>0:::((hi))
|
||
changecom(`,', `)')
|
||
=>
|
||
echo(hi,hi)bye)
|
||
=>1:HI,hi)bye:HI,hi)bye:
|
||
changecom
|
||
=>
|
||
echo(hi,`,`'hi',hi)
|
||
=>3:HI,,HI,HI:HI,,`'hi,HI:
|
||
echo(hi,`,`'hi',hi`'changecom(`,,', `hi'))
|
||
=>3:HI,,`'hi,HI:HI,,`'hi,HI:
|
||
|
||
It is an error if the end of file occurs within a comment.
|
||
|
||
changecom(`/*', `*/')
|
||
=>
|
||
/*dangling comment
|
||
^D
|
||
error-->m4:stdin:2: ERROR: end of file in comment
|
||
|
||
|
||
File: m4.info, Node: Changeword, Next: M4wrap, Prev: Changecom, Up: Input Control
|
||
|
||
8.4 Changing the lexical structure of words
|
||
===========================================
|
||
|
||
The macro `changeword' and all associated functionality is
|
||
experimental. It is only available if the `--enable-changeword'
|
||
option was given to `configure', at GNU `m4' installation time.
|
||
The functionality will go away in the future, to be replaced by
|
||
other new features that are more efficient at providing the same
|
||
capabilities. _Do not rely on it_. Please direct your comments
|
||
about it the same way you would do for bugs.
|
||
|
||
A file being processed by `m4' is split into quoted strings, words
|
||
(potential macro names) and simple tokens (any other single character).
|
||
Initially a word is defined by the following regular expression:
|
||
|
||
[_a-zA-Z][_a-zA-Z0-9]*
|
||
|
||
Using `changeword', you can change this regular expression:
|
||
|
||
-- Optional builtin: changeword (REGEX)
|
||
Changes the regular expression for recognizing macro names to be
|
||
REGEX. If REGEX is empty, use `[_a-zA-Z][_a-zA-Z0-9]*'. REGEX
|
||
must obey the constraint that every prefix of the desired final
|
||
pattern is also accepted by the regular expression. If REGEX
|
||
contains grouping parentheses, the macro invoked is the portion
|
||
that matched the first group, rather than the entire matching
|
||
string.
|
||
|
||
The expansion of `changeword' is void. The macro `changeword' is
|
||
recognized only with parameters.
|
||
|
||
Relaxing the lexical rules of `m4' might be useful (for example) if
|
||
you wanted to apply translations to a file of numbers:
|
||
|
||
ifdef(`changeword', `', `errprint(` skipping: no changeword support
|
||
')m4exit(`77')')dnl
|
||
changeword(`[_a-zA-Z0-9]+')
|
||
=>
|
||
define(`1', `0')1
|
||
=>0
|
||
|
||
Tightening the lexical rules is less useful, because it will
|
||
generally make some of the builtins unavailable. You could use it to
|
||
prevent accidental call of builtins, for example:
|
||
|
||
ifdef(`changeword', `', `errprint(` skipping: no changeword support
|
||
')m4exit(`77')')dnl
|
||
define(`_indir', defn(`indir'))
|
||
=>
|
||
changeword(`_[_a-zA-Z0-9]*')
|
||
=>
|
||
esyscmd(`foo')
|
||
=>esyscmd(foo)
|
||
_indir(`esyscmd', `echo hi')
|
||
=>hi
|
||
=>
|
||
|
||
Because `m4' constructs its words a character at a time, there is a
|
||
restriction on the regular expressions that may be passed to
|
||
`changeword'. This is that if your regular expression accepts `foo',
|
||
it must also accept `f' and `fo'.
|
||
|
||
ifdef(`changeword', `', `errprint(` skipping: no changeword support
|
||
')m4exit(`77')')dnl
|
||
define(`foo
|
||
', `bar
|
||
')
|
||
=>
|
||
dnl This example wants to recognize changeword, dnl, and `foo\n'.
|
||
dnl First, we check that our regexp will match.
|
||
regexp(`changeword', `[cd][a-z]*\|foo[
|
||
]')
|
||
=>0
|
||
regexp(`foo
|
||
', `[cd][a-z]*\|foo[
|
||
]')
|
||
=>0
|
||
regexp(`f', `[cd][a-z]*\|foo[
|
||
]')
|
||
=>-1
|
||
foo
|
||
=>foo
|
||
changeword(`[cd][a-z]*\|foo[
|
||
]')
|
||
=>
|
||
dnl Even though `foo\n' matches, we forgot to allow `f'.
|
||
foo
|
||
=>foo
|
||
changeword(`[cd][a-z]*\|fo*[
|
||
]?')
|
||
=>
|
||
dnl Now we can call `foo\n'.
|
||
foo
|
||
=>bar
|
||
|
||
`changeword' has another function. If the regular expression
|
||
supplied contains any grouped subexpressions, then text outside the
|
||
first of these is discarded before symbol lookup. So:
|
||
|
||
ifdef(`changeword', `', `errprint(` skipping: no changeword support
|
||
')m4exit(`77')')dnl
|
||
ifdef(`__unix__', ,
|
||
`errprint(` skipping: syscmd does not have unix semantics
|
||
')m4exit(`77')')dnl
|
||
changecom(`/*', `*/')dnl
|
||
define(`foo', `bar')dnl
|
||
changeword(`#\([_a-zA-Z0-9]*\)')
|
||
=>
|
||
#esyscmd(`echo foo \#foo')
|
||
=>foo bar
|
||
=>
|
||
|
||
`m4' now requires a `#' mark at the beginning of every macro
|
||
invocation, so one can use `m4' to preprocess plain text without losing
|
||
various words like `divert'.
|
||
|
||
In `m4', macro substitution is based on text, while in TeX, it is
|
||
based on tokens. `changeword' can throw this difference into relief.
|
||
For example, here is the same idea represented in TeX and `m4'. First,
|
||
the TeX version:
|
||
|
||
\def\a{\message{Hello}}
|
||
\catcode`\@=0
|
||
\catcode`\\=12
|
||
@a
|
||
@bye
|
||
=>Hello
|
||
|
||
Then, the `m4' version:
|
||
|
||
ifdef(`changeword', `', `errprint(` skipping: no changeword support
|
||
')m4exit(`77')')dnl
|
||
define(`a', `errprint(`Hello')')dnl
|
||
changeword(`@\([_a-zA-Z0-9]*\)')
|
||
=>
|
||
@a
|
||
=>errprint(Hello)
|
||
|
||
In the TeX example, the first line defines a macro `a' to print the
|
||
message `Hello'. The second line defines <@> to be usable instead of
|
||
<\> as an escape character. The third line defines <\> to be a normal
|
||
printing character, not an escape. The fourth line invokes the macro
|
||
`a'. So, when TeX is run on this file, it displays the message `Hello'.
|
||
|
||
When the `m4' example is passed through `m4', it outputs
|
||
`errprint(Hello)'. The reason for this is that TeX does lexical
|
||
analysis of macro definition when the macro is _defined_. `m4' just
|
||
stores the text, postponing the lexical analysis until the macro is
|
||
_used_.
|
||
|
||
You should note that using `changeword' will slow `m4' down by a
|
||
factor of about seven, once it is changed to something other than the
|
||
default regular expression. You can invoke `changeword' with the empty
|
||
string to restore the default word definition, and regain the parsing
|
||
speed.
|
||
|
||
|
||
File: m4.info, Node: M4wrap, Prev: Changeword, Up: Input Control
|
||
|
||
8.5 Saving text until end of input
|
||
==================================
|
||
|
||
It is possible to `save' some text until the end of the normal input has
|
||
been seen. Text can be saved, to be read again by `m4' when the normal
|
||
input has been exhausted. This feature is normally used to initiate
|
||
cleanup actions before normal exit, e.g., deleting temporary files.
|
||
|
||
To save input text, use the builtin `m4wrap':
|
||
|
||
-- Builtin: m4wrap (STRING, ...)
|
||
Stores STRING in a safe place, to be reread when end of input is
|
||
reached. As a GNU extension, additional arguments are
|
||
concatenated with a space to the STRING.
|
||
|
||
The expansion of `m4wrap' is void. The macro `m4wrap' is
|
||
recognized only with parameters.
|
||
|
||
define(`cleanup', `This is the `cleanup' action.
|
||
')
|
||
=>
|
||
m4wrap(`cleanup')
|
||
=>
|
||
This is the first and last normal input line.
|
||
=>This is the first and last normal input line.
|
||
^D
|
||
=>This is the cleanup action.
|
||
|
||
The saved input is only reread when the end of normal input is seen,
|
||
and not if `m4exit' is used to exit `m4'.
|
||
|
||
It is safe to call `m4wrap' from saved text, but then the order in
|
||
which the saved text is reread is undefined. If `m4wrap' is not used
|
||
recursively, the saved pieces of text are reread in the opposite order
|
||
in which they were saved (LIFO--last in, first out). However, this
|
||
behavior is likely to change in a future release, to match POSIX, so
|
||
you should not depend on this order.
|
||
|
||
It is possible to emulate POSIX behavior even with older versions of
|
||
GNU M4 by including the file `m4-1.4.13/examples/wrapfifo.m4' from the
|
||
distribution:
|
||
|
||
$ m4 -I examples
|
||
undivert(`wrapfifo.m4')dnl
|
||
=>dnl Redefine m4wrap to have FIFO semantics.
|
||
=>define(`_m4wrap_level', `0')dnl
|
||
=>define(`m4wrap',
|
||
=>`ifdef(`m4wrap'_m4wrap_level,
|
||
=> `define(`m4wrap'_m4wrap_level,
|
||
=> defn(`m4wrap'_m4wrap_level)`$1')',
|
||
=> `builtin(`m4wrap', `define(`_m4wrap_level',
|
||
=> incr(_m4wrap_level))dnl
|
||
=>m4wrap'_m4wrap_level)dnl
|
||
=>define(`m4wrap'_m4wrap_level, `$1')')')dnl
|
||
include(`wrapfifo.m4')
|
||
=>
|
||
m4wrap(`a`'m4wrap(`c
|
||
', `d')')m4wrap(`b')
|
||
=>
|
||
^D
|
||
=>abc
|
||
|
||
It is likewise possible to emulate LIFO behavior without resorting to
|
||
the GNU M4 extension of `builtin', by including the file
|
||
`m4-1.4.13/examples/wraplifo.m4' from the distribution.
|
||
(Unfortunately, both examples shown here share some subtle bugs. See
|
||
if you can find and correct them; or *note Answers: Improved m4wrap.).
|
||
|
||
$ m4 -I examples
|
||
undivert(`wraplifo.m4')dnl
|
||
=>dnl Redefine m4wrap to have LIFO semantics.
|
||
=>define(`_m4wrap_level', `0')dnl
|
||
=>define(`_m4wrap', defn(`m4wrap'))dnl
|
||
=>define(`m4wrap',
|
||
=>`ifdef(`m4wrap'_m4wrap_level,
|
||
=> `define(`m4wrap'_m4wrap_level,
|
||
=> `$1'defn(`m4wrap'_m4wrap_level))',
|
||
=> `_m4wrap(`define(`_m4wrap_level', incr(_m4wrap_level))dnl
|
||
=>m4wrap'_m4wrap_level)dnl
|
||
=>define(`m4wrap'_m4wrap_level, `$1')')')dnl
|
||
include(`wraplifo.m4')
|
||
=>
|
||
m4wrap(`a`'m4wrap(`c
|
||
', `d')')m4wrap(`b')
|
||
=>
|
||
^D
|
||
=>bac
|
||
|
||
Here is an example of implementing a factorial function using
|
||
`m4wrap':
|
||
|
||
define(`f', `ifelse(`$1', `0', `Answer: 0!=1
|
||
', eval(`$1>1'), `0', `Answer: $2$1=eval(`$2$1')
|
||
', `m4wrap(`f(decr(`$1'), `$2$1*')')')')
|
||
=>
|
||
f(`10')
|
||
=>
|
||
^D
|
||
=>Answer: 10*9*8*7*6*5*4*3*2*1=3628800
|
||
|
||
Invocations of `m4wrap' at the same recursion level are concatenated
|
||
and rescanned as usual:
|
||
|
||
define(`aa', `AA
|
||
')
|
||
=>
|
||
m4wrap(`a')m4wrap(`a')
|
||
=>
|
||
^D
|
||
=>AA
|
||
|
||
however, the transition between recursion levels behaves like an end of
|
||
file condition between two input files.
|
||
|
||
m4wrap(`m4wrap(`)')len(abc')
|
||
=>
|
||
^D
|
||
error-->m4:stdin:1: ERROR: end of file in argument list
|
||
|
||
|
||
File: m4.info, Node: File Inclusion, Next: Diversions, Prev: Input Control, Up: Top
|
||
|
||
9 File inclusion
|
||
****************
|
||
|
||
`m4' allows you to include named files at any point in the input.
|
||
|
||
* Menu:
|
||
|
||
* Include:: Including named files
|
||
* Search Path:: Searching for include files
|
||
|
||
|
||
File: m4.info, Node: Include, Next: Search Path, Up: File Inclusion
|
||
|
||
9.1 Including named files
|
||
=========================
|
||
|
||
There are two builtin macros in `m4' for including files:
|
||
|
||
-- Builtin: include (FILE)
|
||
-- Builtin: sinclude (FILE)
|
||
Both macros cause the file named FILE to be read by `m4'. When
|
||
the end of the file is reached, input is resumed from the previous
|
||
input file.
|
||
|
||
The expansion of `include' and `sinclude' is therefore the
|
||
contents of FILE.
|
||
|
||
If FILE does not exist, is a directory, or cannot otherwise be
|
||
read, the expansion is void, and `include' will fail with an error
|
||
while `sinclude' is silent. The empty string counts as a file
|
||
that does not exist.
|
||
|
||
The macros `include' and `sinclude' are recognized only with
|
||
parameters.
|
||
|
||
include(`none')
|
||
error-->m4:stdin:1: cannot open `none': No such file or directory
|
||
=>
|
||
include()
|
||
error-->m4:stdin:2: cannot open `': No such file or directory
|
||
=>
|
||
sinclude(`none')
|
||
=>
|
||
sinclude()
|
||
=>
|
||
|
||
The rest of this section assumes that `m4' is invoked with the `-I'
|
||
option (*note Invoking m4: Preprocessor features.) pointing to the
|
||
`m4-1.4.13/examples' directory shipped as part of the GNU `m4' package.
|
||
The file `m4-1.4.13/examples/incl.m4' in the distribution contains the
|
||
lines:
|
||
|
||
$ cat examples/incl.m4
|
||
=>Include file start
|
||
=>foo
|
||
=>Include file end
|
||
|
||
Normally file inclusion is used to insert the contents of a file
|
||
into the input stream. The contents of the file will be read by `m4'
|
||
and macro calls in the file will be expanded:
|
||
|
||
$ m4 -I examples
|
||
define(`foo', `FOO')
|
||
=>
|
||
include(`incl.m4')
|
||
=>Include file start
|
||
=>FOO
|
||
=>Include file end
|
||
=>
|
||
|
||
The fact that `include' and `sinclude' expand to the contents of the
|
||
file can be used to define macros that operate on entire files. Here
|
||
is an example, which defines `bar' to expand to the contents of
|
||
`incl.m4':
|
||
|
||
$ m4 -I examples
|
||
define(`bar', include(`incl.m4'))
|
||
=>
|
||
This is `bar': >>bar<<
|
||
=>This is bar: >>Include file start
|
||
=>foo
|
||
=>Include file end
|
||
=><<
|
||
|
||
This use of `include' is not trivial, though, as files can contain
|
||
quotes, commas, and parentheses, which can interfere with the way the
|
||
`m4' parser works. GNU `m4' seamlessly concatenates the file contents
|
||
with the next character, even if the included file ended in the middle
|
||
of a comment, string, or macro call. These conditions are only treated
|
||
as end of file errors if specified as input files on the command line.
|
||
|
||
In GNU `m4', an alternative method of reading files is using
|
||
`undivert' (*note Undivert::) on a named file.
|
||
|
||
|
||
File: m4.info, Node: Search Path, Prev: Include, Up: File Inclusion
|
||
|
||
9.2 Searching for include files
|
||
===============================
|
||
|
||
GNU `m4' allows included files to be found in other directories than
|
||
the current working directory.
|
||
|
||
If the `--prepend-include' or `-B' command-line option was provided
|
||
(*note Invoking m4: Preprocessor features.), those directories are
|
||
searched first, in reverse order that those options were listed on the
|
||
command line. Then `m4' looks in the current working directory. Next
|
||
comes the directories specified with the `--include' or `-I' option, in
|
||
the order found on the command line. Finally, if the `M4PATH'
|
||
environment variable is set, it is expected to contain a
|
||
colon-separated list of directories, which will be searched in order.
|
||
|
||
If the automatic search for include-files causes trouble, the `p'
|
||
debug flag (*note Debug Levels::) can help isolate the problem.
|
||
|
||
|
||
File: m4.info, Node: Diversions, Next: Text handling, Prev: File Inclusion, Up: Top
|
||
|
||
10 Diverting and undiverting output
|
||
***********************************
|
||
|
||
Diversions are a way of temporarily saving output. The output of `m4'
|
||
can at any time be diverted to a temporary file, and be reinserted into
|
||
the output stream, "undiverted", again at a later time.
|
||
|
||
Numbered diversions are counted from 0 upwards, diversion number 0
|
||
being the normal output stream. The number of simultaneous diversions
|
||
is limited mainly by the memory used to describe them, because GNU `m4'
|
||
tries to keep diversions in memory. However, there is a limit to the
|
||
overall memory usable by all diversions taken altogether (512K,
|
||
currently). When this maximum is about to be exceeded, a temporary
|
||
file is opened to receive the contents of the biggest diversion still
|
||
in memory, freeing this memory for other diversions. When creating the
|
||
temporary file, `m4' honors the value of the environment variable
|
||
`TMPDIR', and falls back to `/tmp'. So, it is theoretically possible
|
||
that the number and aggregate size of diversions is limited only by
|
||
available disk space.
|
||
|
||
Diversions make it possible to generate output in a different order
|
||
than the input was read. It is possible to implement topological
|
||
sorting dependencies. For example, GNU Autoconf makes use of
|
||
diversions under the hood to ensure that the expansion of a prerequisite
|
||
macro appears in the output prior to the expansion of a dependent macro,
|
||
regardless of which order the two macros were invoked in the user's
|
||
input file.
|
||
|
||
* Menu:
|
||
|
||
* Divert:: Diverting output
|
||
* Undivert:: Undiverting output
|
||
* Divnum:: Diversion numbers
|
||
* Cleardivert:: Discarding diverted text
|
||
|
||
|
||
File: m4.info, Node: Divert, Next: Undivert, Up: Diversions
|
||
|
||
10.1 Diverting output
|
||
=====================
|
||
|
||
Output is diverted using `divert':
|
||
|
||
-- Builtin: divert ([NUMBER = `0'])
|
||
The current diversion is changed to NUMBER. If NUMBER is left out
|
||
or empty, it is assumed to be zero. If NUMBER cannot be parsed,
|
||
the diversion is unchanged.
|
||
|
||
The expansion of `divert' is void.
|
||
|
||
When all the `m4' input will have been processed, all existing
|
||
diversions are automatically undiverted, in numerical order.
|
||
|
||
divert(`1')
|
||
This text is diverted.
|
||
divert
|
||
=>
|
||
This text is not diverted.
|
||
=>This text is not diverted.
|
||
^D
|
||
=>
|
||
=>This text is diverted.
|
||
|
||
Several calls of `divert' with the same argument do not overwrite
|
||
the previous diverted text, but append to it. Diversions are printed
|
||
after any wrapped text is expanded.
|
||
|
||
define(`text', `TEXT')
|
||
=>
|
||
divert(`1')`diverted text.'
|
||
divert
|
||
=>
|
||
m4wrap(`Wrapped text precedes ')
|
||
=>
|
||
^D
|
||
=>Wrapped TEXT precedes diverted text.
|
||
|
||
If output is diverted to a negative diversion, it is simply
|
||
discarded. This can be used to suppress unwanted output. A common
|
||
example of unwanted output is the trailing newlines after macro
|
||
definitions. Here is a common programming idiom in `m4' for avoiding
|
||
them.
|
||
|
||
divert(`-1')
|
||
define(`foo', `Macro `foo'.')
|
||
define(`bar', `Macro `bar'.')
|
||
divert
|
||
=>
|
||
|
||
Traditional implementations only supported ten diversions. But as a
|
||
GNU extension, diversion numbers can be as large as positive integers
|
||
will allow, rather than treating a multi-digit diversion number as a
|
||
request to discard text.
|
||
|
||
divert(eval(`1<<28'))world
|
||
divert(`2')hello
|
||
^D
|
||
=>hello
|
||
=>world
|
||
|
||
Note that `divert' is an English word, but also an active macro
|
||
without arguments. When processing plain text, the word might appear in
|
||
normal text and be unintentionally swallowed as a macro invocation. One
|
||
way to avoid this is to use the `-P' option to rename all builtins
|
||
(*note Invoking m4: Operation modes.). Another is to write a wrapper
|
||
that requires a parameter to be recognized.
|
||
|
||
We decided to divert the stream for irrigation.
|
||
=>We decided to the stream for irrigation.
|
||
define(`divert', `ifelse(`$#', `0', ``$0'', `builtin(`$0', $@)')')
|
||
=>
|
||
divert(`-1')
|
||
Ignored text.
|
||
divert(`0')
|
||
=>
|
||
We decided to divert the stream for irrigation.
|
||
=>We decided to divert the stream for irrigation.
|
||
|
||
|
||
File: m4.info, Node: Undivert, Next: Divnum, Prev: Divert, Up: Diversions
|
||
|
||
10.2 Undiverting output
|
||
=======================
|
||
|
||
Diverted text can be undiverted explicitly using the builtin `undivert':
|
||
|
||
-- Builtin: undivert ([DIVERSIONS...])
|
||
Undiverts the numeric DIVERSIONS given by the arguments, in the
|
||
order given. If no arguments are supplied, all diversions are
|
||
undiverted, in numerical order.
|
||
|
||
As a GNU extension, DIVERSIONS may contain non-numeric strings,
|
||
which are treated as the names of files to copy into the output
|
||
without expansion. A warning is issued if a file could not be
|
||
opened.
|
||
|
||
The expansion of `undivert' is void.
|
||
|
||
divert(`1')
|
||
This text is diverted.
|
||
divert
|
||
=>
|
||
This text is not diverted.
|
||
=>This text is not diverted.
|
||
undivert(`1')
|
||
=>
|
||
=>This text is diverted.
|
||
=>
|
||
|
||
Notice the last two blank lines. One of them comes from the newline
|
||
following `undivert', the other from the newline that followed the
|
||
`divert'! A diversion often starts with a blank line like this.
|
||
|
||
When diverted text is undiverted, it is _not_ reread by `m4', but
|
||
rather copied directly to the current output, and it is therefore not
|
||
an error to undivert into a diversion. Undiverting the empty string is
|
||
the same as specifying diversion 0; in either case nothing happens
|
||
since the output has already been flushed.
|
||
|
||
divert(`1')diverted text
|
||
divert
|
||
=>
|
||
undivert()
|
||
=>
|
||
undivert(`0')
|
||
=>
|
||
undivert
|
||
=>diverted text
|
||
=>
|
||
divert(`1')more
|
||
divert(`2')undivert(`1')diverted text`'divert
|
||
=>
|
||
undivert(`1')
|
||
=>
|
||
undivert(`2')
|
||
=>more
|
||
=>diverted text
|
||
|
||
When a diversion has been undiverted, the diverted text is discarded,
|
||
and it is not possible to bring back diverted text more than once.
|
||
|
||
divert(`1')
|
||
This text is diverted first.
|
||
divert(`0')undivert(`1')dnl
|
||
=>
|
||
=>This text is diverted first.
|
||
undivert(`1')
|
||
=>
|
||
divert(`1')
|
||
This text is also diverted but not appended.
|
||
divert(`0')undivert(`1')dnl
|
||
=>
|
||
=>This text is also diverted but not appended.
|
||
|
||
Attempts to undivert the current diversion are silently ignored.
|
||
Thus, when the current diversion is not 0, the current diversion does
|
||
not get rearranged among the other diversions.
|
||
|
||
divert(`1')one
|
||
divert(`2')two
|
||
divert(`3')three
|
||
divert(`2')undivert`'dnl
|
||
divert`'undivert`'dnl
|
||
=>two
|
||
=>one
|
||
=>three
|
||
|
||
GNU `m4' allows named files to be undiverted. Given a non-numeric
|
||
argument, the contents of the file named will be copied, uninterpreted,
|
||
to the current output. This complements the builtin `include' (*note
|
||
Include::). To illustrate the difference, assume the file `foo'
|
||
contains:
|
||
|
||
$ cat foo
|
||
bar
|
||
|
||
then
|
||
|
||
define(`bar', `BAR')
|
||
=>
|
||
undivert(`foo')
|
||
=>bar
|
||
=>
|
||
include(`foo')
|
||
=>BAR
|
||
=>
|
||
|
||
If the file is not found (or cannot be read), an error message is
|
||
issued, and the expansion is void. It is possible to intermix files
|
||
and diversion numbers.
|
||
|
||
divert(`1')diversion one
|
||
divert(`2')undivert(`foo')dnl
|
||
divert(`3')diversion three
|
||
divert`'dnl
|
||
undivert(`1', `2', `foo', `3')dnl
|
||
=>diversion one
|
||
=>bar
|
||
=>bar
|
||
=>diversion three
|
||
|
||
|
||
File: m4.info, Node: Divnum, Next: Cleardivert, Prev: Undivert, Up: Diversions
|
||
|
||
10.3 Diversion numbers
|
||
======================
|
||
|
||
The current diversion is tracked by the builtin `divnum':
|
||
|
||
-- Builtin: divnum
|
||
Expands to the number of the current diversion.
|
||
|
||
Initial divnum
|
||
=>Initial 0
|
||
divert(`1')
|
||
Diversion one: divnum
|
||
divert(`2')
|
||
Diversion two: divnum
|
||
^D
|
||
=>
|
||
=>Diversion one: 1
|
||
=>
|
||
=>Diversion two: 2
|
||
|
||
|
||
File: m4.info, Node: Cleardivert, Prev: Divnum, Up: Diversions
|
||
|
||
10.4 Discarding diverted text
|
||
=============================
|
||
|
||
Often it is not known, when output is diverted, whether the diverted
|
||
text is actually needed. Since all non-empty diversion are brought back
|
||
on the main output stream when the end of input is seen, a method of
|
||
discarding a diversion is needed. If all diversions should be
|
||
discarded, the easiest is to end the input to `m4' with `divert(`-1')'
|
||
followed by an explicit `undivert':
|
||
|
||
divert(`1')
|
||
Diversion one: divnum
|
||
divert(`2')
|
||
Diversion two: divnum
|
||
divert(`-1')
|
||
undivert
|
||
^D
|
||
|
||
No output is produced at all.
|
||
|
||
Clearing selected diversions can be done with the following macro:
|
||
|
||
-- Composite: cleardivert ([DIVERSIONS...])
|
||
Discard the contents of each of the listed numeric DIVERSIONS.
|
||
|
||
define(`cleardivert',
|
||
`pushdef(`_n', divnum)divert(`-1')undivert($@)divert(_n)popdef(`_n')')
|
||
=>
|
||
|
||
It is called just like `undivert', but the effect is to clear the
|
||
diversions, given by the arguments. (This macro has a nasty bug! You
|
||
should try to see if you can find it and correct it; or *note Answers:
|
||
Improved cleardivert.).
|
||
|
||
|
||
File: m4.info, Node: Text handling, Next: Arithmetic, Prev: Diversions, Up: Top
|
||
|
||
11 Macros for text handling
|
||
***************************
|
||
|
||
There are a number of builtins in `m4' for manipulating text in various
|
||
ways, extracting substrings, searching, substituting, and so on.
|
||
|
||
* Menu:
|
||
|
||
* Len:: Calculating length of strings
|
||
* Index macro:: Searching for substrings
|
||
* Regexp:: Searching for regular expressions
|
||
* Substr:: Extracting substrings
|
||
* Translit:: Translating characters
|
||
* Patsubst:: Substituting text by regular expression
|
||
* Format:: Formatting strings (printf-like)
|
||
|
||
|
||
File: m4.info, Node: Len, Next: Index macro, Up: Text handling
|
||
|
||
11.1 Calculating length of strings
|
||
==================================
|
||
|
||
The length of a string can be calculated by `len':
|
||
|
||
-- Builtin: len (STRING)
|
||
Expands to the length of STRING, as a decimal number.
|
||
|
||
The macro `len' is recognized only with parameters.
|
||
|
||
len()
|
||
=>0
|
||
len(`abcdef')
|
||
=>6
|
||
|
||
|
||
File: m4.info, Node: Index macro, Next: Regexp, Prev: Len, Up: Text handling
|
||
|
||
11.2 Searching for substrings
|
||
=============================
|
||
|
||
Searching for substrings is done with `index':
|
||
|
||
-- Builtin: index (STRING, SUBSTRING)
|
||
Expands to the index of the first occurrence of SUBSTRING in
|
||
STRING. The first character in STRING has index 0. If SUBSTRING
|
||
does not occur in STRING, `index' expands to `-1'.
|
||
|
||
The macro `index' is recognized only with parameters.
|
||
|
||
index(`gnus, gnats, and armadillos', `nat')
|
||
=>7
|
||
index(`gnus, gnats, and armadillos', `dag')
|
||
=>-1
|
||
|
||
Omitting SUBSTRING evokes a warning, but still produces output;
|
||
contrast this with an empty SUBSTRING.
|
||
|
||
index(`abc')
|
||
error-->m4:stdin:1: Warning: too few arguments to builtin `index'
|
||
=>0
|
||
index(`abc', `')
|
||
=>0
|
||
index(`abc', `b')
|
||
=>1
|
||
|
||
|
||
File: m4.info, Node: Regexp, Next: Substr, Prev: Index macro, Up: Text handling
|
||
|
||
11.3 Searching for regular expressions
|
||
======================================
|
||
|
||
Searching for regular expressions is done with the builtin `regexp':
|
||
|
||
-- Builtin: regexp (STRING, REGEXP, [REPLACEMENT])
|
||
Searches for REGEXP in STRING. The syntax for regular expressions
|
||
is the same as in GNU Emacs, which is similar to BRE (Basic
|
||
Regular Expressions) in POSIX. *Note Syntax of Regular
|
||
Expressions: (emacs)Regexps. Support for ERE (Extended Regular
|
||
Expressions) is not available, but will be added in GNU M4 2.0.
|
||
|
||
If REPLACEMENT is omitted, `regexp' expands to the index of the
|
||
first match of REGEXP in STRING. If REGEXP does not match
|
||
anywhere in STRING, it expands to -1.
|
||
|
||
If REPLACEMENT is supplied, and there was a match, `regexp'
|
||
changes the expansion to this argument, with `\N' substituted by
|
||
the text matched by the Nth parenthesized sub-expression of
|
||
REGEXP, up to nine sub-expressions. The escape `\&' is replaced
|
||
by the text of the entire regular expression matched. For all
|
||
other characters, `\' treats the next character literally. A
|
||
warning is issued if there were fewer sub-expressions than the
|
||
`\N' requested, or if there is a trailing `\'. If there was no
|
||
match, `regexp' expands to the empty string.
|
||
|
||
The macro `regexp' is recognized only with parameters.
|
||
|
||
regexp(`GNUs not Unix', `\<[a-z]\w+')
|
||
=>5
|
||
regexp(`GNUs not Unix', `\<Q\w*')
|
||
=>-1
|
||
regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
|
||
=>*** Unix *** nix ***
|
||
regexp(`GNUs not Unix', `\<Q\w*', `*** \& *** \1 ***')
|
||
=>
|
||
|
||
Here are some more examples on the handling of backslash:
|
||
|
||
regexp(`abc', `\(b\)', `\\\10\a')
|
||
=>\b0a
|
||
regexp(`abc', `b', `\1\')
|
||
error-->m4:stdin:2: Warning: sub-expression 1 not present
|
||
error-->m4:stdin:2: Warning: trailing \ ignored in replacement
|
||
=>
|
||
regexp(`abc', `\(\(d\)?\)\(c\)', `\1\2\3\4\5\6')
|
||
error-->m4:stdin:3: Warning: sub-expression 4 not present
|
||
error-->m4:stdin:3: Warning: sub-expression 5 not present
|
||
error-->m4:stdin:3: Warning: sub-expression 6 not present
|
||
=>c
|
||
|
||
Omitting REGEXP evokes a warning, but still produces output;
|
||
contrast this with an empty REGEXP argument.
|
||
|
||
regexp(`abc')
|
||
error-->m4:stdin:1: Warning: too few arguments to builtin `regexp'
|
||
=>0
|
||
regexp(`abc', `')
|
||
=>0
|
||
regexp(`abc', `', `\\def')
|
||
=>\def
|
||
|
||
|
||
File: m4.info, Node: Substr, Next: Translit, Prev: Regexp, Up: Text handling
|
||
|
||
11.4 Extracting substrings
|
||
==========================
|
||
|
||
Substrings are extracted with `substr':
|
||
|
||
-- Builtin: substr (STRING, FROM, [LENGTH])
|
||
Expands to the substring of STRING, which starts at index FROM,
|
||
and extends for LENGTH characters, or to the end of STRING, if
|
||
LENGTH is omitted. The starting index of a string is always 0.
|
||
The expansion is empty if there is an error parsing FROM or
|
||
LENGTH, if FROM is beyond the end of STRING, or if LENGTH is
|
||
negative.
|
||
|
||
The macro `substr' is recognized only with parameters.
|
||
|
||
substr(`gnus, gnats, and armadillos', `6')
|
||
=>gnats, and armadillos
|
||
substr(`gnus, gnats, and armadillos', `6', `5')
|
||
=>gnats
|
||
|
||
Omitting FROM evokes a warning, but still produces output.
|
||
|
||
substr(`abc')
|
||
error-->m4:stdin:1: Warning: too few arguments to builtin `substr'
|
||
=>abc
|
||
substr(`abc',)
|
||
error-->m4:stdin:2: empty string treated as 0 in builtin `substr'
|
||
=>abc
|
||
|
||
|
||
File: m4.info, Node: Translit, Next: Patsubst, Prev: Substr, Up: Text handling
|
||
|
||
11.5 Translating characters
|
||
===========================
|
||
|
||
Character translation is done with `translit':
|
||
|
||
-- Builtin: translit (STRING, CHARS, [REPLACEMENT])
|
||
Expands to STRING, with each character that occurs in CHARS
|
||
translated into the character from REPLACEMENT with the same index.
|
||
|
||
If REPLACEMENT is shorter than CHARS, the excess characters of
|
||
CHARS are deleted from the expansion; if CHARS is shorter, the
|
||
excess characters in REPLACEMENT are silently ignored. If
|
||
REPLACEMENT is omitted, all characters in STRING that are present
|
||
in CHARS are deleted from the expansion. If a character appears
|
||
more than once in CHARS, only the first instance is used in making
|
||
the translation. Only a single translation pass is made, even if
|
||
characters in REPLACEMENT also appear in CHARS.
|
||
|
||
As a GNU extension, both CHARS and REPLACEMENT can contain
|
||
character-ranges, e.g., `a-z' (meaning all lowercase letters) or
|
||
`0-9' (meaning all digits). To include a dash `-' in CHARS or
|
||
REPLACEMENT, place it first or last in the entire string, or as
|
||
the last character of a range. Back-to-back ranges can share a
|
||
common endpoint. It is not an error for the last character in the
|
||
range to be `larger' than the first. In that case, the range runs
|
||
backwards, i.e., `9-0' means the string `9876543210'. The
|
||
expansion of a range is dependent on the underlying encoding of
|
||
characters, so using ranges is not always portable between
|
||
machines.
|
||
|
||
The macro `translit' is recognized only with parameters.
|
||
|
||
translit(`GNUs not Unix', `A-Z')
|
||
=>s not nix
|
||
translit(`GNUs not Unix', `a-z', `A-Z')
|
||
=>GNUS NOT UNIX
|
||
translit(`GNUs not Unix', `A-Z', `z-a')
|
||
=>tmfs not fnix
|
||
translit(`+,-12345', `+--1-5', `<;>a-c-a')
|
||
=><;>abcba
|
||
translit(`abcdef', `aabdef', `bcged')
|
||
=>bgced
|
||
|
||
In the ASCII encoding, the first example deletes all uppercase
|
||
letters, the second converts lowercase to uppercase, and the third
|
||
`mirrors' all uppercase letters, while converting them to lowercase.
|
||
The two first cases are by far the most common, even though they are not
|
||
portable to EBCDIC or other encodings. The fourth example shows a
|
||
range ending in `-', as well as back-to-back ranges. The final example
|
||
shows that `a' is mapped to `b', not `c'; the resulting `b' is not
|
||
further remapped to `g'; the `d' and `e' are swapped, and the `f' is
|
||
discarded.
|
||
|
||
Omitting CHARS evokes a warning, but still produces output.
|
||
|
||
translit(`abc')
|
||
error-->m4:stdin:1: Warning: too few arguments to builtin `translit'
|
||
=>abc
|
||
|
||
|
||
File: m4.info, Node: Patsubst, Next: Format, Prev: Translit, Up: Text handling
|
||
|
||
11.6 Substituting text by regular expression
|
||
============================================
|
||
|
||
Global substitution in a string is done by `patsubst':
|
||
|
||
-- Builtin: patsubst (STRING, REGEXP, [REPLACEMENT])
|
||
Searches STRING for matches of REGEXP, and substitutes REPLACEMENT
|
||
for each match. The syntax for regular expressions is the same as
|
||
in GNU Emacs (*note Regexp::).
|
||
|
||
The parts of STRING that are not covered by any match of REGEXP
|
||
are copied to the expansion. Whenever a match is found, the
|
||
search proceeds from the end of the match, so a character from
|
||
STRING will never be substituted twice. If REGEXP matches a
|
||
string of zero length, the start position for the search is
|
||
incremented, to avoid infinite loops.
|
||
|
||
When a replacement is to be made, REPLACEMENT is inserted into the
|
||
expansion, with `\N' substituted by the text matched by the Nth
|
||
parenthesized sub-expression of PATSUBST, for up to nine
|
||
sub-expressions. The escape `\&' is replaced by the text of the
|
||
entire regular expression matched. For all other characters, `\'
|
||
treats the next character literally. A warning is issued if there
|
||
were fewer sub-expressions than the `\N' requested, or if there is
|
||
a trailing `\'.
|
||
|
||
The REPLACEMENT argument can be omitted, in which case the text
|
||
matched by REGEXP is deleted.
|
||
|
||
The macro `patsubst' is recognized only with parameters.
|
||
|
||
patsubst(`GNUs not Unix', `^', `OBS: ')
|
||
=>OBS: GNUs not Unix
|
||
patsubst(`GNUs not Unix', `\<', `OBS: ')
|
||
=>OBS: GNUs OBS: not OBS: Unix
|
||
patsubst(`GNUs not Unix', `\w*', `(\&)')
|
||
=>(GNUs)() (not)() (Unix)()
|
||
patsubst(`GNUs not Unix', `\w+', `(\&)')
|
||
=>(GNUs) (not) (Unix)
|
||
patsubst(`GNUs not Unix', `[A-Z][a-z]+')
|
||
=>GN not
|
||
patsubst(`GNUs not Unix', `not', `NOT\')
|
||
error-->m4:stdin:6: Warning: trailing \ ignored in replacement
|
||
=>GNUs NOT Unix
|
||
|
||
Here is a slightly more realistic example, which capitalizes
|
||
individual words or whole sentences, by substituting calls of the macros
|
||
`upcase' and `downcase' into the strings.
|
||
|
||
-- Composite: upcase (TEXT)
|
||
-- Composite: downcase (TEXT)
|
||
-- Composite: capitalize (TEXT)
|
||
Expand to TEXT, but with capitalization changed: `upcase' changes
|
||
all letters to upper case, `downcase' changes all letters to lower
|
||
case, and `capitalize' changes the first character of each word to
|
||
upper case and the remaining characters to lower case.
|
||
|
||
First, an example of their usage, using implementations distributed
|
||
in `m4-1.4.13/examples/capitalize.m4'.
|
||
|
||
$ m4 -I examples
|
||
include(`capitalize.m4')
|
||
=>
|
||
upcase(`GNUs not Unix')
|
||
=>GNUS NOT UNIX
|
||
downcase(`GNUs not Unix')
|
||
=>gnus not unix
|
||
capitalize(`GNUs not Unix')
|
||
=>Gnus Not Unix
|
||
|
||
Now for the implementation. There is a helper macro `_capitalize'
|
||
which puts only its first word in mixed case. Then `capitalize' merely
|
||
parses out the words, and replaces them with an invocation of
|
||
`_capitalize'. (As presented here, the `capitalize' macro has some
|
||
subtle flaws. You should try to see if you can find and correct them;
|
||
or *note Answers: Improved capitalize.).
|
||
|
||
$ m4 -I examples
|
||
undivert(`capitalize.m4')dnl
|
||
=>divert(`-1')
|
||
=># upcase(text)
|
||
=># downcase(text)
|
||
=># capitalize(text)
|
||
=># change case of text, simple version
|
||
=>define(`upcase', `translit(`$*', `a-z', `A-Z')')
|
||
=>define(`downcase', `translit(`$*', `A-Z', `a-z')')
|
||
=>define(`_capitalize',
|
||
=> `regexp(`$1', `^\(\w\)\(\w*\)',
|
||
=> `upcase(`\1')`'downcase(`\2')')')
|
||
=>define(`capitalize', `patsubst(`$1', `\w+', `_$0(`\&')')')
|
||
=>divert`'dnl
|
||
|
||
While `regexp' replaces the whole input with the replacement as soon
|
||
as there is a match, `patsubst' replaces each _occurrence_ of a match
|
||
and preserves non-matching pieces:
|
||
|
||
define(`patreg',
|
||
`patsubst($@)
|
||
regexp($@)')dnl
|
||
patreg(`bar foo baz Foo', `foo\|Foo', `FOO')
|
||
=>bar FOO baz FOO
|
||
=>FOO
|
||
patreg(`aba abb 121', `\(.\)\(.\)\1', `\2\1\2')
|
||
=>bab abb 212
|
||
=>bab
|
||
|
||
Omitting REGEXP evokes a warning, but still produces output;
|
||
contrast this with an empty REGEXP argument.
|
||
|
||
patsubst(`abc')
|
||
error-->m4:stdin:1: Warning: too few arguments to builtin `patsubst'
|
||
=>abc
|
||
patsubst(`abc', `')
|
||
=>abc
|
||
patsubst(`abc', `', `\\-')
|
||
=>\-a\-b\-c\-
|
||
|
||
|
||
File: m4.info, Node: Format, Prev: Patsubst, Up: Text handling
|
||
|
||
11.7 Formatting strings (printf-like)
|
||
=====================================
|
||
|
||
Formatted output can be made with `format':
|
||
|
||
-- Builtin: format (FORMAT-STRING, ...)
|
||
Works much like the C function `printf'. The first argument
|
||
FORMAT-STRING can contain `%' specifications which are satisfied
|
||
by additional arguments, and the expansion of `format' is the
|
||
formatted string.
|
||
|
||
The macro `format' is recognized only with parameters.
|
||
|
||
Its use is best described by a few examples:
|
||
|
||
define(`foo', `The brown fox jumped over the lazy dog')
|
||
=>
|
||
format(`The string "%s" uses %d characters', foo, len(foo))
|
||
=>The string "The brown fox jumped over the lazy dog" uses 38 characters
|
||
format(`%*.*d', `-1', `-1', `1')
|
||
=>1
|
||
format(`%.0f', `56789.9876')
|
||
=>56790
|
||
len(format(`%-*X', `5000', `1'))
|
||
=>5000
|
||
ifelse(format(`%010F', `infinity'), ` INF', `success',
|
||
format(`%010F', `infinity'), ` INFINITY', `success',
|
||
format(`%010F', `infinity'))
|
||
=>success
|
||
ifelse(format(`%.1A', `1.999'), `0X1.0P+1', `success',
|
||
format(`%.1A', `1.999'), `0X2.0P+0', `success',
|
||
format(`%.1A', `1.999'))
|
||
=>success
|
||
format(`%g', `0xa.P+1')
|
||
=>20
|
||
|
||
Using the `forloop' macro defined earlier (*note Forloop::), this
|
||
example shows how `format' can be used to produce tabular output.
|
||
|
||
$ m4 -I examples
|
||
include(`forloop.m4')
|
||
=>
|
||
forloop(`i', `1', `10', `format(`%6d squared is %10d
|
||
', i, eval(i**2))')
|
||
=> 1 squared is 1
|
||
=> 2 squared is 4
|
||
=> 3 squared is 9
|
||
=> 4 squared is 16
|
||
=> 5 squared is 25
|
||
=> 6 squared is 36
|
||
=> 7 squared is 49
|
||
=> 8 squared is 64
|
||
=> 9 squared is 81
|
||
=> 10 squared is 100
|
||
=>
|
||
|
||
The builtin `format' is modeled after the ANSI C `printf' function,
|
||
and supports these `%' specifiers: `c', `s', `d', `o', `x', `X', `u',
|
||
`a', `A', `e', `E', `f', `F', `g', `G', and `%'; it supports field
|
||
widths and precisions, and the flags `+', `-', ` ', `0', `#', and `''.
|
||
For integer specifiers, the width modifiers `hh', `h', and `l' are
|
||
recognized, and for floating point specifiers, the width modifier `l'
|
||
is recognized. Items not yet supported include positional arguments,
|
||
the `n', `p', `S', and `C' specifiers, the `z', `t', `j', `L' and `ll'
|
||
modifiers, and any platform extensions available in the native
|
||
`printf'. For more details on the functioning of `printf', see the C
|
||
Library Manual, or the POSIX specification (for example, `%a' is
|
||
supported even on platforms that haven't yet implemented C99
|
||
hexadecimal floating point output natively).
|
||
|
||
Unrecognized specifiers result in a warning. It is anticipated that
|
||
a future release of GNU `m4' will support more specifiers, and give
|
||
better warnings when various problems such as overflow are encountered.
|
||
Likewise, escape sequences are not yet recognized.
|
||
|
||
format(`%p', `0')
|
||
error-->m4:stdin:1: Warning: unrecognized specifier in `%p'
|
||
=>
|
||
|
||
|
||
File: m4.info, Node: Arithmetic, Next: Shell commands, Prev: Text handling, Up: Top
|
||
|
||
12 Macros for doing arithmetic
|
||
******************************
|
||
|
||
Integer arithmetic is included in `m4', with a C-like syntax. As
|
||
convenient shorthands, there are builtins for simple increment and
|
||
decrement operations.
|
||
|
||
* Menu:
|
||
|
||
* Incr:: Decrement and increment operators
|
||
* Eval:: Evaluating integer expressions
|
||
|
||
|
||
File: m4.info, Node: Incr, Next: Eval, Up: Arithmetic
|
||
|
||
12.1 Decrement and increment operators
|
||
======================================
|
||
|
||
Increment and decrement of integers are supported using the builtins
|
||
`incr' and `decr':
|
||
|
||
-- Builtin: incr (NUMBER)
|
||
-- Builtin: decr (NUMBER)
|
||
Expand to the numerical value of NUMBER, incremented or
|
||
decremented, respectively, by one. Except for the empty string,
|
||
the expansion is empty if NUMBER could not be parsed.
|
||
|
||
The macros `incr' and `decr' are recognized only with parameters.
|
||
|
||
incr(`4')
|
||
=>5
|
||
decr(`7')
|
||
=>6
|
||
incr()
|
||
error-->m4:stdin:3: empty string treated as 0 in builtin `incr'
|
||
=>1
|
||
decr()
|
||
error-->m4:stdin:4: empty string treated as 0 in builtin `decr'
|
||
=>-1
|
||
|
||
|
||
File: m4.info, Node: Eval, Prev: Incr, Up: Arithmetic
|
||
|
||
12.2 Evaluating integer expressions
|
||
===================================
|
||
|
||
Integer expressions are evaluated with `eval':
|
||
|
||
-- Builtin: eval (EXPRESSION, [RADIX = `10'], [WIDTH])
|
||
Expands to the value of EXPRESSION. The expansion is empty if a
|
||
problem is encountered while parsing the arguments. If specified,
|
||
RADIX and WIDTH control the format of the output.
|
||
|
||
Calculations are done with 32-bit signed numbers. Overflow
|
||
silently results in wraparound. A warning is issued if division
|
||
by zero is attempted, or if EXPRESSION could not be parsed.
|
||
|
||
Expressions can contain the following operators, listed in order of
|
||
decreasing precedence.
|
||
|
||
`()'
|
||
Parentheses
|
||
|
||
`+ - ~ !'
|
||
Unary plus and minus, and bitwise and logical negation
|
||
|
||
`**'
|
||
Exponentiation
|
||
|
||
`* / %'
|
||
Multiplication, division, and modulo
|
||
|
||
`+ -'
|
||
Addition and subtraction
|
||
|
||
`<< >>'
|
||
Shift left or right
|
||
|
||
`> >= < <='
|
||
Relational operators
|
||
|
||
`== !='
|
||
Equality operators
|
||
|
||
`&'
|
||
Bitwise and
|
||
|
||
`^'
|
||
Bitwise exclusive-or
|
||
|
||
`|'
|
||
Bitwise or
|
||
|
||
`&&'
|
||
Logical and
|
||
|
||
`||'
|
||
Logical or
|
||
|
||
The macro `eval' is recognized only with parameters.
|
||
|
||
All binary operators, except exponentiation, are left associative. C
|
||
operators that perform variable assignment, such as `+=' or `--', are
|
||
not implemented, since `eval' only operates on constants, not
|
||
variables. Attempting to use them results in an error. However, since
|
||
traditional implementations treated `=' as an undocumented alias for
|
||
`==' as opposed to an assignment operator, this usage is supported as a
|
||
special case. Be aware that a future version of GNU M4 may support
|
||
assignment semantics as an extension when POSIX mode is not requested,
|
||
and that using `=' to check equality is not portable.
|
||
|
||
eval(`2 = 2')
|
||
error-->m4:stdin:1: Warning: recommend ==, not =, for equality operator
|
||
=>1
|
||
eval(`++0')
|
||
error-->m4:stdin:2: invalid operator in eval: ++0
|
||
=>
|
||
eval(`0 |= 1')
|
||
error-->m4:stdin:3: invalid operator in eval: 0 |= 1
|
||
=>
|
||
|
||
Note that some older `m4' implementations use `^' as an alternate
|
||
operator for the exponentiation, although POSIX requires the C behavior
|
||
of bitwise exclusive-or. The precedence of the negation operators, `~'
|
||
and `!', was traditionally lower than equality. The unary operators
|
||
could not be used reliably more than once on the same term without
|
||
intervening parentheses. The traditional precedence of the equality
|
||
operators `==' and `!=' was identical instead of lower than the
|
||
relational operators such as `<', even through GNU M4 1.4.8. Starting
|
||
with version 1.4.9, GNU M4 correctly follows POSIX precedence rules.
|
||
M4 scripts designed to be portable between releases must be aware that
|
||
parentheses may be required to enforce C precedence rules. Likewise,
|
||
division by zero, even in the unused branch of a short-circuiting
|
||
operator, is not always well-defined in other implementations.
|
||
|
||
Following are some examples where the current version of M4 follows C
|
||
precedence rules, but where older versions and some other
|
||
implementations of `m4' require explicit parentheses to get the correct
|
||
result:
|
||
|
||
eval(`1 == 2 > 0')
|
||
=>1
|
||
eval(`(1 == 2) > 0')
|
||
=>0
|
||
eval(`! 0 * 2')
|
||
=>2
|
||
eval(`! (0 * 2)')
|
||
=>1
|
||
eval(`1 | 1 ^ 1')
|
||
=>1
|
||
eval(`(1 | 1) ^ 1')
|
||
=>0
|
||
eval(`+ + - ~ ! ~ 0')
|
||
=>1
|
||
eval(`2 || 1 / 0')
|
||
=>1
|
||
eval(`0 || 1 / 0')
|
||
error-->m4:stdin:9: divide by zero in eval: 0 || 1 / 0
|
||
=>
|
||
eval(`0 && 1 % 0')
|
||
=>0
|
||
eval(`2 && 1 % 0')
|
||
error-->m4:stdin:11: modulo by zero in eval: 2 && 1 % 0
|
||
=>
|
||
|
||
As a GNU extension, the operator `**' performs integral
|
||
exponentiation. The operator is right-associative, and if evaluated,
|
||
the exponent must be non-negative, and at least one of the arguments
|
||
must be non-zero, or a warning is issued.
|
||
|
||
eval(`2 ** 3 ** 2')
|
||
=>512
|
||
eval(`(2 ** 3) ** 2')
|
||
=>64
|
||
eval(`0 ** 1')
|
||
=>0
|
||
eval(`2 ** 0')
|
||
=>1
|
||
eval(`0 ** 0')
|
||
=>
|
||
error-->m4:stdin:5: divide by zero in eval: 0 ** 0
|
||
eval(`4 ** -2')
|
||
error-->m4:stdin:6: negative exponent in eval: 4 ** -2
|
||
=>
|
||
|
||
Within EXPRESSION, (but not RADIX or WIDTH), numbers without a
|
||
special prefix are decimal. A simple `0' prefix introduces an octal
|
||
number. `0x' introduces a hexadecimal number. As GNU extensions, `0b'
|
||
introduces a binary number. `0r' introduces a number expressed in any
|
||
radix between 1 and 36: the prefix should be immediately followed by
|
||
the decimal expression of the radix, a colon, then the digits making
|
||
the number. For radix 1, leading zeros are ignored, and all remaining
|
||
digits must be `1'; for all other radices, the digits are `0', `1', `2',
|
||
.... Beyond `9', the digits are `a', `b' ... up to `z'. Lower and
|
||
upper case letters can be used interchangeably in numbers prefixes and
|
||
as number digits.
|
||
|
||
Parentheses may be used to group subexpressions whenever needed.
|
||
For the relational operators, a true relation returns `1', and a false
|
||
relation return `0'.
|
||
|
||
Here are a few examples of use of `eval'.
|
||
|
||
eval(`-3 * 5')
|
||
=>-15
|
||
eval(`-99 / 10')
|
||
=>-9
|
||
eval(`-99 % 10')
|
||
=>-9
|
||
eval(`99 % -10')
|
||
=>9
|
||
eval(index(`Hello world', `llo') >= 0)
|
||
=>1
|
||
eval(`0r1:0111 + 0b100 + 0r3:12')
|
||
=>12
|
||
define(`square', `eval(`($1) ** 2')')
|
||
=>
|
||
square(`9')
|
||
=>81
|
||
square(square(`5')` + 1')
|
||
=>676
|
||
define(`foo', `666')
|
||
=>
|
||
eval(`foo / 6')
|
||
error-->m4:stdin:11: bad expression in eval: foo / 6
|
||
=>
|
||
eval(foo / 6)
|
||
=>111
|
||
|
||
As the last two lines show, `eval' does not handle macro names, even
|
||
if they expand to a valid expression (or part of a valid expression).
|
||
Therefore all macros must be expanded before they are passed to `eval'.
|
||
|
||
Some calculations are not portable to other implementations, since
|
||
they have undefined semantics in C, but GNU `m4' has well-defined
|
||
behavior on overflow. When shifting, an out-of-range shift amount is
|
||
implicitly brought into the range of 32-bit signed integers using an
|
||
implicit bit-wise and with 0x1f).
|
||
|
||
define(`max_int', eval(`0x7fffffff'))
|
||
=>
|
||
define(`min_int', incr(max_int))
|
||
=>
|
||
eval(min_int` < 0')
|
||
=>1
|
||
eval(max_int` > 0')
|
||
=>1
|
||
ifelse(eval(min_int` / -1'), min_int, `overflow occurred')
|
||
=>overflow occurred
|
||
min_int
|
||
=>-2147483648
|
||
eval(`0x80000000 % -1')
|
||
=>0
|
||
eval(`-4 >> 1')
|
||
=>-2
|
||
eval(`-4 >> 33')
|
||
=>-2
|
||
|
||
If RADIX is specified, it specifies the radix to be used in the
|
||
expansion. The default radix is 10; this is also the case if RADIX is
|
||
the empty string. A warning results if the radix is outside the range
|
||
of 1 through 36, inclusive. The result of `eval' is always taken to be
|
||
signed. No radix prefix is output, and for radices greater than 10,
|
||
the digits are lower case. The WIDTH argument specifies the minimum
|
||
output width, excluding any negative sign. The result is zero-padded
|
||
to extend the expansion to the requested width. A warning results if
|
||
the width is negative. If RADIX or WIDTH is out of bounds, the
|
||
expansion of `eval' is empty.
|
||
|
||
eval(`666', `10')
|
||
=>666
|
||
eval(`666', `11')
|
||
=>556
|
||
eval(`666', `6')
|
||
=>3030
|
||
eval(`666', `6', `10')
|
||
=>0000003030
|
||
eval(`-666', `6', `10')
|
||
=>-0000003030
|
||
eval(`10', `', `0')
|
||
=>10
|
||
`0r1:'eval(`10', `1', `11')
|
||
=>0r1:01111111111
|
||
eval(`10', `16')
|
||
=>a
|
||
eval(`1', `37')
|
||
error-->m4:stdin:9: radix 37 in builtin `eval' out of range
|
||
=>
|
||
eval(`1', , `-1')
|
||
error-->m4:stdin:10: negative width to builtin `eval'
|
||
=>
|
||
eval()
|
||
error-->m4:stdin:11: empty string treated as 0 in builtin `eval'
|
||
=>0
|
||
|
||
|
||
File: m4.info, Node: Shell commands, Next: Miscellaneous, Prev: Arithmetic, Up: Top
|
||
|
||
13 Macros for running shell commands
|
||
************************************
|
||
|
||
There are a few builtin macros in `m4' that allow you to run shell
|
||
commands from within `m4'.
|
||
|
||
Note that the definition of a valid shell command is system
|
||
dependent. On UNIX systems, this is the typical `/bin/sh'. But on
|
||
other systems, such as native Windows, the shell has a different syntax
|
||
of commands that it understands. Some examples in this chapter assume
|
||
`/bin/sh', and also demonstrate how to quit early with a known exit
|
||
value if this is not the case.
|
||
|
||
* Menu:
|
||
|
||
* Platform macros:: Determining the platform
|
||
* Syscmd:: Executing simple commands
|
||
* Esyscmd:: Reading the output of commands
|
||
* Sysval:: Exit status
|
||
* Mkstemp:: Making temporary files
|
||
|
||
|
||
File: m4.info, Node: Platform macros, Next: Syscmd, Up: Shell commands
|
||
|
||
13.1 Determining the platform
|
||
=============================
|
||
|
||
Sometimes it is desirable for an input file to know which platform `m4'
|
||
is running on. GNU `m4' provides several macros that are predefined to
|
||
expand to the empty string; checking for their existence will confirm
|
||
platform details.
|
||
|
||
-- Optional builtin: __gnu__
|
||
-- Optional builtin: __os2__
|
||
-- Optional builtin: os2
|
||
-- Optional builtin: __unix__
|
||
-- Optional builtin: unix
|
||
-- Optional builtin: __windows__
|
||
-- Optional builtin: windows
|
||
Each of these macros is conditionally defined as needed to
|
||
describe the environment of `m4'. If defined, each macro expands
|
||
to the empty string. For now, these macros silently ignore all
|
||
arguments, but in a future release of M4, they might warn if
|
||
arguments are present.
|
||
|
||
When GNU extensions are in effect (that is, when you did not use the
|
||
`-G' option, *note Invoking m4: Limits control.), GNU `m4' will define
|
||
the macro `__gnu__' to expand to the empty string.
|
||
|
||
$ m4
|
||
__gnu__
|
||
=>
|
||
__gnu__(`ignored')
|
||
=>
|
||
Extensions are ifdef(`__gnu__', `active', `inactive')
|
||
=>Extensions are active
|
||
|
||
$ m4 -G
|
||
__gnu__
|
||
=>__gnu__
|
||
__gnu__(`ignored')
|
||
=>__gnu__(ignored)
|
||
Extensions are ifdef(`__gnu__', `active', `inactive')
|
||
=>Extensions are inactive
|
||
|
||
On UNIX systems, GNU `m4' will define `__unix__' by default, or
|
||
`unix' when the `-G' option is specified.
|
||
|
||
On native Windows systems, GNU `m4' will define `__windows__' by
|
||
default, or `windows' when the `-G' option is specified.
|
||
|
||
On OS/2 systems, GNU `m4' will define `__os2__' by default, or `os2'
|
||
when the `-G' option is specified.
|
||
|
||
If GNU `m4' does not provide a platform macro for your system,
|
||
please report that as a bug.
|
||
|
||
define(`provided', `0')
|
||
=>
|
||
ifdef(`__unix__', `define(`provided', incr(provided))')
|
||
=>
|
||
ifdef(`__windows__', `define(`provided', incr(provided))')
|
||
=>
|
||
ifdef(`__os2__', `define(`provided', incr(provided))')
|
||
=>
|
||
provided
|
||
=>1
|
||
|
||
|
||
File: m4.info, Node: Syscmd, Next: Esyscmd, Prev: Platform macros, Up: Shell commands
|
||
|
||
13.2 Executing simple commands
|
||
==============================
|
||
|
||
Any shell command can be executed, using `syscmd':
|
||
|
||
-- Builtin: syscmd (SHELL-COMMAND)
|
||
Executes SHELL-COMMAND as a shell command.
|
||
|
||
The expansion of `syscmd' is void, _not_ the output from
|
||
SHELL-COMMAND! Output or error messages from SHELL-COMMAND are
|
||
not read by `m4'. *Note Esyscmd::, if you need to process the
|
||
command output.
|
||
|
||
Prior to executing the command, `m4' flushes its buffers. The
|
||
default standard input, output and error of SHELL-COMMAND are the
|
||
same as those of `m4'.
|
||
|
||
By default, the SHELL-COMMAND will be used as the argument to the
|
||
`-c' option of the `/bin/sh' shell (or the version of `sh'
|
||
specified by `command -p getconf PATH', if your system supports
|
||
that). If you prefer a different shell, the `configure' script
|
||
can be given the option `--with-syscmd-shell=LOCATION' to set the
|
||
location of an alternative shell at GNU `m4' installation; the
|
||
alternative shell must still support `-c'.
|
||
|
||
The macro `syscmd' is recognized only with parameters.
|
||
|
||
define(`foo', `FOO')
|
||
=>
|
||
syscmd(`echo foo')
|
||
=>foo
|
||
=>
|
||
|
||
Note how the expansion of `syscmd' keeps the trailing newline of the
|
||
command, as well as using the newline that appeared after the macro.
|
||
|
||
The following is an example of SHELL-COMMAND using the same standard
|
||
input as `m4':
|
||
|
||
$ echo "m4wrap(\`syscmd(\`cat')')" | m4
|
||
=>
|
||
|
||
It tells `m4' to read all of its input before executing the wrapped
|
||
text, then hand a valid (albeit emptied) pipe as standard input for the
|
||
`cat' subcommand. Therefore, you should be careful when using standard
|
||
input (either by specifying no files, or by passing `-' as a file name
|
||
on the command line, *note Invoking m4: Command line files.), and also
|
||
invoking subcommands via `syscmd' or `esyscmd' that consume data from
|
||
standard input. When standard input is a seekable file, the subprocess
|
||
will pick up with the next character not yet processed by `m4'; when it
|
||
is a pipe or other non-seekable file, there is no guarantee how much
|
||
data will already be buffered by `m4' and thus unavailable to the child.
|
||
|
||
|
||
File: m4.info, Node: Esyscmd, Next: Sysval, Prev: Syscmd, Up: Shell commands
|
||
|
||
13.3 Reading the output of commands
|
||
===================================
|
||
|
||
If you want `m4' to read the output of a shell command, use `esyscmd':
|
||
|
||
-- Builtin: esyscmd (SHELL-COMMAND)
|
||
Expands to the standard output of the shell command SHELL-COMMAND.
|
||
|
||
Prior to executing the command, `m4' flushes its buffers. The
|
||
default standard input and standard error of SHELL-COMMAND are the
|
||
same as those of `m4'. The error output of SHELL-COMMAND is not a
|
||
part of the expansion: it will appear along with the error output
|
||
of `m4'.
|
||
|
||
By default, the SHELL-COMMAND will be used as the argument to the
|
||
`-c' option of the `/bin/sh' shell (or the version of `sh'
|
||
specified by `command -p getconf PATH', if your system supports
|
||
that). If you prefer a different shell, the `configure' script
|
||
can be given the option `--with-syscmd-shell=LOCATION' to set the
|
||
location of an alternative shell at GNU `m4' installation; the
|
||
alternative shell must still support `-c'.
|
||
|
||
The macro `esyscmd' is recognized only with parameters.
|
||
|
||
define(`foo', `FOO')
|
||
=>
|
||
esyscmd(`echo foo')
|
||
=>FOO
|
||
=>
|
||
|
||
Note how the expansion of `esyscmd' keeps the trailing newline of
|
||
the command, as well as using the newline that appeared after the macro.
|
||
|
||
Just as with `syscmd', care must be exercised when sharing standard
|
||
input between `m4' and the child process of `esyscmd'.
|
||
|
||
|
||
File: m4.info, Node: Sysval, Next: Mkstemp, Prev: Esyscmd, Up: Shell commands
|
||
|
||
13.4 Exit status
|
||
================
|
||
|
||
To see whether a shell command succeeded, use `sysval':
|
||
|
||
-- Builtin: sysval
|
||
Expands to the exit status of the last shell command run with
|
||
`syscmd' or `esyscmd'. Expands to 0 if no command has been run
|
||
yet.
|
||
|
||
sysval
|
||
=>0
|
||
syscmd(`false')
|
||
=>
|
||
ifelse(sysval, `0', `zero', `non-zero')
|
||
=>non-zero
|
||
syscmd(`exit 2')
|
||
=>
|
||
sysval
|
||
=>2
|
||
syscmd(`true')
|
||
=>
|
||
sysval
|
||
=>0
|
||
esyscmd(`false')
|
||
=>
|
||
ifelse(sysval, `0', `zero', `non-zero')
|
||
=>non-zero
|
||
esyscmd(`exit 2')
|
||
=>
|
||
sysval
|
||
=>2
|
||
esyscmd(`true')
|
||
=>
|
||
sysval
|
||
=>0
|
||
|
||
`sysval' results in 127 if there was a problem executing the
|
||
command, for example, if the system-imposed argument length is exceeded,
|
||
or if there were not enough resources to fork. It is not possible to
|
||
distinguish between failed execution and successful execution that had
|
||
an exit status of 127.
|
||
|
||
On UNIX platforms, where it is possible to detect when command
|
||
execution is terminated by a signal, rather than a normal exit, the
|
||
result is the signal number shifted left by eight bits.
|
||
|
||
dnl This test assumes kill is a shell builtin, and that signals are
|
||
dnl recognizable.
|
||
ifdef(`__unix__', ,
|
||
`errprint(` skipping: syscmd does not have unix semantics
|
||
')m4exit(`77')')dnl
|
||
syscmd(`kill -9 $$')
|
||
=>
|
||
sysval
|
||
=>2304
|
||
syscmd()
|
||
=>
|
||
sysval
|
||
=>0
|
||
esyscmd(`kill -9 $$')
|
||
=>
|
||
sysval
|
||
=>2304
|
||
|
||
|
||
File: m4.info, Node: Mkstemp, Prev: Sysval, Up: Shell commands
|
||
|
||
13.5 Making temporary files
|
||
===========================
|
||
|
||
Commands specified to `syscmd' or `esyscmd' might need a temporary
|
||
file, for output or for some other purpose. There is a builtin macro,
|
||
`mkstemp', for making a temporary file:
|
||
|
||
-- Builtin: mkstemp (TEMPLATE)
|
||
-- Builtin: maketemp (TEMPLATE)
|
||
Expands to the quoted name of a new, empty file, made from the
|
||
string TEMPLATE, which should end with the string `XXXXXX'. The
|
||
six `X' characters are then replaced with random characters
|
||
matching the regular expression `[a-zA-Z0-9._-]', in order to make
|
||
the file name unique. If fewer than six `X' characters are found
|
||
at the end of `template', the result will be longer than the
|
||
template. The created file will have access permissions as if by
|
||
`chmod =rw,go=', meaning that the current umask of the `m4'
|
||
process is taken into account, and at most only the current user
|
||
can read and write the file.
|
||
|
||
The traditional behavior, standardized by POSIX, is that
|
||
`maketemp' merely replaces the trailing `X' with the process id,
|
||
without creating a file or quoting the expansion, and without
|
||
ensuring that the resulting string is a unique file name. In
|
||
part, this means that using the same TEMPLATE twice in the same
|
||
input file will result in the same expansion. This behavior is a
|
||
security hole, as it is very easy for another process to guess the
|
||
name that will be generated, and thus interfere with a subsequent
|
||
use of `syscmd' trying to manipulate that file name. Hence, POSIX
|
||
has recommended that all new implementations of `m4' provide the
|
||
secure `mkstemp' builtin, and that users of `m4' check for its
|
||
existence.
|
||
|
||
The expansion is void and an error issued if a temporary file could
|
||
not be created.
|
||
|
||
The macros `mkstemp' and `maketemp' are recognized only with
|
||
parameters.
|
||
|
||
If you try this next example, you will most likely get different
|
||
output for the two file names, since the replacement characters are
|
||
randomly chosen:
|
||
|
||
$ m4
|
||
define(`tmp', `oops')
|
||
=>
|
||
maketemp(`/tmp/fooXXXXXX')
|
||
=>/tmp/fooa07346
|
||
ifdef(`mkstemp', `define(`maketemp', defn(`mkstemp'))',
|
||
`define(`mkstemp', defn(`maketemp'))dnl
|
||
errprint(`warning: potentially insecure maketemp implementation
|
||
')')
|
||
=>
|
||
mkstemp(`doc')
|
||
=>docQv83Uw
|
||
|
||
Unless you use the `--traditional' command line option (or `-G',
|
||
*note Invoking m4: Limits control.), the GNU version of `maketemp' is
|
||
secure. This means that using the same template to multiple calls will
|
||
generate multiple files. However, we recommend that you use the new
|
||
`mkstemp' macro, introduced in GNU M4 1.4.8, which is secure even in
|
||
traditional mode. Also, as of M4 1.4.11, the secure implementation
|
||
quotes the resulting file name, so that you are guaranteed to know what
|
||
file was created even if the random file name happens to match an
|
||
existing macro. Notice that this example is careful to use `defn' to
|
||
avoid unintended expansion of `foo'.
|
||
|
||
$ m4
|
||
define(`foo', `errprint(`oops')')
|
||
=>
|
||
syscmd(`rm -f foo-??????')sysval
|
||
=>0
|
||
define(`file1', maketemp(`foo-XXXXXX'))dnl
|
||
ifelse(esyscmd(`echo \` foo-?????? \''), ` foo-?????? ',
|
||
`no file', `created')
|
||
=>created
|
||
define(`file2', maketemp(`foo-XX'))dnl
|
||
define(`file3', mkstemp(`foo-XXXXXX'))dnl
|
||
ifelse(len(defn(`file1')), len(defn(`file2')),
|
||
`same length', `different')
|
||
=>same length
|
||
ifelse(defn(`file1'), defn(`file2'), `same', `different file')
|
||
=>different file
|
||
ifelse(defn(`file2'), defn(`file3'), `same', `different file')
|
||
=>different file
|
||
ifelse(defn(`file1'), defn(`file3'), `same', `different file')
|
||
=>different file
|
||
syscmd(`rm 'defn(`file1') defn(`file2') defn(`file3'))
|
||
=>
|
||
sysval
|
||
=>0
|
||
|
||
|
||
File: m4.info, Node: Miscellaneous, Next: Frozen files, Prev: Shell commands, Up: Top
|
||
|
||
14 Miscellaneous builtin macros
|
||
*******************************
|
||
|
||
This chapter describes various builtins, that do not really belong in
|
||
any of the previous chapters.
|
||
|
||
* Menu:
|
||
|
||
* Errprint:: Printing error messages
|
||
* Location:: Printing current location
|
||
* M4exit:: Exiting from `m4'
|
||
|
||
|
||
File: m4.info, Node: Errprint, Next: Location, Up: Miscellaneous
|
||
|
||
14.1 Printing error messages
|
||
============================
|
||
|
||
You can print error messages using `errprint':
|
||
|
||
-- Builtin: errprint (MESSAGE, ...)
|
||
Prints MESSAGE and the rest of the arguments to standard error,
|
||
separated by spaces. Standard error is used, regardless of the
|
||
`--debugfile' option (*note Invoking m4: Debugging options.).
|
||
|
||
The expansion of `errprint' is void. The macro `errprint' is
|
||
recognized only with parameters.
|
||
|
||
errprint(`Invalid arguments to forloop
|
||
')
|
||
error-->Invalid arguments to forloop
|
||
=>
|
||
errprint(`1')errprint(`2',`3
|
||
')
|
||
error-->12 3
|
||
=>
|
||
|
||
A trailing newline is _not_ printed automatically, so it should be
|
||
supplied as part of the argument, as in the example. Unfortunately, the
|
||
exact output of `errprint' is not very portable to other `m4'
|
||
implementations: POSIX requires that all arguments be printed, but some
|
||
implementations of `m4' only print the first. Furthermore, some BSD
|
||
implementations always append a newline for each `errprint' call,
|
||
regardless of whether the last argument already had one, and POSIX is
|
||
silent on whether this is acceptable.
|
||
|
||
|
||
File: m4.info, Node: Location, Next: M4exit, Prev: Errprint, Up: Miscellaneous
|
||
|
||
14.2 Printing current location
|
||
==============================
|
||
|
||
To make it possible to specify the location of an error, three utility
|
||
builtins exist:
|
||
|
||
-- Builtin: __file__
|
||
-- Builtin: __line__
|
||
-- Builtin: __program__
|
||
Expand to the quoted name of the current input file, the current
|
||
input line number in that file, and the quoted name of the current
|
||
invocation of `m4'.
|
||
|
||
errprint(__program__:__file__:__line__: `input error
|
||
')
|
||
error-->m4:stdin:1: input error
|
||
=>
|
||
|
||
Line numbers start at 1 for each file. If the file was found due to
|
||
the `-I' option or `M4PATH' environment variable, that is reflected in
|
||
the file name. The syncline option (`-s', *note Invoking m4:
|
||
Preprocessor features.), and the `f' and `l' flags of `debugmode'
|
||
(*note Debug Levels::), also use this notion of current file and line.
|
||
Redefining the three location macros has no effect on syncline, debug,
|
||
warning, or error message output.
|
||
|
||
This example reuses the file `incl.m4' mentioned earlier (*note
|
||
Include::):
|
||
|
||
$ m4 -I examples
|
||
define(`foo', ``$0' called at __file__:__line__')
|
||
=>
|
||
foo
|
||
=>foo called at stdin:2
|
||
include(`incl.m4')
|
||
=>Include file start
|
||
=>foo called at examples/incl.m4:2
|
||
=>Include file end
|
||
=>
|
||
|
||
The location of macros invoked during the rescanning of macro
|
||
expansion text corresponds to the location in the file where the
|
||
expansion was triggered, regardless of how many newline characters the
|
||
expansion text contains. As of GNU M4 1.4.8, the location of text
|
||
wrapped with `m4wrap' (*note M4wrap::) is the point at which the
|
||
`m4wrap' was invoked. Previous versions, however, behaved as though
|
||
wrapped text came from line 0 of the file "".
|
||
|
||
define(`echo', `$@')
|
||
=>
|
||
define(`foo', `echo(__line__
|
||
__line__)')
|
||
=>
|
||
echo(__line__
|
||
__line__)
|
||
=>4
|
||
=>5
|
||
m4wrap(`foo
|
||
')
|
||
=>
|
||
foo(errprint(__line__
|
||
__line__
|
||
))
|
||
error-->8
|
||
error-->9
|
||
=>8
|
||
=>8
|
||
__line__
|
||
=>11
|
||
m4wrap(`__line__
|
||
')
|
||
=>
|
||
^D
|
||
=>12
|
||
=>6
|
||
=>6
|
||
|
||
The `__program__' macro behaves like `$0' in shell terminology. If
|
||
you invoke `m4' through an absolute path or a link with a different
|
||
spelling, rather than by relying on a `PATH' search for plain `m4', it
|
||
will affect how `__program__' expands. The intent is that you can use
|
||
it to produce error messages with the same formatting that `m4'
|
||
produces internally. It can also be used within `syscmd' (*note
|
||
Syscmd::) to pick the same version of `m4' that is currently running,
|
||
rather than whatever version of `m4' happens to be first in `PATH'. It
|
||
was first introduced in GNU M4 1.4.6.
|
||
|
||
|
||
File: m4.info, Node: M4exit, Prev: Location, Up: Miscellaneous
|
||
|
||
14.3 Exiting from `m4'
|
||
======================
|
||
|
||
If you need to exit from `m4' before the entire input has been read,
|
||
you can use `m4exit':
|
||
|
||
-- Builtin: m4exit ([CODE = `0'])
|
||
Causes `m4' to exit, with exit status CODE. If CODE is left out,
|
||
the exit status is zero. If CODE cannot be parsed, or is outside
|
||
the range of 0 to 255, the exit status is one. No further input
|
||
is read, and all wrapped and diverted text is discarded.
|
||
|
||
m4wrap(`This text is lost due to `m4exit'.')
|
||
=>
|
||
divert(`1') So is this.
|
||
divert
|
||
=>
|
||
m4exit And this is never read.
|
||
|
||
A common use of this is to abort processing:
|
||
|
||
-- Composite: fatal_error (MESSAGE)
|
||
Abort processing with an error message and non-zero status. Prefix
|
||
MESSAGE with details about where the error occurred, and print the
|
||
resulting string to standard error.
|
||
|
||
define(`fatal_error',
|
||
`errprint(__program__:__file__:__line__`: fatal error: $*
|
||
')m4exit(`1')')
|
||
=>
|
||
fatal_error(`this is a BAD one, buster')
|
||
error-->m4:stdin:4: fatal error: this is a BAD one, buster
|
||
|
||
After this macro call, `m4' will exit with exit status 1. This macro
|
||
is only intended for error exits, since the normal exit procedures are
|
||
not followed, i.e., diverted text is not undiverted, and saved text
|
||
(*note M4wrap::) is not reread. (This macro could be made more robust
|
||
to earlier versions of `m4'. You should try to see if you can find
|
||
weaknesses and correct them; or *note Answers: Improved fatal_error.).
|
||
|
||
Note that it is still possible for the exit status to be different
|
||
than what was requested by `m4exit'. If `m4' detects some other error,
|
||
such as a write error on standard output, the exit status will be
|
||
non-zero even if `m4exit' requested zero.
|
||
|
||
If standard input is seekable, then the file will be positioned at
|
||
the next unread character. If it is a pipe or other non-seekable file,
|
||
then there are no guarantees how much data `m4' might have read into
|
||
buffers, and thus discarded.
|
||
|
||
|
||
File: m4.info, Node: Frozen files, Next: Compatibility, Prev: Miscellaneous, Up: Top
|
||
|
||
15 Fast loading of frozen state
|
||
*******************************
|
||
|
||
Some bigger `m4' applications may be built over a common base
|
||
containing hundreds of definitions and other costly initializations.
|
||
Usually, the common base is kept in one or more declarative files,
|
||
which files are listed on each `m4' invocation prior to the user's
|
||
input file, or else each input file uses `include'.
|
||
|
||
Reading the common base of a big application, over and over again,
|
||
may be time consuming. GNU `m4' offers some machinery to speed up the
|
||
start of an application using lengthy common bases.
|
||
|
||
* Menu:
|
||
|
||
* Using frozen files:: Using frozen files
|
||
* Frozen file format:: Frozen file format
|
||
|
||
|
||
File: m4.info, Node: Using frozen files, Next: Frozen file format, Up: Frozen files
|
||
|
||
15.1 Using frozen files
|
||
=======================
|
||
|
||
Suppose a user has a library of `m4' initializations in `base.m4',
|
||
which is then used with multiple input files:
|
||
|
||
$ m4 base.m4 input1.m4
|
||
$ m4 base.m4 input2.m4
|
||
$ m4 base.m4 input3.m4
|
||
|
||
Rather than spending time parsing the fixed contents of `base.m4'
|
||
every time, the user might rather execute:
|
||
|
||
$ m4 -F base.m4f base.m4
|
||
|
||
once, and further execute, as often as needed:
|
||
|
||
$ m4 -R base.m4f input1.m4
|
||
$ m4 -R base.m4f input2.m4
|
||
$ m4 -R base.m4f input3.m4
|
||
|
||
with the varying input. The first call, containing the `-F' option,
|
||
only reads and executes file `base.m4', defining various application
|
||
macros and computing other initializations. Once the input file
|
||
`base.m4' has been completely processed, GNU `m4' produces in
|
||
`base.m4f' a "frozen" file, that is, a file which contains a kind of
|
||
snapshot of the `m4' internal state.
|
||
|
||
Later calls, containing the `-R' option, are able to reload the
|
||
internal state of `m4', from `base.m4f', _prior_ to reading any other
|
||
input files. This means instead of starting with a virgin copy of
|
||
`m4', input will be read after having effectively recovered the effect
|
||
of a prior run. In our example, the effect is the same as if file
|
||
`base.m4' has been read anew. However, this effect is achieved a lot
|
||
faster.
|
||
|
||
Only one frozen file may be created or read in any one `m4'
|
||
invocation. It is not possible to recover two frozen files at once.
|
||
However, frozen files may be updated incrementally, through using `-R'
|
||
and `-F' options simultaneously. For example, if some care is taken,
|
||
the command:
|
||
|
||
$ m4 file1.m4 file2.m4 file3.m4 file4.m4
|
||
|
||
could be broken down in the following sequence, accumulating the same
|
||
output:
|
||
|
||
$ m4 -F file1.m4f file1.m4
|
||
$ m4 -R file1.m4f -F file2.m4f file2.m4
|
||
$ m4 -R file2.m4f -F file3.m4f file3.m4
|
||
$ m4 -R file3.m4f file4.m4
|
||
|
||
Some care is necessary because not every effort has been made for
|
||
this to work in all cases. In particular, the trace attribute of
|
||
macros is not handled, nor the current setting of `changeword'.
|
||
Currently, `m4wrap' and `sysval' also have problems. Also,
|
||
interactions for some options of `m4', being used in one call and not
|
||
in the next, have not been fully analyzed yet. On the other end, you
|
||
may be confident that stacks of `pushdef' definitions are handled
|
||
correctly, as well as undefined or renamed builtins, and changed
|
||
strings for quotes or comments. And future releases of GNU M4 will
|
||
improve on the utility of frozen files.
|
||
|
||
When an `m4' run is to be frozen, the automatic undiversion which
|
||
takes place at end of execution is inhibited. Instead, all positively
|
||
numbered diversions are saved into the frozen file. The active
|
||
diversion number is also transmitted.
|
||
|
||
A frozen file to be reloaded need not reside in the current
|
||
directory. It is looked up the same way as an `include' file (*note
|
||
Search Path::).
|
||
|
||
If the frozen file was generated with a newer version of `m4', and
|
||
contains directives that an older `m4' cannot parse, attempting to load
|
||
the frozen file with option `-R' will cause `m4' to exit with status 63
|
||
to indicate version mismatch.
|
||
|
||
|
||
File: m4.info, Node: Frozen file format, Prev: Using frozen files, Up: Frozen files
|
||
|
||
15.2 Frozen file format
|
||
=======================
|
||
|
||
Frozen files are sharable across architectures. It is safe to write a
|
||
frozen file on one machine and read it on another, given that the
|
||
second machine uses the same or newer version of GNU `m4'. It is
|
||
conventional, but not required, to give a frozen file the suffix of
|
||
`.m4f'.
|
||
|
||
These are simple (editable) text files, made up of directives, each
|
||
starting with a capital letter and ending with a newline (<NL>).
|
||
Wherever a directive is expected, the character `#' introduces a
|
||
comment line; empty lines are also ignored if they are not part of an
|
||
embedded string. In the following descriptions, each LEN refers to the
|
||
length of the corresponding strings STR in the next line of input.
|
||
Numbers are always expressed in decimal. There are no escape
|
||
characters. The directives are:
|
||
|
||
`C LEN1 , LEN2 <NL> STR1 STR2 <NL>'
|
||
Uses STR1 and STR2 as the begin-comment and end-comment strings.
|
||
If omitted, then `#' and <NL> are the comment delimiters.
|
||
|
||
`D NUMBER, LEN <NL> STR <NL>'
|
||
Selects diversion NUMBER, making it current, then copy STR in the
|
||
current diversion. NUMBER may be a negative number for a
|
||
non-existing diversion. To merely specify an active selection,
|
||
use this command with an empty STR. With 0 as the diversion
|
||
NUMBER, STR will be issued on standard output at reload time. GNU
|
||
`m4' will not produce the `D' directive with non-zero length for
|
||
diversion 0, but this can be done with manual edits. This
|
||
directive may appear more than once for the same diversion, in
|
||
which case the diversion is the concatenation of the various uses.
|
||
If omitted, then diversion 0 is current.
|
||
|
||
`F LEN1 , LEN2 <NL> STR1 STR2 <NL>'
|
||
Defines, through `pushdef', a definition for STR1 expanding to the
|
||
function whose builtin name is STR2. If the builtin does not
|
||
exist (for example, if the frozen file was produced by a copy of
|
||
`m4' compiled with changeword support, but the version of `m4'
|
||
reloading was compiled without it), the reload is silent, but any
|
||
subsequent use of the definition of STR1 will result in a warning.
|
||
This directive may appear more than once for the same name, and
|
||
its order, along with `T', is important. If omitted, you will
|
||
have no access to any builtins.
|
||
|
||
`Q LEN1 , LEN2 <NL> STR1 STR2 <NL>'
|
||
Uses STR1 and STR2 as the begin-quote and end-quote strings. If
|
||
omitted, then ``' and `'' are the quote delimiters.
|
||
|
||
`T LEN1 , LEN2 <NL> STR1 STR2 <NL>'
|
||
Defines, though `pushdef', a definition for STR1 expanding to the
|
||
text given by STR2. This directive may appear more than once for
|
||
the same name, and its order, along with `F', is important.
|
||
|
||
`V NUMBER <NL>'
|
||
Confirms the format of the file. `m4' 1.4.13 only creates and
|
||
understands frozen files where NUMBER is 1. This directive must
|
||
be the first non-comment in the file, and may not appear more than
|
||
once.
|
||
|
||
|
||
File: m4.info, Node: Compatibility, Next: Answers, Prev: Frozen files, Up: Top
|
||
|
||
16 Compatibility with other versions of `m4'
|
||
********************************************
|
||
|
||
This chapter describes the many of the differences between this
|
||
implementation of `m4', and of other implementations found under UNIX,
|
||
such as System V Release 3, Solaris, and BSD flavors. In particular,
|
||
it lists the known differences and extensions to POSIX. However, the
|
||
list is not necessarily comprehensive.
|
||
|
||
At the time of this writing, POSIX 2001 (also known as IEEE Std
|
||
1003.1-2001) is the latest standard, although a new version of POSIX is
|
||
under development and includes several proposals for modifying what
|
||
`m4' is required to do. The requirements for `m4' are shared between
|
||
SUSv3 and POSIX, and can be viewed at
|
||
`http://www.opengroup.org/onlinepubs/000095399/utilities/m4.html'.
|
||
|
||
* Menu:
|
||
|
||
* Extensions:: Extensions in GNU M4
|
||
* Incompatibilities:: Facilities in System V m4 not in GNU M4
|
||
* Other Incompatibilities:: Other incompatibilities
|
||
|
||
|
||
File: m4.info, Node: Extensions, Next: Incompatibilities, Up: Compatibility
|
||
|
||
16.1 Extensions in GNU M4
|
||
=========================
|
||
|
||
This version of `m4' contains a few facilities that do not exist in
|
||
System V `m4'. These extra facilities are all suppressed by using the
|
||
`-G' command line option (*note Invoking m4: Limits control.), unless
|
||
overridden by other command line options.
|
||
|
||
* In the `$N' notation for macro arguments, N can contain several
|
||
digits, while the System V `m4' only accepts one digit. This
|
||
allows macros in GNU `m4' to take any number of arguments, and not
|
||
only nine (*note Arguments::).
|
||
|
||
This means that `define(`foo', `$11')' is ambiguous between
|
||
implementations. To portably choose between grabbing the first
|
||
parameter and appending 1 to the expansion, or grabbing the
|
||
eleventh parameter, you can do the following:
|
||
|
||
define(`a1', `A1')
|
||
=>
|
||
dnl First argument, concatenated with 1
|
||
define(`_1', `$1')define(`first1', `_1($@)1')
|
||
=>
|
||
dnl Eleventh argument, portable
|
||
define(`_9', `$9')define(`eleventh', `_9(shift(shift($@)))')
|
||
=>
|
||
dnl Eleventh argument, GNU style
|
||
define(`Eleventh', `$11')
|
||
=>
|
||
first1(`a', `b', `c', `d', `e', `f', `g', `h', `i', `j', `k')
|
||
=>A1
|
||
eleventh(`a', `b', `c', `d', `e', `f', `g', `h', `i', `j', `k')
|
||
=>k
|
||
Eleventh(`a', `b', `c', `d', `e', `f', `g', `h', `i', `j', `k')
|
||
=>k
|
||
|
||
Also see the `argn' macro (*note Shift::).
|
||
|
||
* The `divert' (*note Divert::) macro can manage more than 9
|
||
diversions. GNU `m4' treats all positive numbers as valid
|
||
diversions, rather than discarding diversions greater than 9.
|
||
|
||
* Files included with `include' and `sinclude' are sought in a user
|
||
specified search path, if they are not found in the working
|
||
directory. The search path is specified by the `-I' option and the
|
||
`M4PATH' environment variable (*note Search Path::).
|
||
|
||
* Arguments to `undivert' can be non-numeric, in which case the named
|
||
file will be included uninterpreted in the output (*note
|
||
Undivert::).
|
||
|
||
* Formatted output is supported through the `format' builtin, which
|
||
is modeled after the C library function `printf' (*note Format::).
|
||
|
||
* Searches and text substitution through basic regular expressions
|
||
are supported by the `regexp' (*note Regexp::) and `patsubst'
|
||
(*note Patsubst::) builtins. Some BSD implementations use
|
||
extended regular expressions instead.
|
||
|
||
* The output of shell commands can be read into `m4' with `esyscmd'
|
||
(*note Esyscmd::).
|
||
|
||
* There is indirect access to any builtin macro with `builtin'
|
||
(*note Builtin::).
|
||
|
||
* Macros can be called indirectly through `indir' (*note Indir::).
|
||
|
||
* The name of the program, the current input file, and the current
|
||
input line number are accessible through the builtins
|
||
`__program__', `__file__', and `__line__' (*note Location::).
|
||
|
||
* The format of the output from `dumpdef' and macro tracing can be
|
||
controlled with `debugmode' (*note Debug Levels::).
|
||
|
||
* The destination of trace and debug output can be controlled with
|
||
`debugfile' (*note Debug Output::).
|
||
|
||
* The `maketemp' (*note Mkstemp::) macro behaves like `mkstemp',
|
||
creating a new file with a unique name on every invocation, rather
|
||
than following the insecure behavior of replacing the trailing `X'
|
||
characters with the `m4' process id.
|
||
|
||
* POSIX only requires support for the command line options `-s',
|
||
`-D', and `-U', so all other options accepted by GNU M4 are
|
||
extensions. *Note Invoking m4::, for a description of these
|
||
options.
|
||
|
||
The debugging and tracing facilities in GNU `m4' are much more
|
||
extensive than in most other versions of `m4'.
|
||
|
||
|
||
File: m4.info, Node: Incompatibilities, Next: Other Incompatibilities, Prev: Extensions, Up: Compatibility
|
||
|
||
16.2 Facilities in System V `m4' not in GNU `m4'
|
||
================================================
|
||
|
||
The version of `m4' from System V contains a few facilities that have
|
||
not been implemented in GNU `m4' yet. Additionally, POSIX requires
|
||
some behaviors that GNU `m4' has not implemented yet. Relying on these
|
||
behaviors is non-portable, as a future release of GNU `m4' may change.
|
||
|
||
* POSIX requires support for multiple arguments to `defn', without
|
||
any clarification on how `defn' behaves when one of the multiple
|
||
arguments names a builtin. System V `m4' and some other
|
||
implementations allow mixing builtins and text macros into a single
|
||
macro. GNU `m4' only supports joining multiple text arguments,
|
||
although a future implementation may lift this restriction to
|
||
behave more like System V. The only portable way to join text
|
||
macros with builtins is via helper macros and implicit
|
||
concatenation of macro results.
|
||
|
||
* POSIX requires an application to exit with non-zero status if it
|
||
wrote an error message to stderr. This has not yet been
|
||
consistently implemented for the various builtins that are
|
||
required to issue an error (such as `eval' (*note Eval::) when an
|
||
argument cannot be parsed).
|
||
|
||
* Some traditional implementations only allow reading standard input
|
||
once, but GNU `m4' correctly handles multiple instances of `-' on
|
||
the command line.
|
||
|
||
* POSIX requires `m4wrap' (*note M4wrap::) to act in FIFO (first-in,
|
||
first-out) order, but GNU `m4' currently uses LIFO order.
|
||
Furthermore, POSIX states that only the first argument to `m4wrap'
|
||
is saved for later evaluation, but GNU `m4' saves and processes
|
||
all arguments, with output separated by spaces.
|
||
|
||
* POSIX states that builtins that require arguments, but are called
|
||
without arguments, have undefined behavior. Traditional
|
||
implementations simply behave as though empty strings had been
|
||
passed. For example, `a`'define`'b' would expand to `ab'. But
|
||
GNU `m4' ignores certain builtins if they have missing arguments,
|
||
giving `adefineb' for the above example.
|
||
|
||
* Traditional implementations handle `define(`f',`1')' (*note
|
||
Define::) by undefining the entire stack of previous definitions,
|
||
and if doing `undefine(`f')' first. GNU `m4' replaces just the top
|
||
definition on the stack, as if doing `popdef(`f')' followed by
|
||
`pushdef(`f',`1')'. POSIX allows either behavior.
|
||
|
||
* POSIX 2001 requires `syscmd' (*note Syscmd::) to evaluate command
|
||
output for macro expansion, but this was a mistake that is
|
||
anticipated to be corrected in the next version of POSIX. GNU
|
||
`m4' follows traditional behavior in `syscmd' where output is not
|
||
rescanned, and provides the extension `esyscmd' that does scan the
|
||
output.
|
||
|
||
* At one point, POSIX required `changequote(ARG)' (*note
|
||
Changequote::) to use newline as the close quote, but this was a
|
||
bug, and the next version of POSIX is anticipated to state that
|
||
using empty strings or just one argument is unspecified.
|
||
Meanwhile, the GNU `m4' behavior of treating an empty end-quote
|
||
delimiter as `'' is not portable, as Solaris treats it as
|
||
repeating the start-quote delimiter, and BSD treats it as leaving
|
||
the previous end-quote delimiter unchanged. For predictable
|
||
results, never call changequote with just one argument, or with
|
||
empty strings for arguments.
|
||
|
||
* At one point, POSIX required `changecom(ARG,)' (*note Changecom::)
|
||
to make it impossible to end a comment, but this is a bug, and the
|
||
next version of POSIX is anticipated to state that using empty
|
||
strings is unspecified. Meanwhile, the GNU `m4' behavior of
|
||
treating an empty end-comment delimiter as newline is not
|
||
portable, as BSD treats it as leaving the previous end-comment
|
||
delimiter unchanged. It is also impossible in BSD implementations
|
||
to disable comments, even though that is required by POSIX. For
|
||
predictable results, never call changecom with empty strings for
|
||
arguments.
|
||
|
||
* Most implementations of `m4' give macros a higher precedence than
|
||
comments when parsing, meaning that if the start delimiter given to
|
||
`changecom' (*note Changecom::) starts with a macro name, comments
|
||
are effectively disabled. POSIX does not specify what the
|
||
precedence is, so this version of GNU `m4' parser recognizes
|
||
comments, then macros, then quoted strings.
|
||
|
||
* Traditional implementations allow argument collection, but not
|
||
string and comment processing, to span file boundaries. Thus, if
|
||
`a.m4' contains `len(', and `b.m4' contains `abc)', `m4 a.m4 b.m4'
|
||
outputs `3' with traditional `m4', but gives an error message that
|
||
the end of file was encountered inside a macro with GNU `m4'. On
|
||
the other hand, traditional implementations do end of file
|
||
processing for files included with `include' or `sinclude' (*note
|
||
Include::), while GNU `m4' seamlessly integrates the content of
|
||
those files. Thus `include(`a.m4')include(`b.m4')' will output
|
||
`3' instead of giving an error.
|
||
|
||
* Traditional `m4' treats `traceon' (*note Trace::) without
|
||
arguments as a global variable, independent of named macro tracing.
|
||
Also, once a macro is undefined, named tracing of that macro is
|
||
lost. On the other hand, when GNU `m4' encounters `traceon'
|
||
without arguments, it turns tracing on for all existing
|
||
definitions at the time, but does not trace future definitions;
|
||
`traceoff' without arguments turns tracing off for all definitions
|
||
regardless of whether they were also traced by name; and tracing
|
||
by name, such as with `-tfoo' at the command line or
|
||
`traceon(`foo')' in the input, is an attribute that is preserved
|
||
even if the macro is currently undefined.
|
||
|
||
Additionally, while POSIX requires trace output, it makes no
|
||
demands on the formatting of that output. Parsing trace output is
|
||
not guaranteed to be reliable, even between different releases of
|
||
GNU M4; however, the intent is that any future changes in trace
|
||
output will only occur under the direction of additional
|
||
`debugmode' flags (*note Debug Levels::).
|
||
|
||
* POSIX requires `eval' (*note Eval::) to treat all operators with
|
||
the same precedence as C. However, earlier versions of GNU `m4'
|
||
followed the traditional behavior of other `m4' implementations,
|
||
where bitwise and logical negation (`~' and `!') have lower
|
||
precedence than equality operators; and where equality operators
|
||
(`==' and `!=') had the same precedence as relational operators
|
||
(such as `<'). Use explicit parentheses to ensure proper
|
||
precedence. As extensions to POSIX, GNU `m4' gives well-defined
|
||
semantics to operations that C leaves undefined, such as when
|
||
overflow occurs, when shifting negative numbers, or when
|
||
performing division by zero. POSIX also requires `=' to cause an
|
||
error, but many traditional implementations allowed it as an alias
|
||
for `=='.
|
||
|
||
* POSIX 2001 requires `translit' (*note Translit::) to treat each
|
||
character of the second and third arguments literally. However,
|
||
it is anticipated that the next version of POSIX will allow the
|
||
GNU `m4' behavior of treating `-' as a range operator.
|
||
|
||
* POSIX requires `m4' to honor the locale environment variables of
|
||
`LANG', `LC_ALL', `LC_CTYPE', `LC_MESSAGES', and `NLSPATH', but
|
||
this has not yet been implemented in GNU `m4'.
|
||
|
||
* POSIX states that only unquoted leading newlines and blanks (that
|
||
is, space and tab) are ignored when collecting macro arguments.
|
||
However, this appears to be a bug in POSIX, since most traditional
|
||
implementations also ignore all whitespace (formfeed, carriage
|
||
return, and vertical tab). GNU `m4' follows tradition and ignores
|
||
all leading unquoted whitespace.
|
||
|
||
* A strictly-compliant POSIX client is not allowed to use
|
||
command-line arguments not specified by POSIX. However, since
|
||
this version of M4 ignores `POSIXLY_CORRECT' and enables the option
|
||
`--gnu' by default (*note Invoking m4: Limits control.), a client
|
||
desiring to be strictly compliant has no way to disable GNU
|
||
extensions that conflict with POSIX when directly invoking the
|
||
compiled `m4'. A future version of `GNU' M4 will honor the
|
||
environment variable `POSIXLY_CORRECT', implicitly enabling
|
||
`--traditional' if it is set, in order to allow a
|
||
strictly-compliant client. In the meantime, a client needing
|
||
strict POSIX compliance can use the workaround of invoking a shell
|
||
script wrapper, where the wrapper then adds `--traditional' to the
|
||
arguments passed to the compiled `m4'.
|
||
|
||
|
||
File: m4.info, Node: Other Incompatibilities, Prev: Incompatibilities, Up: Compatibility
|
||
|
||
16.3 Other incompatibilities
|
||
============================
|
||
|
||
There are a few other incompatibilities between this implementation of
|
||
`m4', and the System V version.
|
||
|
||
* GNU `m4' implements sync lines differently from System V `m4',
|
||
when text is being diverted. GNU `m4' outputs the sync lines when
|
||
the text is being diverted, and System V `m4' when the diverted
|
||
text is being brought back.
|
||
|
||
The problem is which lines and file names should be attached to
|
||
text that is being, or has been, diverted. System V `m4' regards
|
||
all the diverted text as being generated by the source line
|
||
containing the `undivert' call, whereas GNU `m4' regards the
|
||
diverted text as being generated at the time it is diverted.
|
||
|
||
The sync line option is used mostly when using `m4' as a front end
|
||
to a compiler. If a diverted line causes a compiler error, the
|
||
error messages should most probably refer to the place where the
|
||
diversion was made, and not where it was inserted again.
|
||
|
||
divert(2)2
|
||
divert(1)1
|
||
divert`'0
|
||
=>#line 3 "stdin"
|
||
=>0
|
||
^D
|
||
=>#line 2 "stdin"
|
||
=>1
|
||
=>#line 1 "stdin"
|
||
=>2
|
||
|
||
The current `m4' implementation has a limitation that the syncline
|
||
output at the start of each diversion occurs no matter what, even
|
||
if the previous diversion did not end with a newline. This goes
|
||
contrary to the claim that synclines appear on a line by
|
||
themselves, so this limitation may be corrected in a future
|
||
version of `m4'. In the meantime, when using `-s', it is wisest
|
||
to make sure all diversions end with newline.
|
||
|
||
* GNU `m4' makes no attempt at prohibiting self-referential
|
||
definitions like:
|
||
|
||
define(`x', `x')
|
||
=>
|
||
define(`x', `x ')
|
||
=>
|
||
|
||
There is nothing inherently wrong with defining `x' to return `x'.
|
||
The wrong thing is to expand `x' unquoted, because that would
|
||
cause an infinite rescan loop. In `m4', one might use macros to
|
||
hold strings, as we do for variables in other programming
|
||
languages, further checking them with:
|
||
|
||
ifelse(defn(`HOLDER'), `VALUE', ...)
|
||
|
||
In cases like this one, an interdiction for a macro to hold its
|
||
own name would be a useless limitation. Of course, this leaves
|
||
more rope for the GNU `m4' user to hang himself! Rescanning hangs
|
||
may be avoided through careful programming, a little like for
|
||
endless loops in traditional programming languages.
|
||
|
||
|
||
File: m4.info, Node: Answers, Next: Copying This Package, Prev: Compatibility, Up: Top
|
||
|
||
17 Correct version of some examples
|
||
***********************************
|
||
|
||
Some of the examples in this manuals are buggy or not very robust, for
|
||
demonstration purposes. Improved versions of these composite macros are
|
||
presented here.
|
||
|
||
* Menu:
|
||
|
||
* Improved exch:: Solution for `exch'
|
||
* Improved forloop:: Solution for `forloop'
|
||
* Improved foreach:: Solution for `foreach'
|
||
* Improved copy:: Solution for `copy'
|
||
* Improved m4wrap:: Solution for `m4wrap'
|
||
* Improved cleardivert:: Solution for `cleardivert'
|
||
* Improved capitalize:: Solution for `capitalize'
|
||
* Improved fatal_error:: Solution for `fatal_error'
|
||
|
||
|
||
File: m4.info, Node: Improved exch, Next: Improved forloop, Up: Answers
|
||
|
||
17.1 Solution for `exch'
|
||
========================
|
||
|
||
The `exch' macro (*note Arguments::) as presented requires clients to
|
||
double quote their arguments. A nicer definition, which lets clients
|
||
follow the rule of thumb of one level of quoting per level of
|
||
parentheses, involves adding quotes in the definition of `exch', as
|
||
follows:
|
||
|
||
define(`exch', ``$2', `$1'')
|
||
=>
|
||
define(exch(`expansion text', `macro'))
|
||
=>
|
||
macro
|
||
=>expansion text
|
||
|
||
|
||
File: m4.info, Node: Improved forloop, Next: Improved foreach, Prev: Improved exch, Up: Answers
|
||
|
||
17.2 Solution for `forloop'
|
||
===========================
|
||
|
||
The `forloop' macro (*note Forloop::) as presented earlier can go into
|
||
an infinite loop if given an iterator that is not parsed as a macro
|
||
name. It does not do any sanity checking on its numeric bounds, and
|
||
only permits decimal numbers for bounds. Here is an improved version,
|
||
shipped as `m4-1.4.13/examples/forloop2.m4'; this version also
|
||
optimizes overhead by calling four macros instead of six per iteration
|
||
(excluding those in TEXT), by not dereferencing the ITERATOR in the
|
||
helper `_forloop'.
|
||
|
||
$ m4 -d -I examples
|
||
undivert(`forloop2.m4')dnl
|
||
=>divert(`-1')
|
||
=># forloop(var, from, to, stmt) - improved version:
|
||
=># works even if VAR is not a strict macro name
|
||
=># performs sanity check that FROM is larger than TO
|
||
=># allows complex numerical expressions in TO and FROM
|
||
=>define(`forloop', `ifelse(eval(`($2) <= ($3)'), `1',
|
||
=> `pushdef(`$1')_$0(`$1', eval(`$2'),
|
||
=> eval(`$3'), `$4')popdef(`$1')')')
|
||
=>define(`_forloop',
|
||
=> `define(`$1', `$2')$4`'ifelse(`$2', `$3', `',
|
||
=> `$0(`$1', incr(`$2'), `$3', `$4')')')
|
||
=>divert`'dnl
|
||
include(`forloop2.m4')
|
||
=>
|
||
forloop(`i', `2', `1', `no iteration occurs')
|
||
=>
|
||
forloop(`', `1', `2', ` odd iterator name')
|
||
=> odd iterator name odd iterator name
|
||
forloop(`i', `5 + 5', `0xc', ` 0x`'eval(i, `16')')
|
||
=> 0xa 0xb 0xc
|
||
forloop(`i', `a', `b', `non-numeric bounds')
|
||
error-->m4:stdin:6: bad expression in eval (bad input): (a) <= (b)
|
||
=>
|
||
|
||
One other change to notice is that the improved version used `_$0'
|
||
rather than `_foreach' to invoke the helper routine. In general, this
|
||
is a good practice to follow, because then the set of macros can be
|
||
uniformly transformed. The following example shows a transformation
|
||
that doubles the current quoting and appends a suffix `2' to each
|
||
transformed macro. If `foreach' refers to the literal `_foreach', then
|
||
`foreach2' invokes `_foreach' instead of the intended `_foreach2', and
|
||
the mixing of quoting paradigms leads to an infinite recursion loop in
|
||
this example.
|
||
|
||
$ m4 -d -L 9 -I examples
|
||
define(`arg1', `$1')include(`forloop2.m4')include(`quote.m4')
|
||
=>
|
||
define(`double', `define(`$1'`2',
|
||
arg1(patsubst(dquote(defn(`$1')), `[`']', `\&\&')))')
|
||
=>
|
||
double(`forloop')double(`_forloop')defn(`forloop2')
|
||
=>ifelse(eval(``($2) <= ($3)''), ``1'',
|
||
=> ``pushdef(``$1'')_$0(``$1'', eval(``$2''),
|
||
=> eval(``$3''), ``$4'')popdef(``$1'')'')
|
||
forloop(i, 1, 5, `ifelse(')forloop(i, 1, 5, `)')
|
||
=>
|
||
changequote(`[', `]')changequote([``], [''])
|
||
=>
|
||
forloop2(i, 1, 5, ``ifelse('')forloop2(i, 1, 5, ``)'')
|
||
=>
|
||
changequote`'include(`forloop.m4')
|
||
=>
|
||
double(`forloop')double(`_forloop')defn(`forloop2')
|
||
=>pushdef(``$1'', ``$2'')_forloop($@)popdef(``$1'')
|
||
forloop(i, 1, 5, `ifelse(')forloop(i, 1, 5, `)')
|
||
=>
|
||
changequote(`[', `]')changequote([``], [''])
|
||
=>
|
||
forloop2(i, 1, 5, ``ifelse('')forloop2(i, 1, 5, ``)'')
|
||
error-->m4:stdin:12: recursion limit of 9 exceeded, use -L<N> to change it
|
||
|
||
One more optimization is still possible. Instead of repeatedly
|
||
assigning a variable then invoking or dereferencing it, it is possible
|
||
to pass the current iterator value as a single argument. Coupled with
|
||
`curry' if other arguments are needed (*note Composition::), or with
|
||
helper macros if the argument is needed in more than one place in the
|
||
expansion, the output can be generated with three, rather than four,
|
||
macros of overhead per iteration. Notice how the file
|
||
`m4-1.4.13/examples/forloop3.m4' rearranges the arguments of the helper
|
||
`_forloop' to take two arguments that are placed around the current
|
||
value. By splitting a balanced set of parantheses across multiple
|
||
arguments, the helper macro can now be shared by `forloop' and the new
|
||
`forloop_arg'.
|
||
|
||
$ m4 -I examples
|
||
include(`forloop3.m4')
|
||
=>
|
||
undivert(`forloop3.m4')dnl
|
||
=>divert(`-1')
|
||
=># forloop_arg(from, to, macro) - invoke MACRO(value) for
|
||
=># each value between FROM and TO, without define overhead
|
||
=>define(`forloop_arg', `ifelse(eval(`($1) <= ($2)'), `1',
|
||
=> `_forloop(`$1', eval(`$2'), `$3(', `)')')')
|
||
=># forloop(var, from, to, stmt) - refactored to share code
|
||
=>define(`forloop', `ifelse(eval(`($2) <= ($3)'), `1',
|
||
=> `pushdef(`$1')_forloop(eval(`$2'), eval(`$3'),
|
||
=> `define(`$1',', `)$4')popdef(`$1')')')
|
||
=>define(`_forloop',
|
||
=> `$3`$1'$4`'ifelse(`$1', `$2', `',
|
||
=> `$0(incr(`$1'), `$2', `$3', `$4')')')
|
||
=>divert`'dnl
|
||
forloop(`i', `1', `3', ` i')
|
||
=> 1 2 3
|
||
define(`echo', `$@')
|
||
=>
|
||
forloop_arg(`1', `3', ` echo')
|
||
=> 1 2 3
|
||
include(`curry.m4')
|
||
=>
|
||
forloop_arg(`1', `3', `curry(`pushdef', `a')')
|
||
=>
|
||
a
|
||
=>3
|
||
popdef(`a')a
|
||
=>2
|
||
popdef(`a')a
|
||
=>1
|
||
popdef(`a')a
|
||
=>a
|
||
|
||
Of course, it is possible to make even more improvements, such as
|
||
adding an optional step argument, or allowing iteration through
|
||
descending sequences. GNU Autoconf provides some of these additional
|
||
bells and whistles in its `m4_for' macro.
|
||
|
||
|
||
File: m4.info, Node: Improved foreach, Next: Improved copy, Prev: Improved forloop, Up: Answers
|
||
|
||
17.3 Solution for `foreach'
|
||
===========================
|
||
|
||
The `foreach' and `foreachq' macros (*note Foreach::) as presented
|
||
earlier each have flaws. First, we will examine and fix the quadratic
|
||
behavior of `foreachq':
|
||
|
||
$ m4 -I examples
|
||
include(`foreachq.m4')
|
||
=>
|
||
traceon(`shift')debugmode(`aq')
|
||
=>
|
||
foreachq(`x', ``1', `2', `3', `4'', `x
|
||
')dnl
|
||
=>1
|
||
error-->m4trace: -3- shift(`1', `2', `3', `4')
|
||
error-->m4trace: -2- shift(`1', `2', `3', `4')
|
||
=>2
|
||
error-->m4trace: -4- shift(`1', `2', `3', `4')
|
||
error-->m4trace: -3- shift(`2', `3', `4')
|
||
error-->m4trace: -3- shift(`1', `2', `3', `4')
|
||
error-->m4trace: -2- shift(`2', `3', `4')
|
||
=>3
|
||
error-->m4trace: -5- shift(`1', `2', `3', `4')
|
||
error-->m4trace: -4- shift(`2', `3', `4')
|
||
error-->m4trace: -3- shift(`3', `4')
|
||
error-->m4trace: -4- shift(`1', `2', `3', `4')
|
||
error-->m4trace: -3- shift(`2', `3', `4')
|
||
error-->m4trace: -2- shift(`3', `4')
|
||
=>4
|
||
error-->m4trace: -6- shift(`1', `2', `3', `4')
|
||
error-->m4trace: -5- shift(`2', `3', `4')
|
||
error-->m4trace: -4- shift(`3', `4')
|
||
error-->m4trace: -3- shift(`4')
|
||
|
||
Each successive iteration was adding more quoted `shift'
|
||
invocations, and the entire list contents were passing through every
|
||
iteration. In general, when recursing, it is a good idea to make the
|
||
recursion use fewer arguments, rather than adding additional quoted
|
||
uses of `shift'. By doing so, `m4' uses less memory, invokes fewer
|
||
macros, is less likely to run into machine limits, and most
|
||
importantly, performs faster. The fixed version of `foreachq' can be
|
||
found in `m4-1.4.13/examples/foreachq2.m4':
|
||
|
||
$ m4 -I examples
|
||
include(`foreachq2.m4')
|
||
=>
|
||
undivert(`foreachq2.m4')dnl
|
||
=>include(`quote.m4')dnl
|
||
=>divert(`-1')
|
||
=># foreachq(x, `item_1, item_2, ..., item_n', stmt)
|
||
=># quoted list, improved version
|
||
=>define(`foreachq', `pushdef(`$1')_$0($@)popdef(`$1')')
|
||
=>define(`_arg1q', ``$1'')
|
||
=>define(`_rest', `ifelse(`$#', `1', `', `dquote(shift($@))')')
|
||
=>define(`_foreachq', `ifelse(`$2', `', `',
|
||
=> `define(`$1', _arg1q($2))$3`'$0(`$1', _rest($2), `$3')')')
|
||
=>divert`'dnl
|
||
traceon(`shift')debugmode(`aq')
|
||
=>
|
||
foreachq(`x', ``1', `2', `3', `4'', `x
|
||
')dnl
|
||
=>1
|
||
error-->m4trace: -3- shift(`1', `2', `3', `4')
|
||
=>2
|
||
error-->m4trace: -3- shift(`2', `3', `4')
|
||
=>3
|
||
error-->m4trace: -3- shift(`3', `4')
|
||
=>4
|
||
|
||
Note that the fixed version calls unquoted helper macros in
|
||
`_foreachq' to trim elements immediately; those helper macros in turn
|
||
must re-supply the layer of quotes lost in the macro invocation.
|
||
Contrast the use of `_arg1q', which quotes the first list element, with
|
||
`_arg1' of the earlier implementation that returned the first list
|
||
element directly. Additionally, by calling the helper method
|
||
immediately, the `defn(`ITERATOR')' no longer contains unexpanded
|
||
macros.
|
||
|
||
The astute m4 programmer might notice that the solution above still
|
||
uses more memory and macro invocations, and thus more time, than
|
||
strictly necessary. Note that `$2', which contains an arbitrarily long
|
||
quoted list, is expanded and rescanned three times per iteration of
|
||
`_foreachq'. Furthermore, every iteration of the algorithm effectively
|
||
unboxes then reboxes the list, which costs a couple of macro
|
||
invocations. It is possible to rewrite the algorithm for a bit more
|
||
speed by swapping the order of the arguments to `_foreachq' in order to
|
||
operate on an unboxed list in the first place, and by using the
|
||
fixed-length `$#' instead of an arbitrary length list as the key to end
|
||
recursion. The result is an overhead of six macro invocations per loop
|
||
(excluding any macros in TEXT), instead of eight. This alternative
|
||
approach is available as `m4-1.4.13/examples/foreach3.m4':
|
||
|
||
$ m4 -I examples
|
||
include(`foreachq3.m4')
|
||
=>
|
||
undivert(`foreachq3.m4')dnl
|
||
=>divert(`-1')
|
||
=># foreachq(x, `item_1, item_2, ..., item_n', stmt)
|
||
=># quoted list, alternate improved version
|
||
=>define(`foreachq', `ifelse(`$2', `', `',
|
||
=> `pushdef(`$1')_$0(`$1', `$3', `', $2)popdef(`$1')')')
|
||
=>define(`_foreachq', `ifelse(`$#', `3', `',
|
||
=> `define(`$1', `$4')$2`'$0(`$1', `$2',
|
||
=> shift(shift(shift($@))))')')
|
||
=>divert`'dnl
|
||
traceon(`shift')debugmode(`aq')
|
||
=>
|
||
foreachq(`x', ``1', `2', `3', `4'', `x
|
||
')dnl
|
||
=>1
|
||
error-->m4trace: -4- shift(`x', `x
|
||
error-->', `', `1', `2', `3', `4')
|
||
error-->m4trace: -3- shift(`x
|
||
error-->', `', `1', `2', `3', `4')
|
||
error-->m4trace: -2- shift(`', `1', `2', `3', `4')
|
||
=>2
|
||
error-->m4trace: -4- shift(`x', `x
|
||
error-->', `1', `2', `3', `4')
|
||
error-->m4trace: -3- shift(`x
|
||
error-->', `1', `2', `3', `4')
|
||
error-->m4trace: -2- shift(`1', `2', `3', `4')
|
||
=>3
|
||
error-->m4trace: -4- shift(`x', `x
|
||
error-->', `2', `3', `4')
|
||
error-->m4trace: -3- shift(`x
|
||
error-->', `2', `3', `4')
|
||
error-->m4trace: -2- shift(`2', `3', `4')
|
||
=>4
|
||
error-->m4trace: -4- shift(`x', `x
|
||
error-->', `3', `4')
|
||
error-->m4trace: -3- shift(`x
|
||
error-->', `3', `4')
|
||
error-->m4trace: -2- shift(`3', `4')
|
||
|
||
In the current version of M4, every instance of `$@' is rescanned as
|
||
it is encountered. Thus, the `foreachq3.m4' alternative uses much less
|
||
memory than `foreachq2.m4', and executes as much as 10% faster, since
|
||
each iteration encounters fewer `$@'. However, the implementation of
|
||
rescanning every byte in `$@' is quadratic in the number of bytes
|
||
scanned (for example, making the broken version in `foreachq.m4' cubic,
|
||
rather than quadratic, in behavior). A future release of M4 will
|
||
improve the underlying implementation by reusing results of previous
|
||
scans, so that both styles of `foreachq' can become linear in the
|
||
number of bytes scanned. Notice how the implementation injects an
|
||
empty argument prior to expanding `$2' within `foreachq'; the helper
|
||
macro `_foreachq' then ignores the third argument altogether, and ends
|
||
recursion when there are three arguments left because there was nothing
|
||
left to pass through `shift'. Thus, each iteration only needs one
|
||
`ifelse', rather than the two conditionals used in the version from
|
||
`foreachq2.m4'.
|
||
|
||
So far, all of the implementations of `foreachq' presented have been
|
||
quadratic with M4 1.4.x. But `forloop' is linear, because each
|
||
iteration parses a constant amount of arguments. So, it is possible to
|
||
design a variant that uses `forloop' to do the iteration, then uses
|
||
`$@' only once at the end, giving a linear result even with older M4
|
||
implementations. This implementation relies on the GNU extension that
|
||
`$10' expands to the tenth argument rather than the first argument
|
||
concatenated with `0'. The trick is to define an intermediate macro
|
||
that repeats the text `m4_define(`$1', `$N')$2`'', with `n' set to
|
||
successive integers corresponding to each argument. The helper macro
|
||
`_foreachq_' is needed in order to generate the literal sequences such
|
||
as `$1' into the intermediate macro, rather than expanding them as the
|
||
arguments of `_foreachq'. With this approach, no `shift' calls are
|
||
even needed! Even though there are seven macros of overhead per
|
||
iteration instead of six in `foreachq3.m4', the linear scaling is
|
||
apparent at relatively small list sizes. However, this approach will
|
||
need adjustment when a future version of M4 follows POSIX by no longer
|
||
treating `$10' as the tenth argument; the anticipation is that `${10}'
|
||
can be used instead, although that alternative syntax is not yet
|
||
supported.
|
||
|
||
$ m4 -I examples
|
||
include(`foreachq4.m4')
|
||
=>
|
||
undivert(`foreachq4.m4')dnl
|
||
=>include(`forloop2.m4')dnl
|
||
=>divert(`-1')
|
||
=># foreachq(x, `item_1, item_2, ..., item_n', stmt)
|
||
=># quoted list, version based on forloop
|
||
=>define(`foreachq',
|
||
=>`ifelse(`$2', `', `', `_$0(`$1', `$3', $2)')')
|
||
=>define(`_foreachq',
|
||
=>`pushdef(`$1', forloop(`$1', `3', `$#',
|
||
=> `$0_(`1', `2', indir(`$1'))')`popdef(
|
||
=> `$1')')indir(`$1', $@)')
|
||
=>define(`_foreachq_',
|
||
=>``define(`$$1', `$$3')$$2`''')
|
||
=>divert`'dnl
|
||
traceon(`shift')debugmode(`aq')
|
||
=>
|
||
foreachq(`x', ``1', `2', `3', `4'', `x
|
||
')dnl
|
||
=>1
|
||
=>2
|
||
=>3
|
||
=>4
|
||
|
||
For yet another approach, the improved version of `foreach',
|
||
available in `m4-1.4.13/examples/foreach2.m4', simply overquotes the
|
||
arguments to `_foreach' to begin with, using `dquote_elt'. Then
|
||
`_foreach' can just use `_arg1' to remove the extra layer of quoting
|
||
that was added up front:
|
||
|
||
$ m4 -I examples
|
||
include(`foreach2.m4')
|
||
=>
|
||
undivert(`foreach2.m4')dnl
|
||
=>include(`quote.m4')dnl
|
||
=>divert(`-1')
|
||
=># foreach(x, (item_1, item_2, ..., item_n), stmt)
|
||
=># parenthesized list, improved version
|
||
=>define(`foreach', `pushdef(`$1')_$0(`$1',
|
||
=> (dquote(dquote_elt$2)), `$3')popdef(`$1')')
|
||
=>define(`_arg1', `$1')
|
||
=>define(`_foreach', `ifelse(`$2', `(`')', `',
|
||
=> `define(`$1', _arg1$2)$3`'$0(`$1', (dquote(shift$2)), `$3')')')
|
||
=>divert`'dnl
|
||
traceon(`shift')debugmode(`aq')
|
||
=>
|
||
foreach(`x', `(`1', `2', `3', `4')', `x
|
||
')dnl
|
||
error-->m4trace: -4- shift(`1', `2', `3', `4')
|
||
error-->m4trace: -4- shift(`2', `3', `4')
|
||
error-->m4trace: -4- shift(`3', `4')
|
||
=>1
|
||
error-->m4trace: -3- shift(``1'', ``2'', ``3'', ``4'')
|
||
=>2
|
||
error-->m4trace: -3- shift(``2'', ``3'', ``4'')
|
||
=>3
|
||
error-->m4trace: -3- shift(``3'', ``4'')
|
||
=>4
|
||
error-->m4trace: -3- shift(``4'')
|
||
|
||
It is likewise possible to write a variant of `foreach' that
|
||
performs in linear time on M4 1.4.x; the easiest method is probably
|
||
writing a version of `foreach' that unboxes its list, then invokes
|
||
`_foreachq' as previously defined in `foreachq4.m4'.
|
||
|
||
In summary, recursion over list elements is trickier than it
|
||
appeared at first glance, but provides a powerful idiom within `m4'
|
||
processing. As a final demonstration, both list styles are now able to
|
||
handle several scenarios that would wreak havoc on one or both of the
|
||
original implementations. This points out one other difference between
|
||
the list styles. `foreach' evaluates unquoted list elements only once,
|
||
in preparation for calling `_foreach', similary for `foreachq' as
|
||
provided by `foreachq3.m4' or `foreachq4.m4'. But `foreachq', as
|
||
provided by `foreachq2.m4', evaluates unquoted list elements twice
|
||
while visiting the first list element, once in `_arg1q' and once in
|
||
`_rest'. When deciding which list style to use, one must take into
|
||
account whether repeating the side effects of unquoted list elements
|
||
will have any detrimental effects.
|
||
|
||
$ m4 -I examples
|
||
include(`foreach2.m4')
|
||
=>
|
||
include(`foreachq2.m4')
|
||
=>
|
||
dnl 0-element list:
|
||
foreach(`x', `', `<x>') / foreachq(`x', `', `<x>')
|
||
=> /
|
||
dnl 1-element list of empty element
|
||
foreach(`x', `()', `<x>') / foreachq(`x', ``'', `<x>')
|
||
=><> / <>
|
||
dnl 2-element list of empty elements
|
||
foreach(`x', `(`',`')', `<x>') / foreachq(`x', ``',`'', `<x>')
|
||
=><><> / <><>
|
||
dnl 1-element list of a comma
|
||
foreach(`x', `(`,')', `<x>') / foreachq(`x', ``,'', `<x>')
|
||
=><,> / <,>
|
||
dnl 2-element list of unbalanced parentheses
|
||
foreach(`x', `(`(', `)')', `<x>') / foreachq(`x', ``(', `)'', `<x>')
|
||
=><(><)> / <(><)>
|
||
define(`ab', `oops')dnl using defn(`iterator')
|
||
foreach(`x', `(`a', `b')', `defn(`x')') /dnl
|
||
foreachq(`x', ``a', `b'', `defn(`x')')
|
||
=>ab / ab
|
||
define(`active', `ACT, IVE')
|
||
=>
|
||
traceon(`active')
|
||
=>
|
||
dnl list of unquoted macros; expansion occurs before recursion
|
||
foreach(`x', `(active, active)', `<x>
|
||
')dnl
|
||
error-->m4trace: -4- active -> `ACT, IVE'
|
||
error-->m4trace: -4- active -> `ACT, IVE'
|
||
=><ACT>
|
||
=><IVE>
|
||
=><ACT>
|
||
=><IVE>
|
||
foreachq(`x', `active, active', `<x>
|
||
')dnl
|
||
error-->m4trace: -3- active -> `ACT, IVE'
|
||
error-->m4trace: -3- active -> `ACT, IVE'
|
||
=><ACT>
|
||
error-->m4trace: -3- active -> `ACT, IVE'
|
||
error-->m4trace: -3- active -> `ACT, IVE'
|
||
=><IVE>
|
||
=><ACT>
|
||
=><IVE>
|
||
dnl list of quoted macros; expansion occurs during recursion
|
||
foreach(`x', `(`active', `active')', `<x>
|
||
')dnl
|
||
error-->m4trace: -1- active -> `ACT, IVE'
|
||
=><ACT, IVE>
|
||
error-->m4trace: -1- active -> `ACT, IVE'
|
||
=><ACT, IVE>
|
||
foreachq(`x', ``active', `active'', `<x>
|
||
')dnl
|
||
error-->m4trace: -1- active -> `ACT, IVE'
|
||
=><ACT, IVE>
|
||
error-->m4trace: -1- active -> `ACT, IVE'
|
||
=><ACT, IVE>
|
||
dnl list of double-quoted macro names; no expansion
|
||
foreach(`x', `(``active'', ``active'')', `<x>
|
||
')dnl
|
||
=><active>
|
||
=><active>
|
||
foreachq(`x', ```active'', ``active''', `<x>
|
||
')dnl
|
||
=><active>
|
||
=><active>
|
||
|
||
|
||
File: m4.info, Node: Improved copy, Next: Improved m4wrap, Prev: Improved foreach, Up: Answers
|
||
|
||
17.4 Solution for `copy'
|
||
========================
|
||
|
||
The macro `copy' presented above is unable to handle builtin tokens
|
||
with M4 1.4.x, because it tries to pass the builtin token through the
|
||
macro `curry', where it is silently flattened to an empty string (*note
|
||
Composition::). Rather than using the problematic `curry' to work
|
||
around the limitation that `stack_foreach' expects to invoke a macro
|
||
that takes exactly one argument, we can write a new macro that lets us
|
||
form the exact two-argument `pushdef' call sequence needed, so that we
|
||
are no longer passing a builtin token through a text macro.
|
||
|
||
-- Composite: stack_foreach_sep (MACRO, PRE, POST, SEP)
|
||
-- Composite: stack_foreach_sep_lifo (MACRO, PRE, POST, SEP)
|
||
For each of the `pushdef' definitions associated with MACRO,
|
||
expand the sequence `PRE`'definition`'POST'. Additionally, expand
|
||
SEP between definitions. `stack_foreach_sep' visits the oldest
|
||
definition first, while `stack_foreach_sep_lifo' visits the
|
||
current definition first. The expansion may dereference MACRO,
|
||
but should not modify it. There are a few special macros, such as
|
||
`defn', which cannot be used as the MACRO parameter.
|
||
|
||
Note that `stack_foreach(`MACRO', `ACTION')' is equivalent to
|
||
`stack_foreach_sep(`MACRO', `ACTION(', `)')'. By supplying explicit
|
||
parentheses, split among the PRE and POST arguments to
|
||
`stack_foreach_sep', it is now possible to construct macro calls with
|
||
more than one argument, without passing builtin tokens through a macro
|
||
call. It is likewise possible to directly reference the stack
|
||
definitions without a macro call, by leaving PRE and POST empty. Thus,
|
||
in addition to fixing `copy' on builtin tokens, it also executes with
|
||
fewer macro invocations.
|
||
|
||
The new macro also adds a separator that is only output after the
|
||
first iteration of the helper `_stack_reverse_sep', implemented by
|
||
prepending the original SEP to PRE and omitting a SEP argument in
|
||
subsequent iterations. Note that the empty string that separates SEP
|
||
from PRE is provided as part of the fourth argument when originally
|
||
calling `_stack_reverse_sep', and not by writing `$4`'$3' as the third
|
||
argument in the recursive call; while the other approach would give the
|
||
same output, it does so at the expense of increasing the argument size
|
||
on each iteration of `_stack_reverse_sep', which results in quadratic
|
||
instead of linear execution time. The improved stack walking macros
|
||
are available in `m4-1.4.13/examples/stack_sep.m4':
|
||
|
||
$ m4 -I examples
|
||
include(`stack_sep.m4')
|
||
=>
|
||
define(`copy', `ifdef(`$2', `errprint(`$2 already defined
|
||
')m4exit(`1')',
|
||
`stack_foreach_sep(`$1', `pushdef(`$2',', `)')')')dnl
|
||
pushdef(`a', `1')pushdef(`a', defn(`divnum'))
|
||
=>
|
||
copy(`a', `b')
|
||
=>
|
||
b
|
||
=>0
|
||
popdef(`b')
|
||
=>
|
||
b
|
||
=>1
|
||
pushdef(`c', `1')pushdef(`c', `2')
|
||
=>
|
||
stack_foreach_sep_lifo(`c', `', `', `, ')
|
||
=>2, 1
|
||
undivert(`stack_sep.m4')dnl
|
||
=>divert(`-1')
|
||
=># stack_foreach_sep(macro, pre, post, sep)
|
||
=># Invoke PRE`'defn`'POST with a single argument of each definition
|
||
=># from the definition stack of MACRO, starting with the oldest, and
|
||
=># separated by SEP between definitions.
|
||
=>define(`stack_foreach_sep',
|
||
=>`_stack_reverse_sep(`$1', `tmp-$1')'dnl
|
||
=>`_stack_reverse_sep(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4`'')')
|
||
=># stack_foreach_sep_lifo(macro, pre, post, sep)
|
||
=># Like stack_foreach_sep, but starting with the newest definition.
|
||
=>define(`stack_foreach_sep_lifo',
|
||
=>`_stack_reverse_sep(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4`'')'dnl
|
||
=>`_stack_reverse_sep(`tmp-$1', `$1')')
|
||
=>define(`_stack_reverse_sep',
|
||
=>`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
|
||
=> `$1', `$2', `$4$3')')')
|
||
=>divert`'dnl
|
||
|
||
|
||
File: m4.info, Node: Improved m4wrap, Next: Improved cleardivert, Prev: Improved copy, Up: Answers
|
||
|
||
17.5 Solution for `m4wrap'
|
||
==========================
|
||
|
||
The replacement `m4wrap' versions presented above, designed to
|
||
guarantee FIFO or LIFO order regardless of the underlying M4
|
||
implementation, share a bug when dealing with wrapped text that looks
|
||
like parameter expansion. Note how the invocation of `m4wrapN'
|
||
interprets these parameters, while using the builtin preserves them for
|
||
their intended use.
|
||
|
||
$ m4 -I examples
|
||
include(`wraplifo.m4')
|
||
=>
|
||
m4wrap(`define(`foo', ``$0:'-$1-$*-$#-')foo(`a', `b')
|
||
')
|
||
=>
|
||
builtin(`m4wrap', ``'define(`bar', ``$0:'-$1-$*-$#-')bar(`a', `b')
|
||
')
|
||
=>
|
||
^D
|
||
=>bar:-a-a,b-2-
|
||
=>m4wrap0:---0-
|
||
|
||
Additionally, the computation of `_m4wrap_level' and creation of
|
||
multiple `m4wrapN' placeholders in the original examples is more
|
||
expensive in time and memory than strictly necessary. Notice how the
|
||
improved version grabs the wrapped text via `defn' to avoid parameter
|
||
expansion, then undefines `_m4wrap_text', before stripping a level of
|
||
quotes with `_arg1' to expand the text. That way, each level of
|
||
wrapping reuses the single placeholder, which starts each nesting level
|
||
in an undefined state.
|
||
|
||
Finally, it is worth emulating the GNU M4 extension of saving all
|
||
arguments to `m4wrap', separated by a space, rather than saving just
|
||
the first argument. This is done with the `join' macro documented
|
||
previously (*note Shift::). The improved LIFO example is shipped as
|
||
`m4-1.4.13/examples/wraplifo2.m4', and can easily be converted to a
|
||
FIFO solution by swapping the adjacent invocations of `joinall' and
|
||
`defn'.
|
||
|
||
$ m4 -I examples
|
||
include(`wraplifo2.m4')
|
||
=>
|
||
undivert(`wraplifo2.m4')dnl
|
||
=>dnl Redefine m4wrap to have LIFO semantics, improved example.
|
||
=>include(`join.m4')dnl
|
||
=>define(`_m4wrap', defn(`m4wrap'))dnl
|
||
=>define(`_arg1', `$1')dnl
|
||
=>define(`m4wrap',
|
||
=>`ifdef(`_$0_text',
|
||
=> `define(`_$0_text', joinall(` ', $@)defn(`_$0_text'))',
|
||
=> `_$0(`_arg1(defn(`_$0_text')undefine(`_$0_text'))')dnl
|
||
=>define(`_$0_text', joinall(` ', $@))')')dnl
|
||
m4wrap(`define(`foo', ``$0:'-$1-$*-$#-')foo(`a', `b')
|
||
')
|
||
=>
|
||
m4wrap(`lifo text
|
||
m4wrap(`nested', `', `$@
|
||
')')
|
||
=>
|
||
^D
|
||
=>lifo text
|
||
=>foo:-a-a,b-2-
|
||
=>nested $@
|
||
|
||
|
||
File: m4.info, Node: Improved cleardivert, Next: Improved capitalize, Prev: Improved m4wrap, Up: Answers
|
||
|
||
17.6 Solution for `cleardivert'
|
||
===============================
|
||
|
||
The `cleardivert' macro (*note Cleardivert::) cannot, as it stands, be
|
||
called without arguments to clear all pending diversions. That is
|
||
because using undivert with an empty string for an argument is different
|
||
than using it with no arguments at all. Compare the earlier definition
|
||
with one that takes the number of arguments into account:
|
||
|
||
define(`cleardivert',
|
||
`pushdef(`_n', divnum)divert(`-1')undivert($@)divert(_n)popdef(`_n')')
|
||
=>
|
||
divert(`1')one
|
||
divert
|
||
=>
|
||
cleardivert
|
||
=>
|
||
undivert
|
||
=>one
|
||
=>
|
||
define(`cleardivert',
|
||
`pushdef(`_num', divnum)divert(`-1')ifelse(`$#', `0',
|
||
`undivert`'', `undivert($@)')divert(_num)popdef(`_num')')
|
||
=>
|
||
divert(`2')two
|
||
divert
|
||
=>
|
||
cleardivert
|
||
=>
|
||
undivert
|
||
=>
|
||
|
||
|
||
File: m4.info, Node: Improved capitalize, Next: Improved fatal_error, Prev: Improved cleardivert, Up: Answers
|
||
|
||
17.7 Solution for `capitalize'
|
||
==============================
|
||
|
||
The `capitalize' macro (*note Patsubst::) as presented earlier does not
|
||
allow clients to follow the quoting rule of thumb. Consider the three
|
||
macros `active', `Active', and `ACTIVE', and the difference between
|
||
calling `capitalize' with the expansion of a macro, expanding the
|
||
result of a case change, and changing the case of a double-quoted
|
||
string:
|
||
|
||
$ m4 -I examples
|
||
include(`capitalize.m4')dnl
|
||
define(`active', `act1, ive')dnl
|
||
define(`Active', `Act2, Ive')dnl
|
||
define(`ACTIVE', `ACT3, IVE')dnl
|
||
upcase(active)
|
||
=>ACT1,IVE
|
||
upcase(`active')
|
||
=>ACT3, IVE
|
||
upcase(``active'')
|
||
=>ACTIVE
|
||
downcase(ACTIVE)
|
||
=>act3,ive
|
||
downcase(`ACTIVE')
|
||
=>act1, ive
|
||
downcase(``ACTIVE'')
|
||
=>active
|
||
capitalize(active)
|
||
=>Act1
|
||
capitalize(`active')
|
||
=>Active
|
||
capitalize(``active'')
|
||
=>_capitalize(`active')
|
||
define(`A', `OOPS')
|
||
=>
|
||
capitalize(active)
|
||
=>OOPSct1
|
||
capitalize(`active')
|
||
=>OOPSctive
|
||
|
||
First, when `capitalize' is called with more than one argument, it
|
||
was throwing away later arguments, whereas `upcase' and `downcase' used
|
||
`$*' to collect them all. The fix is simple: use `$*' consistently.
|
||
|
||
Next, with single-quoting, `capitalize' outputs a single character,
|
||
a set of quotes, then the rest of the characters, making it impossible
|
||
to invoke `Active' after the fact, and allowing the alternate macro `A'
|
||
to interfere. Here, the solution is to use additional quoting in the
|
||
helper macros, then pass the final over-quoted output string through
|
||
`_arg1' to remove the extra quoting and finally invoke the concatenated
|
||
portions as a single string.
|
||
|
||
Finally, when passed a double-quoted string, the nested macro
|
||
`_capitalize' is never invoked because it ended up nested inside
|
||
quotes. This one is the toughest to fix. In short, we have no idea how
|
||
many levels of quotes are in effect on the substring being altered by
|
||
`patsubst'. If the replacement string cannot be expressed entirely in
|
||
terms of literal text and backslash substitutions, then we need a
|
||
mechanism to guarantee that the helper macros are invoked outside of
|
||
quotes. In other words, this sounds like a job for `changequote'
|
||
(*note Changequote::). By changing the active quoting characters, we
|
||
can guarantee that replacement text injected by `patsubst' always
|
||
occurs in the middle of a string that has exactly one level of
|
||
over-quoting using alternate quotes; so the replacement text closes the
|
||
quoted string, invokes the helper macros, then reopens the quoted
|
||
string. In turn, that means the replacement text has unbalanced quotes,
|
||
necessitating another round of `changequote'.
|
||
|
||
In the fixed version below, (also shipped as
|
||
`m4-1.4.13/examples/capitalize.m4'), `capitalize' uses the alternate
|
||
quotes of `<<[' and `]>>' (the longer strings are chosen so as to be
|
||
less likely to appear in the text being converted). The helpers
|
||
`_to_alt' and `_from_alt' merely reduce the number of characters
|
||
required to perform a `changequote', since the definition changes
|
||
twice. The outermost pair means that `patsubst' and `_capitalize_alt'
|
||
are invoked with alternate quoting; the innermost pair is used so that
|
||
the third argument to `patsubst' can contain an unbalanced `]>>'/`<<['
|
||
pair. Note that `upcase' and `downcase' must be redefined as
|
||
`_upcase_alt' and `_downcase_alt', since they contain nested quotes but
|
||
are invoked with the alternate quoting scheme in effect.
|
||
|
||
$ m4 -I examples
|
||
include(`capitalize2.m4')dnl
|
||
define(`active', `act1, ive')dnl
|
||
define(`Active', `Act2, Ive')dnl
|
||
define(`ACTIVE', `ACT3, IVE')dnl
|
||
define(`A', `OOPS')dnl
|
||
capitalize(active; `active'; ``active''; ```actIVE''')
|
||
=>Act1,Ive; Act2, Ive; Active; `Active'
|
||
undivert(`capitalize2.m4')dnl
|
||
=>divert(`-1')
|
||
=># upcase(text)
|
||
=># downcase(text)
|
||
=># capitalize(text)
|
||
=># change case of text, improved version
|
||
=>define(`upcase', `translit(`$*', `a-z', `A-Z')')
|
||
=>define(`downcase', `translit(`$*', `A-Z', `a-z')')
|
||
=>define(`_arg1', `$1')
|
||
=>define(`_to_alt', `changequote(`<<[', `]>>')')
|
||
=>define(`_from_alt', `changequote(<<[`]>>, <<[']>>)')
|
||
=>define(`_upcase_alt', `translit(<<[$*]>>, <<[a-z]>>, <<[A-Z]>>)')
|
||
=>define(`_downcase_alt', `translit(<<[$*]>>, <<[A-Z]>>, <<[a-z]>>)')
|
||
=>define(`_capitalize_alt',
|
||
=> `regexp(<<[$1]>>, <<[^\(\w\)\(\w*\)]>>,
|
||
=> <<[_upcase_alt(<<[<<[\1]>>]>>)_downcase_alt(<<[<<[\2]>>]>>)]>>)')
|
||
=>define(`capitalize',
|
||
=> `_arg1(_to_alt()patsubst(<<[<<[$*]>>]>>, <<[\w+]>>,
|
||
=> _from_alt()`]>>_$0_alt(<<[\&]>>)<<['_to_alt())_from_alt())')
|
||
=>divert`'dnl
|
||
|
||
|
||
File: m4.info, Node: Improved fatal_error, Prev: Improved capitalize, Up: Answers
|
||
|
||
17.8 Solution for `fatal_error'
|
||
===============================
|
||
|
||
The `fatal_error' macro (*note M4exit::) is not robust to versions of
|
||
GNU M4 earlier than 1.4.8, where invoking `__file__' (*note Location::)
|
||
inside `m4wrap' would result in an empty string, and `__line__'
|
||
resulted in `0' even though all files start at line 1. Furthermore,
|
||
versions earlier than 1.4.6 did not support the `__program__' macro.
|
||
If you want `fatal_error' to work across the entire 1.4.x release
|
||
series, a better implementation would be:
|
||
|
||
define(`fatal_error',
|
||
`errprint(ifdef(`__program__', `__program__', ``m4'')'dnl
|
||
`:ifelse(__line__, `0', `',
|
||
`__file__:__line__:')` fatal error: $*
|
||
')m4exit(`1')')
|
||
=>
|
||
m4wrap(`divnum(`demo of internal message')
|
||
fatal_error(`inside wrapped text')')
|
||
=>
|
||
^D
|
||
error-->m4:stdin:6: Warning: excess arguments to builtin `divnum' ignored
|
||
=>0
|
||
error-->m4:stdin:6: fatal error: inside wrapped text
|
||
|
||
|
||
File: m4.info, Node: Copying This Package, Next: Copying This Manual, Prev: Answers, Up: Top
|
||
|
||
Appendix A How to make copies of the overall M4 package
|
||
*******************************************************
|
||
|
||
This appendix covers the license for copying the source code of the
|
||
overall M4 package. This manual is under a different set of
|
||
restrictions, covered later (*note Copying This Manual::).
|
||
|
||
* Menu:
|
||
|
||
* GNU General Public License:: License for copying the M4 package
|
||
|
||
|
||
File: m4.info, Node: GNU General Public License, Up: Copying This Package
|
||
|
||
A.1 License for copying the M4 package
|
||
======================================
|
||
|
||
Version 3, 29 June 2007
|
||
|
||
Copyright (C) 2007 Free Software Foundation, Inc. `http://fsf.org/'
|
||
|
||
Everyone is permitted to copy and distribute verbatim copies of this
|
||
license document, but changing it is not allowed.
|
||
|
||
Preamble
|
||
========
|
||
|
||
The GNU General Public License is a free, copyleft license for software
|
||
and other kinds of works.
|
||
|
||
The licenses for most software and other practical works are designed
|
||
to take away your freedom to share and change the works. By contrast,
|
||
the GNU General Public License is intended to guarantee your freedom to
|
||
share and change all versions of a program--to make sure it remains
|
||
free software for all its users. We, the Free Software Foundation, use
|
||
the GNU General Public License for most of our software; it applies
|
||
also to any other work released this way by its authors. You can apply
|
||
it to your programs, too.
|
||
|
||
When we speak of free software, we are referring to freedom, not
|
||
price. Our General Public Licenses are designed to make sure that you
|
||
have the freedom to distribute copies of free software (and charge for
|
||
them if you wish), that you receive source code or can get it if you
|
||
want it, that you can change the software or use pieces of it in new
|
||
free programs, and that you know you can do these things.
|
||
|
||
To protect your rights, we need to prevent others from denying you
|
||
these rights or asking you to surrender the rights. Therefore, you
|
||
have certain responsibilities if you distribute copies of the software,
|
||
or if you modify it: responsibilities to respect the freedom of others.
|
||
|
||
For example, if you distribute copies of such a program, whether
|
||
gratis or for a fee, you must pass on to the recipients the same
|
||
freedoms that you received. You must make sure that they, too, receive
|
||
or can get the source code. And you must show them these terms so they
|
||
know their rights.
|
||
|
||
Developers that use the GNU GPL protect your rights with two steps:
|
||
(1) assert copyright on the software, and (2) offer you this License
|
||
giving you legal permission to copy, distribute and/or modify it.
|
||
|
||
For the developers' and authors' protection, the GPL clearly explains
|
||
that there is no warranty for this free software. For both users' and
|
||
authors' sake, the GPL requires that modified versions be marked as
|
||
changed, so that their problems will not be attributed erroneously to
|
||
authors of previous versions.
|
||
|
||
Some devices are designed to deny users access to install or run
|
||
modified versions of the software inside them, although the
|
||
manufacturer can do so. This is fundamentally incompatible with the
|
||
aim of protecting users' freedom to change the software. The
|
||
systematic pattern of such abuse occurs in the area of products for
|
||
individuals to use, which is precisely where it is most unacceptable.
|
||
Therefore, we have designed this version of the GPL to prohibit the
|
||
practice for those products. If such problems arise substantially in
|
||
other domains, we stand ready to extend this provision to those domains
|
||
in future versions of the GPL, as needed to protect the freedom of
|
||
users.
|
||
|
||
Finally, every program is threatened constantly by software patents.
|
||
States should not allow patents to restrict development and use of
|
||
software on general-purpose computers, but in those that do, we wish to
|
||
avoid the special danger that patents applied to a free program could
|
||
make it effectively proprietary. To prevent this, the GPL assures that
|
||
patents cannot be used to render the program non-free.
|
||
|
||
The precise terms and conditions for copying, distribution and
|
||
modification follow.
|
||
|
||
TERMS AND CONDITIONS
|
||
====================
|
||
|
||
0. Definitions.
|
||
|
||
"This License" refers to version 3 of the GNU General Public
|
||
License.
|
||
|
||
"Copyright" also means copyright-like laws that apply to other
|
||
kinds of works, such as semiconductor masks.
|
||
|
||
"The Program" refers to any copyrightable work licensed under this
|
||
License. Each licensee is addressed as "you". "Licensees" and
|
||
"recipients" may be individuals or organizations.
|
||
|
||
To "modify" a work means to copy from or adapt all or part of the
|
||
work in a fashion requiring copyright permission, other than the
|
||
making of an exact copy. The resulting work is called a "modified
|
||
version" of the earlier work or a work "based on" the earlier work.
|
||
|
||
A "covered work" means either the unmodified Program or a work
|
||
based on the Program.
|
||
|
||
To "propagate" a work means to do anything with it that, without
|
||
permission, would make you directly or secondarily liable for
|
||
infringement under applicable copyright law, except executing it
|
||
on a computer or modifying a private copy. Propagation includes
|
||
copying, distribution (with or without modification), making
|
||
available to the public, and in some countries other activities as
|
||
well.
|
||
|
||
To "convey" a work means any kind of propagation that enables other
|
||
parties to make or receive copies. Mere interaction with a user
|
||
through a computer network, with no transfer of a copy, is not
|
||
conveying.
|
||
|
||
An interactive user interface displays "Appropriate Legal Notices"
|
||
to the extent that it includes a convenient and prominently visible
|
||
feature that (1) displays an appropriate copyright notice, and (2)
|
||
tells the user that there is no warranty for the work (except to
|
||
the extent that warranties are provided), that licensees may
|
||
convey the work under this License, and how to view a copy of this
|
||
License. If the interface presents a list of user commands or
|
||
options, such as a menu, a prominent item in the list meets this
|
||
criterion.
|
||
|
||
1. Source Code.
|
||
|
||
The "source code" for a work means the preferred form of the work
|
||
for making modifications to it. "Object code" means any
|
||
non-source form of a work.
|
||
|
||
A "Standard Interface" means an interface that either is an
|
||
official standard defined by a recognized standards body, or, in
|
||
the case of interfaces specified for a particular programming
|
||
language, one that is widely used among developers working in that
|
||
language.
|
||
|
||
The "System Libraries" of an executable work include anything,
|
||
other than the work as a whole, that (a) is included in the normal
|
||
form of packaging a Major Component, but which is not part of that
|
||
Major Component, and (b) serves only to enable use of the work
|
||
with that Major Component, or to implement a Standard Interface
|
||
for which an implementation is available to the public in source
|
||
code form. A "Major Component", in this context, means a major
|
||
essential component (kernel, window system, and so on) of the
|
||
specific operating system (if any) on which the executable work
|
||
runs, or a compiler used to produce the work, or an object code
|
||
interpreter used to run it.
|
||
|
||
The "Corresponding Source" for a work in object code form means all
|
||
the source code needed to generate, install, and (for an executable
|
||
work) run the object code and to modify the work, including
|
||
scripts to control those activities. However, it does not include
|
||
the work's System Libraries, or general-purpose tools or generally
|
||
available free programs which are used unmodified in performing
|
||
those activities but which are not part of the work. For example,
|
||
Corresponding Source includes interface definition files
|
||
associated with source files for the work, and the source code for
|
||
shared libraries and dynamically linked subprograms that the work
|
||
is specifically designed to require, such as by intimate data
|
||
communication or control flow between those subprograms and other
|
||
parts of the work.
|
||
|
||
The Corresponding Source need not include anything that users can
|
||
regenerate automatically from other parts of the Corresponding
|
||
Source.
|
||
|
||
The Corresponding Source for a work in source code form is that
|
||
same work.
|
||
|
||
2. Basic Permissions.
|
||
|
||
All rights granted under this License are granted for the term of
|
||
copyright on the Program, and are irrevocable provided the stated
|
||
conditions are met. This License explicitly affirms your unlimited
|
||
permission to run the unmodified Program. The output from running
|
||
a covered work is covered by this License only if the output,
|
||
given its content, constitutes a covered work. This License
|
||
acknowledges your rights of fair use or other equivalent, as
|
||
provided by copyright law.
|
||
|
||
You may make, run and propagate covered works that you do not
|
||
convey, without conditions so long as your license otherwise
|
||
remains in force. You may convey covered works to others for the
|
||
sole purpose of having them make modifications exclusively for
|
||
you, or provide you with facilities for running those works,
|
||
provided that you comply with the terms of this License in
|
||
conveying all material for which you do not control copyright.
|
||
Those thus making or running the covered works for you must do so
|
||
exclusively on your behalf, under your direction and control, on
|
||
terms that prohibit them from making any copies of your
|
||
copyrighted material outside their relationship with you.
|
||
|
||
Conveying under any other circumstances is permitted solely under
|
||
the conditions stated below. Sublicensing is not allowed; section
|
||
10 makes it unnecessary.
|
||
|
||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||
|
||
No covered work shall be deemed part of an effective technological
|
||
measure under any applicable law fulfilling obligations under
|
||
article 11 of the WIPO copyright treaty adopted on 20 December
|
||
1996, or similar laws prohibiting or restricting circumvention of
|
||
such measures.
|
||
|
||
When you convey a covered work, you waive any legal power to forbid
|
||
circumvention of technological measures to the extent such
|
||
circumvention is effected by exercising rights under this License
|
||
with respect to the covered work, and you disclaim any intention
|
||
to limit operation or modification of the work as a means of
|
||
enforcing, against the work's users, your or third parties' legal
|
||
rights to forbid circumvention of technological measures.
|
||
|
||
4. Conveying Verbatim Copies.
|
||
|
||
You may convey verbatim copies of the Program's source code as you
|
||
receive it, in any medium, provided that you conspicuously and
|
||
appropriately publish on each copy an appropriate copyright notice;
|
||
keep intact all notices stating that this License and any
|
||
non-permissive terms added in accord with section 7 apply to the
|
||
code; keep intact all notices of the absence of any warranty; and
|
||
give all recipients a copy of this License along with the Program.
|
||
|
||
You may charge any price or no price for each copy that you convey,
|
||
and you may offer support or warranty protection for a fee.
|
||
|
||
5. Conveying Modified Source Versions.
|
||
|
||
You may convey a work based on the Program, or the modifications to
|
||
produce it from the Program, in the form of source code under the
|
||
terms of section 4, provided that you also meet all of these
|
||
conditions:
|
||
|
||
a. The work must carry prominent notices stating that you
|
||
modified it, and giving a relevant date.
|
||
|
||
b. The work must carry prominent notices stating that it is
|
||
released under this License and any conditions added under
|
||
section 7. This requirement modifies the requirement in
|
||
section 4 to "keep intact all notices".
|
||
|
||
c. You must license the entire work, as a whole, under this
|
||
License to anyone who comes into possession of a copy. This
|
||
License will therefore apply, along with any applicable
|
||
section 7 additional terms, to the whole of the work, and all
|
||
its parts, regardless of how they are packaged. This License
|
||
gives no permission to license the work in any other way, but
|
||
it does not invalidate such permission if you have separately
|
||
received it.
|
||
|
||
d. If the work has interactive user interfaces, each must display
|
||
Appropriate Legal Notices; however, if the Program has
|
||
interactive interfaces that do not display Appropriate Legal
|
||
Notices, your work need not make them do so.
|
||
|
||
A compilation of a covered work with other separate and independent
|
||
works, which are not by their nature extensions of the covered
|
||
work, and which are not combined with it such as to form a larger
|
||
program, in or on a volume of a storage or distribution medium, is
|
||
called an "aggregate" if the compilation and its resulting
|
||
copyright are not used to limit the access or legal rights of the
|
||
compilation's users beyond what the individual works permit.
|
||
Inclusion of a covered work in an aggregate does not cause this
|
||
License to apply to the other parts of the aggregate.
|
||
|
||
6. Conveying Non-Source Forms.
|
||
|
||
You may convey a covered work in object code form under the terms
|
||
of sections 4 and 5, provided that you also convey the
|
||
machine-readable Corresponding Source under the terms of this
|
||
License, in one of these ways:
|
||
|
||
a. Convey the object code in, or embodied in, a physical product
|
||
(including a physical distribution medium), accompanied by the
|
||
Corresponding Source fixed on a durable physical medium
|
||
customarily used for software interchange.
|
||
|
||
b. Convey the object code in, or embodied in, a physical product
|
||
(including a physical distribution medium), accompanied by a
|
||
written offer, valid for at least three years and valid for
|
||
as long as you offer spare parts or customer support for that
|
||
product model, to give anyone who possesses the object code
|
||
either (1) a copy of the Corresponding Source for all the
|
||
software in the product that is covered by this License, on a
|
||
durable physical medium customarily used for software
|
||
interchange, for a price no more than your reasonable cost of
|
||
physically performing this conveying of source, or (2) access
|
||
to copy the Corresponding Source from a network server at no
|
||
charge.
|
||
|
||
c. Convey individual copies of the object code with a copy of
|
||
the written offer to provide the Corresponding Source. This
|
||
alternative is allowed only occasionally and noncommercially,
|
||
and only if you received the object code with such an offer,
|
||
in accord with subsection 6b.
|
||
|
||
d. Convey the object code by offering access from a designated
|
||
place (gratis or for a charge), and offer equivalent access
|
||
to the Corresponding Source in the same way through the same
|
||
place at no further charge. You need not require recipients
|
||
to copy the Corresponding Source along with the object code.
|
||
If the place to copy the object code is a network server, the
|
||
Corresponding Source may be on a different server (operated
|
||
by you or a third party) that supports equivalent copying
|
||
facilities, provided you maintain clear directions next to
|
||
the object code saying where to find the Corresponding Source.
|
||
Regardless of what server hosts the Corresponding Source, you
|
||
remain obligated to ensure that it is available for as long
|
||
as needed to satisfy these requirements.
|
||
|
||
e. Convey the object code using peer-to-peer transmission,
|
||
provided you inform other peers where the object code and
|
||
Corresponding Source of the work are being offered to the
|
||
general public at no charge under subsection 6d.
|
||
|
||
|
||
A separable portion of the object code, whose source code is
|
||
excluded from the Corresponding Source as a System Library, need
|
||
not be included in conveying the object code work.
|
||
|
||
A "User Product" is either (1) a "consumer product", which means
|
||
any tangible personal property which is normally used for personal,
|
||
family, or household purposes, or (2) anything designed or sold for
|
||
incorporation into a dwelling. In determining whether a product
|
||
is a consumer product, doubtful cases shall be resolved in favor of
|
||
coverage. For a particular product received by a particular user,
|
||
"normally used" refers to a typical or common use of that class of
|
||
product, regardless of the status of the particular user or of the
|
||
way in which the particular user actually uses, or expects or is
|
||
expected to use, the product. A product is a consumer product
|
||
regardless of whether the product has substantial commercial,
|
||
industrial or non-consumer uses, unless such uses represent the
|
||
only significant mode of use of the product.
|
||
|
||
"Installation Information" for a User Product means any methods,
|
||
procedures, authorization keys, or other information required to
|
||
install and execute modified versions of a covered work in that
|
||
User Product from a modified version of its Corresponding Source.
|
||
The information must suffice to ensure that the continued
|
||
functioning of the modified object code is in no case prevented or
|
||
interfered with solely because modification has been made.
|
||
|
||
If you convey an object code work under this section in, or with,
|
||
or specifically for use in, a User Product, and the conveying
|
||
occurs as part of a transaction in which the right of possession
|
||
and use of the User Product is transferred to the recipient in
|
||
perpetuity or for a fixed term (regardless of how the transaction
|
||
is characterized), the Corresponding Source conveyed under this
|
||
section must be accompanied by the Installation Information. But
|
||
this requirement does not apply if neither you nor any third party
|
||
retains the ability to install modified object code on the User
|
||
Product (for example, the work has been installed in ROM).
|
||
|
||
The requirement to provide Installation Information does not
|
||
include a requirement to continue to provide support service,
|
||
warranty, or updates for a work that has been modified or
|
||
installed by the recipient, or for the User Product in which it
|
||
has been modified or installed. Access to a network may be denied
|
||
when the modification itself materially and adversely affects the
|
||
operation of the network or violates the rules and protocols for
|
||
communication across the network.
|
||
|
||
Corresponding Source conveyed, and Installation Information
|
||
provided, in accord with this section must be in a format that is
|
||
publicly documented (and with an implementation available to the
|
||
public in source code form), and must require no special password
|
||
or key for unpacking, reading or copying.
|
||
|
||
7. Additional Terms.
|
||
|
||
"Additional permissions" are terms that supplement the terms of
|
||
this License by making exceptions from one or more of its
|
||
conditions. Additional permissions that are applicable to the
|
||
entire Program shall be treated as though they were included in
|
||
this License, to the extent that they are valid under applicable
|
||
law. If additional permissions apply only to part of the Program,
|
||
that part may be used separately under those permissions, but the
|
||
entire Program remains governed by this License without regard to
|
||
the additional permissions.
|
||
|
||
When you convey a copy of a covered work, you may at your option
|
||
remove any additional permissions from that copy, or from any part
|
||
of it. (Additional permissions may be written to require their own
|
||
removal in certain cases when you modify the work.) You may place
|
||
additional permissions on material, added by you to a covered work,
|
||
for which you have or can give appropriate copyright permission.
|
||
|
||
Notwithstanding any other provision of this License, for material
|
||
you add to a covered work, you may (if authorized by the copyright
|
||
holders of that material) supplement the terms of this License
|
||
with terms:
|
||
|
||
a. Disclaiming warranty or limiting liability differently from
|
||
the terms of sections 15 and 16 of this License; or
|
||
|
||
b. Requiring preservation of specified reasonable legal notices
|
||
or author attributions in that material or in the Appropriate
|
||
Legal Notices displayed by works containing it; or
|
||
|
||
c. Prohibiting misrepresentation of the origin of that material,
|
||
or requiring that modified versions of such material be
|
||
marked in reasonable ways as different from the original
|
||
version; or
|
||
|
||
d. Limiting the use for publicity purposes of names of licensors
|
||
or authors of the material; or
|
||
|
||
e. Declining to grant rights under trademark law for use of some
|
||
trade names, trademarks, or service marks; or
|
||
|
||
f. Requiring indemnification of licensors and authors of that
|
||
material by anyone who conveys the material (or modified
|
||
versions of it) with contractual assumptions of liability to
|
||
the recipient, for any liability that these contractual
|
||
assumptions directly impose on those licensors and authors.
|
||
|
||
All other non-permissive additional terms are considered "further
|
||
restrictions" within the meaning of section 10. If the Program as
|
||
you received it, or any part of it, contains a notice stating that
|
||
it is governed by this License along with a term that is a further
|
||
restriction, you may remove that term. If a license document
|
||
contains a further restriction but permits relicensing or
|
||
conveying under this License, you may add to a covered work
|
||
material governed by the terms of that license document, provided
|
||
that the further restriction does not survive such relicensing or
|
||
conveying.
|
||
|
||
If you add terms to a covered work in accord with this section, you
|
||
must place, in the relevant source files, a statement of the
|
||
additional terms that apply to those files, or a notice indicating
|
||
where to find the applicable terms.
|
||
|
||
Additional terms, permissive or non-permissive, may be stated in
|
||
the form of a separately written license, or stated as exceptions;
|
||
the above requirements apply either way.
|
||
|
||
8. Termination.
|
||
|
||
You may not propagate or modify a covered work except as expressly
|
||
provided under this License. Any attempt otherwise to propagate or
|
||
modify it is void, and will automatically terminate your rights
|
||
under this License (including any patent licenses granted under
|
||
the third paragraph of section 11).
|
||
|
||
However, if you cease all violation of this License, then your
|
||
license from a particular copyright holder is reinstated (a)
|
||
provisionally, unless and until the copyright holder explicitly
|
||
and finally terminates your license, and (b) permanently, if the
|
||
copyright holder fails to notify you of the violation by some
|
||
reasonable means prior to 60 days after the cessation.
|
||
|
||
Moreover, your license from a particular copyright holder is
|
||
reinstated permanently if the copyright holder notifies you of the
|
||
violation by some reasonable means, this is the first time you have
|
||
received notice of violation of this License (for any work) from
|
||
that copyright holder, and you cure the violation prior to 30 days
|
||
after your receipt of the notice.
|
||
|
||
Termination of your rights under this section does not terminate
|
||
the licenses of parties who have received copies or rights from
|
||
you under this License. If your rights have been terminated and
|
||
not permanently reinstated, you do not qualify to receive new
|
||
licenses for the same material under section 10.
|
||
|
||
9. Acceptance Not Required for Having Copies.
|
||
|
||
You are not required to accept this License in order to receive or
|
||
run a copy of the Program. Ancillary propagation of a covered work
|
||
occurring solely as a consequence of using peer-to-peer
|
||
transmission to receive a copy likewise does not require
|
||
acceptance. However, nothing other than this License grants you
|
||
permission to propagate or modify any covered work. These actions
|
||
infringe copyright if you do not accept this License. Therefore,
|
||
by modifying or propagating a covered work, you indicate your
|
||
acceptance of this License to do so.
|
||
|
||
10. Automatic Licensing of Downstream Recipients.
|
||
|
||
Each time you convey a covered work, the recipient automatically
|
||
receives a license from the original licensors, to run, modify and
|
||
propagate that work, subject to this License. You are not
|
||
responsible for enforcing compliance by third parties with this
|
||
License.
|
||
|
||
An "entity transaction" is a transaction transferring control of an
|
||
organization, or substantially all assets of one, or subdividing an
|
||
organization, or merging organizations. If propagation of a
|
||
covered work results from an entity transaction, each party to that
|
||
transaction who receives a copy of the work also receives whatever
|
||
licenses to the work the party's predecessor in interest had or
|
||
could give under the previous paragraph, plus a right to
|
||
possession of the Corresponding Source of the work from the
|
||
predecessor in interest, if the predecessor has it or can get it
|
||
with reasonable efforts.
|
||
|
||
You may not impose any further restrictions on the exercise of the
|
||
rights granted or affirmed under this License. For example, you
|
||
may not impose a license fee, royalty, or other charge for
|
||
exercise of rights granted under this License, and you may not
|
||
initiate litigation (including a cross-claim or counterclaim in a
|
||
lawsuit) alleging that any patent claim is infringed by making,
|
||
using, selling, offering for sale, or importing the Program or any
|
||
portion of it.
|
||
|
||
11. Patents.
|
||
|
||
A "contributor" is a copyright holder who authorizes use under this
|
||
License of the Program or a work on which the Program is based.
|
||
The work thus licensed is called the contributor's "contributor
|
||
version".
|
||
|
||
A contributor's "essential patent claims" are all patent claims
|
||
owned or controlled by the contributor, whether already acquired or
|
||
hereafter acquired, that would be infringed by some manner,
|
||
permitted by this License, of making, using, or selling its
|
||
contributor version, but do not include claims that would be
|
||
infringed only as a consequence of further modification of the
|
||
contributor version. For purposes of this definition, "control"
|
||
includes the right to grant patent sublicenses in a manner
|
||
consistent with the requirements of this License.
|
||
|
||
Each contributor grants you a non-exclusive, worldwide,
|
||
royalty-free patent license under the contributor's essential
|
||
patent claims, to make, use, sell, offer for sale, import and
|
||
otherwise run, modify and propagate the contents of its
|
||
contributor version.
|
||
|
||
In the following three paragraphs, a "patent license" is any
|
||
express agreement or commitment, however denominated, not to
|
||
enforce a patent (such as an express permission to practice a
|
||
patent or covenant not to sue for patent infringement). To
|
||
"grant" such a patent license to a party means to make such an
|
||
agreement or commitment not to enforce a patent against the party.
|
||
|
||
If you convey a covered work, knowingly relying on a patent
|
||
license, and the Corresponding Source of the work is not available
|
||
for anyone to copy, free of charge and under the terms of this
|
||
License, through a publicly available network server or other
|
||
readily accessible means, then you must either (1) cause the
|
||
Corresponding Source to be so available, or (2) arrange to deprive
|
||
yourself of the benefit of the patent license for this particular
|
||
work, or (3) arrange, in a manner consistent with the requirements
|
||
of this License, to extend the patent license to downstream
|
||
recipients. "Knowingly relying" means you have actual knowledge
|
||
that, but for the patent license, your conveying the covered work
|
||
in a country, or your recipient's use of the covered work in a
|
||
country, would infringe one or more identifiable patents in that
|
||
country that you have reason to believe are valid.
|
||
|
||
If, pursuant to or in connection with a single transaction or
|
||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||
covered work, and grant a patent license to some of the parties
|
||
receiving the covered work authorizing them to use, propagate,
|
||
modify or convey a specific copy of the covered work, then the
|
||
patent license you grant is automatically extended to all
|
||
recipients of the covered work and works based on it.
|
||
|
||
A patent license is "discriminatory" if it does not include within
|
||
the scope of its coverage, prohibits the exercise of, or is
|
||
conditioned on the non-exercise of one or more of the rights that
|
||
are specifically granted under this License. You may not convey a
|
||
covered work if you are a party to an arrangement with a third
|
||
party that is in the business of distributing software, under
|
||
which you make payment to the third party based on the extent of
|
||
your activity of conveying the work, and under which the third
|
||
party grants, to any of the parties who would receive the covered
|
||
work from you, a discriminatory patent license (a) in connection
|
||
with copies of the covered work conveyed by you (or copies made
|
||
from those copies), or (b) primarily for and in connection with
|
||
specific products or compilations that contain the covered work,
|
||
unless you entered into that arrangement, or that patent license
|
||
was granted, prior to 28 March 2007.
|
||
|
||
Nothing in this License shall be construed as excluding or limiting
|
||
any implied license or other defenses to infringement that may
|
||
otherwise be available to you under applicable patent law.
|
||
|
||
12. No Surrender of Others' Freedom.
|
||
|
||
If conditions are imposed on you (whether by court order,
|
||
agreement or otherwise) that contradict the conditions of this
|
||
License, they do not excuse you from the conditions of this
|
||
License. If you cannot convey a covered work so as to satisfy
|
||
simultaneously your obligations under this License and any other
|
||
pertinent obligations, then as a consequence you may not convey it
|
||
at all. For example, if you agree to terms that obligate you to
|
||
collect a royalty for further conveying from those to whom you
|
||
convey the Program, the only way you could satisfy both those
|
||
terms and this License would be to refrain entirely from conveying
|
||
the Program.
|
||
|
||
13. Use with the GNU Affero General Public License.
|
||
|
||
Notwithstanding any other provision of this License, you have
|
||
permission to link or combine any covered work with a work licensed
|
||
under version 3 of the GNU Affero General Public License into a
|
||
single combined work, and to convey the resulting work. The terms
|
||
of this License will continue to apply to the part which is the
|
||
covered work, but the special requirements of the GNU Affero
|
||
General Public License, section 13, concerning interaction through
|
||
a network will apply to the combination as such.
|
||
|
||
14. Revised Versions of this License.
|
||
|
||
The Free Software Foundation may publish revised and/or new
|
||
versions of the GNU General Public License from time to time.
|
||
Such new versions will be similar in spirit to the present
|
||
version, but may differ in detail to address new problems or
|
||
concerns.
|
||
|
||
Each version is given a distinguishing version number. If the
|
||
Program specifies that a certain numbered version of the GNU
|
||
General Public License "or any later version" applies to it, you
|
||
have the option of following the terms and conditions either of
|
||
that numbered version or of any later version published by the
|
||
Free Software Foundation. If the Program does not specify a
|
||
version number of the GNU General Public License, you may choose
|
||
any version ever published by the Free Software Foundation.
|
||
|
||
If the Program specifies that a proxy can decide which future
|
||
versions of the GNU General Public License can be used, that
|
||
proxy's public statement of acceptance of a version permanently
|
||
authorizes you to choose that version for the Program.
|
||
|
||
Later license versions may give you additional or different
|
||
permissions. However, no additional obligations are imposed on any
|
||
author or copyright holder as a result of your choosing to follow a
|
||
later version.
|
||
|
||
15. Disclaimer of Warranty.
|
||
|
||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
|
||
COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS"
|
||
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
|
||
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
|
||
RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
|
||
SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
||
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||
|
||
16. Limitation of Liability.
|
||
|
||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES
|
||
AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
|
||
THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
|
||
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
|
||
THE POSSIBILITY OF SUCH DAMAGES.
|
||
|
||
17. Interpretation of Sections 15 and 16.
|
||
|
||
If the disclaimer of warranty and limitation of liability provided
|
||
above cannot be given local legal effect according to their terms,
|
||
reviewing courts shall apply local law that most closely
|
||
approximates an absolute waiver of all civil liability in
|
||
connection with the Program, unless a warranty or assumption of
|
||
liability accompanies a copy of the Program in return for a fee.
|
||
|
||
|
||
END OF TERMS AND CONDITIONS
|
||
===========================
|
||
|
||
How to Apply These Terms to Your New Programs
|
||
=============================================
|
||
|
||
If you develop a new program, and you want it to be of the greatest
|
||
possible use to the public, the best way to achieve this is to make it
|
||
free software which everyone can redistribute and change under these
|
||
terms.
|
||
|
||
To do so, attach the following notices to the program. It is safest
|
||
to attach them to the start of each source file to most effectively
|
||
state the exclusion of warranty; and each file should have at least the
|
||
"copyright" line and a pointer to where the full notice is found.
|
||
|
||
ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
|
||
Copyright (C) YEAR NAME OF AUTHOR
|
||
|
||
This program is free software: you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
the Free Software Foundation, either version 3 of the License, or (at
|
||
your option) any later version.
|
||
|
||
This program is distributed in the hope that it will be useful, but
|
||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
General Public License for more details.
|
||
|
||
You should have received a copy of the GNU General Public License
|
||
along with this program. If not, see `http://www.gnu.org/licenses/'.
|
||
|
||
Also add information on how to contact you by electronic and paper
|
||
mail.
|
||
|
||
If the program does terminal interaction, make it output a short
|
||
notice like this when it starts in an interactive mode:
|
||
|
||
PROGRAM Copyright (C) YEAR NAME OF AUTHOR
|
||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||
This is free software, and you are welcome to redistribute it
|
||
under certain conditions; type `show c' for details.
|
||
|
||
The hypothetical commands `show w' and `show c' should show the
|
||
appropriate parts of the General Public License. Of course, your
|
||
program's commands might be different; for a GUI interface, you would
|
||
use an "about box".
|
||
|
||
You should also get your employer (if you work as a programmer) or
|
||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||
necessary. For more information on this, and how to apply and follow
|
||
the GNU GPL, see `http://www.gnu.org/licenses/'.
|
||
|
||
The GNU General Public License does not permit incorporating your
|
||
program into proprietary programs. If your program is a subroutine
|
||
library, you may consider it more useful to permit linking proprietary
|
||
applications with the library. If this is what you want to do, use the
|
||
GNU Lesser General Public License instead of this License. But first,
|
||
please read `http://www.gnu.org/philosophy/why-not-lgpl.html'.
|
||
|
||
|
||
File: m4.info, Node: Copying This Manual, Next: Indices, Prev: Copying This Package, Up: Top
|
||
|
||
Appendix B How to make copies of this manual
|
||
********************************************
|
||
|
||
This appendix covers the license for copying this manual. Note that
|
||
some of the longer examples in this manual are also distributed in the
|
||
directory `m4-1.4.13/examples/', where a more permissive license is in
|
||
effect when copying just the examples.
|
||
|
||
* Menu:
|
||
|
||
* GNU Free Documentation License:: License for copying this manual
|
||
|