summaryrefslogtreecommitdiff
path: root/doc/m4.info-1
diff options
context:
space:
mode:
Diffstat (limited to 'doc/m4.info-1')
-rw-r--r--doc/m4.info-17858
1 files changed, 7858 insertions, 0 deletions
diff --git a/doc/m4.info-1 b/doc/m4.info-1
new file mode 100644
index 0000000..e1a6138
--- /dev/null
+++ b/doc/m4.info-1
@@ -0,0 +1,7858 @@
+This is m4.info, produced by makeinfo version 4.13 from m4.texinfo.
+
+This manual (28 February 2011) is for GNU M4 (version 1.4.16), a
+package containing an implementation of the m4 macro language.
+
+ Copyright (C) 1989-1994, 2004-2011 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.3 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 (28 February 2011) is for GNU M4 (version 1.4.16), a
+package containing an implementation of the m4 macro language.
+
+ Copyright (C) 1989-1994, 2004-2011 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.3 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.16/AUTHORS'
+and `m4-1.4.16/THANKS' from the GNU M4 distribution.
+
+ This is release 1.4.16. 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, 1.4.13 in
+2009, 1.4.14 and 1.4.15 in 2010, and 1.4.16 in 2011.
+
+ 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.16
+
+ 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. It also adds another layer of quoting to the first argument of
+`translit', to ensure that the output will be rescanned as a string
+rather than a potential uppercase macro name needing further expansion.
+
+ 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 a string, the quotes
+are stripped and the only output is a literal `STRCASE'. 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.16/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.16/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.16/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.16/examples/foreach.m4', and `foreachq' in
+`m4-1.4.16/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.16/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.16/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.16/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.16/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.16/examples' directory shipped as part of the GNU `m4' package.
+The file `m4-1.4.16/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. GNU `m4' tries to keep diversions in
+memory. However, there is a limit to the overall memory usable by all
+diversions taken together (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'. Thus, the amount of available disk space provides the only
+real limit on the number and aggregate size of diversions.
+
+ 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.16/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(`echo dnl && exit 127')
+ =>
+ sysval
+ =>127
+ 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, unless there was output from the child process.
+
+ 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.16 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.16/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.16/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.16/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.16/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.16/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.16/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.16/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.16/examples/capitalize2.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.16/examples/', where a more permissive license is in
+effect when copying just the examples.
+
+* Menu:
+
+* GNU Free Documentation License:: License for copying this manual
+