summaryrefslogtreecommitdiff
path: root/doc/m4.info-2
diff options
context:
space:
mode:
Diffstat (limited to 'doc/m4.info-2')
-rw-r--r--doc/m4.info-21468
1 files changed, 1468 insertions, 0 deletions
diff --git a/doc/m4.info-2 b/doc/m4.info-2
new file mode 100644
index 00000000..aedf6a64
--- /dev/null
+++ b/doc/m4.info-2
@@ -0,0 +1,1468 @@
+This is Info file m4.info, produced by Makeinfo-1.55 from the input
+file m4.texinfo.
+
+START-INFO-DIR-ENTRY
+* m4: (m4). A powerful macro processor.
+END-INFO-DIR-ENTRY
+
+ This file documents the GNU `m4' utility.
+
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994 Free Software
+Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: m4.info, Node: Debug Output, Prev: Debug Levels, Up: Debugging
+
+Saving debugging output
+=======================
+
+ Debug and tracing output can be redirected to files using either the
+`-o' option to `m4', or with the builtin macro `debugfile':
+
+ debugfile(opt FILENAME)
+
+will send all further debug and trace output to FILENAME. If FILENAME
+is empty, debug and trace output are discarded and if `debugfile' is
+called without any arguments, debug and trace output are sent to the
+standard error output.
+
+
+File: m4.info, Node: Input Control, Next: File Inclusion, Prev: Debugging, Up: Top
+
+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 input until end of input
+
+
+File: m4.info, Node: Dnl, Next: Changequote, Prev: Input Control, Up: Input Control
+
+Deleting whitespace in input
+============================
+
+ The builtin `dnl' reads and discards all characters, up to and
+including the first newline:
+
+ dnl
+
+and it is often used in connection with `define', to remove the newline
+that follow 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.
+
+
+File: m4.info, Node: Changequote, Next: Changecom, Prev: Dnl, Up: Input Control
+
+Changing the quote characters
+=============================
+
+ The default quote delimiters can be changed with the builtin
+`changequote':
+
+ changequote(opt START, opt END)
+
+where START is the new start-quote delimiter and END is the new
+end-quote delimiter. If any of the arguments are missing, the default
+quotes (``' and `'') are used instead of the void arguments.
+
+ The expansion of `changequote' is void.
+
+ changequote([, ])
+ =>
+ define([foo], [Macro [foo].])
+ =>
+ foo
+ =>Macro foo.
+
+ If no single character is appropriate, START and END can be of any
+length.
+
+ changequote([[, ]])
+ =>
+ define([[foo]], [[Macro [[[foo]]].]])
+ =>
+ foo
+ =>Macro [foo].
+
+ Changing the quotes to the empty strings will effectively disable the
+quoting mechanism, leaving no way to quote text.
+
+ define(`foo', `Macro `FOO'.')
+ =>
+ changequote(, )
+ =>
+ foo
+ =>Macro `FOO'.
+ `foo'
+ =>`Macro `FOO'.'
+
+ There is no way in `m4' to quote a string containing an unmatched
+left quote, except using `changequote' to change the current quotes.
+
+ Neither quote string should start with a letter or `_' (underscore),
+as they will be confused with names in the input. Doing so disables
+the quoting mechanism.
+
+
+File: m4.info, Node: Changecom, Next: Changeword, Prev: Changequote, Up: Input Control
+
+Changing comment delimiters
+===========================
+
+ The default comment delimiters can be changed with the builtin macro
+`changecom':
+
+ changecom(opt START, opt END)
+
+where START is the new start-comment delimiter and END is the new
+end-comment delimiter. If any of the arguments are void, the default
+comment delimiters (`#' and newline) are used instead of the void
+arguments. 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 start comment delimiter.
+
+ Calling `changecom' without any arguments disables the commenting
+mechanism completely.
+
+ define(`comment', `COMMENT')
+ =>
+ changecom
+ =>
+ # Not a comment anymore
+ =># Not a COMMENT anymore
+
+
+File: m4.info, Node: Changeword, Next: M4wrap, Prev: Changecom, Up: Input Control
+
+Changing the lexical structure of words
+=======================================
+
+ The macro `changeword' and all associated functionnality is
+ experimental. It is only available if the `--enable-changeword'
+ option was given to `configure', at GNU `m4' installation time.
+ The functionnality might change or even go away in the future.
+ *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. Relaxing
+`m4''s lexical rules might be useful (for example) if you wanted to
+apply translations to a file of numbers:
+
+ changeword(`[_a-zA-Z0-9]+')
+ define(1, 0)
+ =>1
+
+ 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:
+
+ define(`_indir', defn(`indir'))
+ changeword(`_[_a-zA-Z0-9]*')
+ esyscmd(foo)
+ _indir(`esyscmd', `ls')
+
+ 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'.
+
+ `changeword' has another function. If the regular expression
+supplied contains any bracketed subexpressions, then text outside the
+first of these is discarded before symbol lookup. So:
+
+ changecom(`/*', `*/')
+ changeword(`#\([_a-zA-Z0-9]*\)')
+ #esyscmd(ls)
+
+ `m4' now requires a `#' mark at the beginning of every macro
+invocation, so one can use `m4' to preprocess shell scripts without
+getting `shift' commands swallowed, and plain text without losing
+various common words.
+
+ `m4''s macro substitution is based on text, while TeX's 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
+
+Then, the `m4' version:
+
+ define(a, `errprint(`Hello')')
+ changeword(`@\([_a-zA-Z0-9]*\)')
+ =>@a
+
+ 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.
+
+
+File: m4.info, Node: M4wrap, Prev: Changeword, Up: Input Control
+
+Saving 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':
+
+ m4wrap(STRING, ...)
+
+which stores STRING and the rest of the arguments in a safe place, to
+be reread when end of input is reached.
+
+ define(`cleanup', `This is the `cleanup' actions.
+ ')
+ =>
+ 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 actions.
+
+ 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).
+
+
+File: m4.info, Node: File Inclusion, Next: Diversions, Prev: Input Control, Up: Top
+
+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, Prev: File Inclusion, Up: File Inclusion
+
+Including named files
+=====================
+
+ There are two builtin macros in `m4' for including files:
+
+ include(FILENAME)
+ sinclude(FILENAME)
+
+both of which cause the file named FILENAME 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 FILENAME.
+
+ It is an error for an `include'd file not to exist. If you do not
+want error messages about non-existent files, `sinclude' can be used to
+include a file, if it exists, expanding to nothing if it does not.
+
+ include(`no-such-file')
+ =>
+ error-->30.include:2: m4: Cannot open no-such-file: No such file or directory
+ sinclude(`no-such-file')
+ =>
+
+ Assume in the following that the file `incl.m4' contains the lines:
+ 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:
+
+ 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':
+
+ 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.
+
+ The builtin macros `include' and `sinclude' are recognized only when
+given arguments.
+
+
+File: m4.info, Node: Search Path, Prev: Include, Up: File Inclusion
+
+Searching for include files
+===========================
+
+ GNU `m4' allows included files to be found in other directories than
+the current working directory.
+
+ If a file is not found in the current working directory, and the file
+name is not absolute, the file will be looked for in a specified search
+path. First, the directories specified with the `-I' option will be
+searched, in the order found on the command line. Second, 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
+
+Diverting and undiverting output
+********************************
+
+ Diversions are a way of temporarily saving output. The output of
+`m4' can at any time be diverted to a temporary file, and be reinserted
+into the output stream, "undiverted", again at a later time.
+
+ Numbered diversions are counted from 0 upwards, diversion number 0
+being the normal output stream. The number of simultaneous diversions
+is limited mainly by the memory used to describe them, because GNU `m4'
+tries to keep diversions in memory. However, there is a limit to the
+overall memory usable by all diversions taken altogether (512K,
+currently). When this maximum is about to be exceeded, a temporary
+file is opened to receive the contents of the biggest diversion still
+in memory, freeing this memory for other diversions. So, it is
+theoretically possible that the number of diversions be limited by the
+number of available file descriptors.
+
+* Menu:
+
+* Divert:: Diverting output
+* Undivert:: Undiverting output
+* Divnum:: Diversion numbers
+* Cleardiv:: Discarding diverted text
+
+
+File: m4.info, Node: Divert, Next: Undivert, Prev: Diversions, Up: Diversions
+
+Diverting output
+================
+
+ Output is diverted using `divert':
+
+ divert(opt NUMBER)
+
+where NUMBER is the diversion to be used. If NUMBER is left out, it is
+assumed to be zero.
+
+ 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.
+
+ If output is diverted to a non-existent 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 how to avoid them.
+
+ divert(-1)
+ define(`foo', `Macro `foo'.')
+ define(`bar', `Macro `bar'.')
+ divert
+ =>
+
+ This is a common programming idiom in `m4'.
+
+
+File: m4.info, Node: Undivert, Next: Divnum, Prev: Divert, Up: Diversions
+
+Undiverting output
+==================
+
+ Diverted text can be undiverted explicitly using the builtin
+`undivert':
+
+ undivert(opt NUMBER, ...)
+
+which undiverts the diversions given by the arguments, in the order
+given. If no arguments are supplied, all diversions are undiverted, in
+numerical order.
+
+ 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.
+
+ 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.
+
+ 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 the word `bar':
+
+ define(`bar', `BAR')
+ =>
+ undivert(`foo')
+ =>bar
+ =>
+ include(`foo')
+ =>BAR
+ =>
+
+
+File: m4.info, Node: Divnum, Next: Cleardiv, Prev: Undivert, Up: Diversions
+
+Diversion numbers
+=================
+
+ The builtin `divnum':
+
+ divnum
+
+expands to the number of the current diversion.
+
+ Initial divnum
+ =>Initial 0
+ divert(1)
+ Diversion one: divnum
+ divert(2)
+ Diversion two: divnum
+ divert
+ =>
+ ^D
+ =>
+ =>Diversion one: 1
+ =>
+ =>Diversion two: 2
+
+ The last call of `divert' without argument is necessary, since the
+undiverted text would otherwise be diverted itself.
+
+
+File: m4.info, Node: Cleardiv, Prev: Divnum, Up: Diversions
+
+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:
+
+ define(`cleardivert',
+ `pushdef(`_num', divnum)divert(-1)undivert($@)divert(_num)popdef(`_num')')
+ =>
+
+ 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.)
+
+
+File: m4.info, Node: Text handling, Next: Arithmetic, Prev: Diversions, Up: Top
+
+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:: 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, Prev: Text handling, Up: Text handling
+
+Calculating length of strings
+=============================
+
+ The length of a string can be calculated by `len':
+
+ len(STRING)
+
+which expands to the length of STRING, as a decimal number.
+
+ len()
+ =>0
+ len(`abcdef')
+ =>6
+
+ The builtin macro `len' is recognized only when given arguments.
+
+
+File: m4.info, Node: Index, Next: Regexp, Prev: Len, Up: Text handling
+
+Searching for substrings
+========================
+
+ Searching for substrings is done with `index':
+
+ index(STRING, SUBSTRING)
+
+which 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'.
+
+ index(`gnus, gnats, and armadillos', `nat')
+ =>7
+ index(`gnus, gnats, and armadillos', `dag')
+ =>-1
+
+ The builtin macro `index' is recognized only when given arguments.
+
+
+File: m4.info, Node: Regexp, Next: Substr, Prev: Index, Up: Text handling
+
+Searching for regular expressions
+=================================
+
+ Searching for regular expressions is done with the builtin `regexp':
+
+ regexp(STRING, REGEXP, opt REPLACEMENT)
+
+which searches for REGEXP in STRING. The syntax for regular
+expressions is the same as in GNU Emacs. *Note Syntax of Regular
+Expressions: (emacs)Regexps.
+
+ 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.
+
+ regexp(`GNUs not Unix', `\<[a-z]\w+')
+ =>5
+ regexp(`GNUs not Unix', `\<Q\w*')
+ =>-1
+
+ If REPLACEMENT is supplied, `regexp' changes the expansion to this
+argument, with `\N' substituted by the text matched by the Nth
+parenthesized sub-expression of REGEXP, `\&' being the text the entire
+regular expression matched.
+
+ regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
+ =>*** Unix *** nix ***
+
+ The builtin macro `regexp' is recognized only when given arguments.
+
+
+File: m4.info, Node: Substr, Next: Translit, Prev: Regexp, Up: Text handling
+
+Extracting substrings
+=====================
+
+ Substrings are extracted with `substr':
+
+ substr(STRING, FROM, opt LENGTH)
+
+which 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.
+
+ substr(`gnus, gnats, and armadillos', 6)
+ =>gnats, and armadillos
+ substr(`gnus, gnats, and armadillos', 6, 5)
+ =>gnats
+
+ The builtin macro `substr' is recognized only when given arguments.
+
+
+File: m4.info, Node: Translit, Next: Patsubst, Prev: Substr, Up: Text handling
+
+Translating characters
+======================
+
+ Character translation is done with `translit':
+
+ translit(STRING, CHARS, REPLACEMENT)
+
+which 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 are
+deleted from the expansion. If REPLACEMENT is omitted, all characters
+in STRING, that are present in CHARS are deleted from the expansion.
+
+ 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.
+
+ 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'.
+
+ 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
+
+ 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.
+
+ The builtin macro `translit' is recognized only when given arguments.
+
+
+File: m4.info, Node: Patsubst, Next: Format, Prev: Translit, Up: Text handling
+
+Substituting text by regular expression
+=======================================
+
+ Global substitution in a string is done by `patsubst':
+
+ patsubst(STRING, REGEXP, opt REPLACEMENT)
+
+which searches STRING for matches of REGEXP, and substitutes
+REPLACEMENT for each match. The syntax for regular expressions is the
+same as in GNU Emacs.
+
+ 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 REGEXP, `\&' being the text the entire
+regular expression matched.
+
+ The REPLACEMENT argument can be omitted, in which case the text
+matched by REGEXP is deleted.
+
+ 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
+
+ Here is a slightly more realistic example, which capitalizes
+individual word or whole sentences, by substituting calls of the macros
+`upcase' and `downcase' into the strings.
+
+ define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
+ define(`downcase', `translit(`$*', `A-Z', `a-z')')dnl
+ define(`capitalize1',
+ `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')dnl
+ define(`capitalize',
+ `patsubst(`$1', `\w+', `capitalize1(`\&')')')dnl
+ capitalize(`GNUs not Unix')
+ =>Gnus Not Unix
+
+ The builtin macro `patsubst' is recognized only when given arguments.
+
+
+File: m4.info, Node: Format, Prev: Patsubst, Up: Text handling
+
+Formatted output
+================
+
+ Formatted output can be made with `format':
+
+ format(FORMAT-STRING, ...)
+
+which works much like the C function `printf'. The first argument is a
+format string, which can contain `%' specifications, and the expansion
+of `format' is the formatted string.
+
+ Its use is best described by a few examples:
+
+ define(`foo', `The brown fox jumped over the lazy dog')
+ =>
+ format(`The string "%s" is %d characters long', foo, len(foo))
+ =>The string "The brown fox jumped over the lazy dog" is 38 characters long
+
+ Using the `forloop' macro defined in *Note Loops::, this example
+shows how `format' can be used to produce tabular output.
+
+ 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 the normal `%' specifiers: `c', `s', `d', `o', `x', `X',
+`u', `e', `E' and `f'; it supports field widths and precisions, and the
+modifiers `+', `-', ` ', `0', `#', `h' and `l'. For more details on
+the functioning of `printf', see the C Library Manual.
+
+
+File: m4.info, Node: Arithmetic, Next: UNIX commands, Prev: Text handling, Up: Top
+
+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, Prev: Arithmetic, Up: Arithmetic
+
+Decrement and increment operators
+=================================
+
+ Increment and decrement of integers are supported using the builtins
+`incr' and `decr':
+
+ incr(NUMBER)
+ decr(NUMBER)
+
+which expand to the numerical value of NUMBER, incremented, or
+decremented, respectively, by one.
+
+ incr(4)
+ =>5
+ decr(7)
+ =>6
+
+ The builtin macros `incr' and `decr' are recognized only when given
+arguments.
+
+
+File: m4.info, Node: Eval, Prev: Incr, Up: Arithmetic
+
+Evaluating integer expressions
+==============================
+
+ Integer expressions are evaluated with `eval':
+
+ eval(EXPRESSION, opt RADIX, opt WIDTH)
+
+which expands to the value of EXPRESSION.
+
+ Expressions can contain the following operators, listed in order of
+decreasing precedence.
+
+`-'
+ Unary minus
+
+`**'
+ Exponentiation
+
+`* / %'
+ Multiplication, division and modulo
+
+`+ -'
+ Addition and subtraction
+
+`<< >>'
+ Shift left or right
+
+`== != > >= < <='
+ Relational operators
+
+`!'
+ Logical negation
+
+`~'
+ Bitwise negation
+
+`&'
+ Bitwise and
+
+`^'
+ Bitwise exclusive-or
+
+`|'
+ Bitwise or
+
+`&&'
+ Logical and
+
+`||'
+ Logical or
+
+ All operators, except exponentiation, are left associative.
+
+ Note that many `m4' implementations use `^' as an alternate operator
+for the exponentiation, while many others use `^' for the bitwise
+exclusive-or. GNU `m4' changed its behavior: it used to exponentiate
+for `^', it now computes the bitwise exclusive-or.
+
+ Numbers without special prefix are given decimal. A simple `0'
+prefix introduces an octal number. `0x' introduces an hexadecimal
+number. `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 any radix, 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(index(`Hello world', `llo') >= 0)
+ =>1
+ define(`square', `eval(($1)**2)')
+ =>
+ square(9)
+ =>81
+ square(square(5)+1)
+ =>676
+ define(`foo', `666')
+ =>
+ eval(`foo'/6)
+ error-->51.eval:14: m4: Bad expression in eval: foo/6
+ =>
+ eval(foo/6)
+ =>111
+
+ As the second to last example shows, `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'.
+
+ If RADIX is specified, it specifies the radix to be used in the
+expansion. The default radix is 10. The result of `eval' is always
+taken to be signed. The WIDTH argument specifies a minimum output
+width. The result is zero-padded to extend the expansion to the
+requested width.
+
+ eval(666, 10)
+ =>666
+ eval(666, 11)
+ =>556
+ eval(666, 6)
+ =>3030
+ eval(666, 6, 10)
+ =>0000003030
+ eval(-666, 6, 10)
+ =>-000003030
+
+ Take note that RADIX cannot be larger than 36.
+
+ The builtin macro `eval' is recognized only when given arguments.
+
+
+File: m4.info, Node: UNIX commands, Next: Miscellaneous, Prev: Arithmetic, Up: Top
+
+Running UNIX commands
+*********************
+
+ There are a few builtin macros in `m4' that allow you to run UNIX
+commands from within `m4'.
+
+* Menu:
+
+* Syscmd:: Executing simple commands
+* Esyscmd:: Reading the output of commands
+* Sysval:: Exit codes
+* Maketemp:: Making names for temporary files
+
+
+File: m4.info, Node: Syscmd, Next: Esyscmd, Prev: UNIX commands, Up: UNIX commands
+
+Executing simple commands
+=========================
+
+ Any shell command can be executed, using `syscmd':
+
+ syscmd(SHELL-COMMAND)
+
+which 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 output buffers.
+The default standard input, output and error of SHELL-COMMAND are the
+same as those of `m4'.
+
+ The builtin macro `syscmd' is recognized only when given arguments.
+
+
+File: m4.info, Node: Esyscmd, Next: Sysval, Prev: Syscmd, Up: UNIX commands
+
+Reading the output of commands
+==============================
+
+ If you want `m4' to read the output of a UNIX command, use `esyscmd':
+
+ esyscmd(SHELL-COMMAND)
+
+which expands to the standard output of the shell command SHELL-COMMAND.
+
+ Prior to executing the command, `m4' flushes its output buffers.
+The default standard input and error output 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'.
+
+ Assume you are positioned into the `checks' directory of GNU `m4'
+distribution, then:
+
+ define(`vice', `esyscmd(grep Vice ../COPYING)')
+ =>
+ vice
+ => Ty Coon, President of Vice
+ =>
+
+ Note how the expansion of `esyscmd' has a trailing newline.
+
+ The builtin macro `esyscmd' is recognized only when given arguments.
+
+
+File: m4.info, Node: Sysval, Next: Maketemp, Prev: Esyscmd, Up: UNIX commands
+
+Exit codes
+==========
+
+ To see whether a shell command succeeded, use `sysval':
+
+ sysval
+
+which expands to the exit status of the last shell command run with
+`syscmd' or `esyscmd'.
+
+ syscmd(`false')
+ =>
+ ifelse(sysval, 0, zero, non-zero)
+ =>non-zero
+ syscmd(`true')
+ =>
+ sysval
+ =>0
+
+
+File: m4.info, Node: Maketemp, Prev: Sysval, Up: UNIX commands
+
+Making names for 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,
+`maketemp', for making temporary file names:
+
+ maketemp(TEMPLATE)
+
+which expands to a name of a non-existent file, made from the string
+TEMPLATE, which should end with the string `XXXXXX'. The six `X''s are
+then replaced, usually with something that includes the process id of
+the `m4' process, in order to make the filename unique.
+
+ maketemp(`/tmp/fooXXXXXX')
+ =>/tmp/fooa07346
+ maketemp(`/tmp/fooXXXXXX')
+ =>/tmp/fooa07346
+
+ As seen in the example, several calls of `maketemp' might expand to
+the same string, since the selection criteria is whether the file exists
+or not. If a file has not been created before the next call, the two
+macro calls might expand to the same name.
+
+ The builtin macro `maketemp' is recognized only when given arguments.
+
+
+File: m4.info, Node: Miscellaneous, Next: Frozen files, Prev: UNIX commands, Up: Top
+
+Miscellaneous builtin macros
+****************************
+
+ This chapter describes various builtins, that do not really belong in
+any of the previous chapters.
+
+* Menu:
+
+* Errprint:: Printing error messages
+* M4exit:: Exiting from m4
+
+
+File: m4.info, Node: Errprint, Next: M4exit, Prev: Miscellaneous, Up: Miscellaneous
+
+Printing error messages
+=======================
+
+ You can print error messages using `errprint':
+
+ errprint(MESSAGE, ...)
+
+which simply prints MESSAGE and the rest of the arguments on the
+standard error output.
+
+ The expansion of `errprint' is void.
+
+ errprint(`Illegal arguments to forloop
+ ')
+ error-->Illegal arguments to forloop
+ =>
+
+ A trailing newline is *not* printed automatically, so it must be
+supplied as part of the argument, as in the example. (BSD flavored
+`m4''s do append a trailing newline on each `errprint' call).
+
+ To make it possible to specify the location of the error, two
+utility builtins exist:
+
+ __file__
+ __line__
+
+which expands to the quoted name of the current input file, and the
+current input line number in that file.
+
+ errprint(`m4:'__file__:__line__: `Input error
+ ')
+ error-->m4:56.errprint:2: Input error
+ =>
+
+
+File: m4.info, Node: M4exit, Prev: Errprint, Up: Miscellaneous
+
+Exiting from `m4'
+=================
+
+ If you need to exit from `m4' before the entire input has been read,
+you can use `m4exit':
+
+ m4exit(opt CODE)
+
+which causes `m4' to exit, with exit code CODE. If CODE is left out,
+the exit code is zero.
+
+ define(`fatal_error', `errprint(`m4: '__file__: __line__`: fatal error: $*
+ ')m4exit(1)')
+ =>
+ fatal_error(`This is a BAD one, buster')
+ error-->m4: 57.m4exit: 5: fatal error: This is a BAD one, buster
+
+ After this macro call, `m4' will exit with exit code 1. This macro
+is only intended for error exits, since the normal exit procedures are
+not followed, e.g., diverted text is not undiverted, and saved text
+(*note M4wrap::.) is not reread.
+
+
+File: m4.info, Node: Frozen files, Next: Compatibility, Prev: Miscellaneous, Up: Top
+
+Fast loading of frozen states
+*****************************
+
+ 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, `include''d from this input file.
+
+ 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. Presume the user
+repeatedly uses:
+
+ m4 base.m4 input.m4
+
+with a varying contents of `input.m4', but a rather fixed contents for
+`base.m4'. Then, the user might rather execute:
+
+ m4 -F base.m4f base.m4
+
+once, and further execute, as often as needed:
+
+ m4 -R base.m4f input.m4
+
+with the varying input. The first call, containing the `-F' option,
+only reads and executes file `base.m4', so defining various application
+macros and computing other initializations. Only once the input file
+`base.m4' has been completely processed, GNU `m4' produces on
+`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''s memory, from `base.m4f', *prior* to reading
+any other input files. By this mean, 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'. Also,
+interactions for some options of `m4' being used in one call and not
+for the next, have not been fully analyzed yet. On the other end, you
+may be confident that stacks of `pushdef''ed definitions are handled
+correctly, so are `undefine''d or renamed builtins, changed strings for
+quotes or comments.
+
+ 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::.).
+
+ Frozen files are sharable across architectures. It is safe to write
+a frozen file one one machine and read it on another, given that the
+second machine uses the same, or a newer version of GNU `m4'. 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. In the following descriptions, LENGTHs
+always refer to corresponding STRINGs. Numbers are always expressed in
+decimal. The directives are:
+
+`V NUMBER NL'
+ Confirms the format of the file. NUMBER should be 1.
+
+`C LENGTH1 , LENGTH2 NL STRING1 STRING2 NL'
+ Uses STRING1 and STRING2 as the beginning comment and end comment
+ strings.
+
+`Q LENGTH1 , LENGTH2 NL STRING1 STRING2 NL'
+ Uses STRING1 and STRING2 as the beginning quote and end quote
+ strings.
+
+`F LENGTH1 , LENGTH2 NL STRING1 STRING2 NL'
+ Defines, through `pushdef', a definition for STRING1 expanding to
+ the function whose builtin name is STRING2.
+
+`T LENGTH1 , LENGTH2 NL STRING1 STRING2 NL'
+ Defines, though `pushdef', a definition for STRING1 expanding to
+ the text given by STRING2.
+
+`D NUMBER, LENGTH NL STRING NL'
+ Selects diversion NUMBER, making it current, then copy STRING 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 STRING. With 0 as the diversion
+ NUMBER, STRING will be issued on standard output at reload time,
+ however this may not be produced from within `m4'.
+
+
+File: m4.info, Node: Compatibility, Next: Concept index, Prev: Frozen files, Up: Top
+
+Compatibility with other versions of `m4'
+*****************************************
+
+ This chapter describes the differences between this implementation of
+`m4', and the implementation found under UNIX, notably System V,
+Release 3.
+
+ There are also differences in BSD flavors of `m4'. No attempt is
+made to summarize these here.
+
+* Menu:
+
+* Extensions:: Extensions in GNU m4
+* Incompatibilities:: Facilities in System V m4 not in GNU m4
+* Other Incompat:: Other incompatibilities
+
+
+File: m4.info, Node: Extensions, Next: Incompatibilities, Prev: Compatibility, Up: Compatibility
+
+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, 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::.).
+
+ * 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 regular expressions are
+ supported by the `regexp' (*note Regexp::.) and `patsubst' (*note
+ Patsubst::.) builtins.
+
+ * 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 current input file and the current input line
+ number are accessible through the builtins `__file__' and
+ `__line__' (*note Errprint::.).
+
+ * 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::.).
+
+ In addition to the above extensions, GNU `m4' implements the
+following command line options: `-F', `-G', `-I', `-L', `-R', `-V',
+`-W', `-d', `-l', `-o' and `-t'. *Note Invoking m4::, for a
+description of these options.
+
+ Also, 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 Incompat, Prev: Extensions, Up: Compatibility
+
+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.
+
+ * System V `m4' supports multiple arguments to `defn'. This is not
+ implemented in GNU `m4'. Its usefulness is unclear to me.
+
+
+File: m4.info, Node: Other Incompat, Prev: Incompatibilities, Up: Compatibility
+
+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 filenames 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.
+
+ I expect the sync line option to be 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 were made, and not where it was inserted again.
+
+ * GNU `m4' makes no attempt at prohiting autoreferential 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. 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 leave 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.
+
+ * GNU `m4' without `-G' option will define the macro `__gnu__' to
+ expand to the empty string.
+
+ On UNIX systems, GNU `m4' without the `-G' option will define the
+ macro `__unix__', otherwise the macro `unix'. Both will expand to
+ the empty string.
+