summaryrefslogtreecommitdiff
path: root/doc/m4.texinfo
diff options
context:
space:
mode:
Diffstat (limited to 'doc/m4.texinfo')
-rw-r--r--doc/m4.texinfo120
1 files changed, 73 insertions, 47 deletions
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
index 00cff97a..98eba85d 100644
--- a/doc/m4.texinfo
+++ b/doc/m4.texinfo
@@ -394,9 +394,11 @@ addressed some long standing bugs in the venerable 1.4 release. Then in
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. In 2008, Eric additionally rewrote the scanning engine to
-reduce recursive evaluation from quadratic to linear complexity for
-1.4.11. The 1.4.x branch remains open for bug fixes.
+1.4.10, closing the series with 1.4.11 in 2008.
+
+Additionally, in 2008, Eric rewrote the scanning engine to reduce
+recursive evaluation from quadratic to linear complexity, released as M4
+1.6. The 1.x branch series remains open for bug fixes.
Meanwhile, development has continued on new features for @code{m4}, such
as dynamic module loading and additional builtins. When complete,
@@ -2217,7 +2219,7 @@ defn([l], [r])
Using @code{defn} to generate special tokens for builtin macros will
generate a warning in contexts where a macro name is expected. But in
contexts that operate on text, the builtin token is just silently
-converted to an empty string. As of M4 1.4.11, expansion of user macros
+converted to an empty string. As of M4 1.6, expansion of user macros
will also preserve builtin tokens. However, any use of builtin tokens
outside of the second argument to @code{define} and @code{pushdef} is
generally not portable, since earlier @acronym{GNU} M4 versions, as well
@@ -2278,10 +2280,11 @@ bar
@result{}0
@end example
-Also note that @code{defn} with multiple arguments can only join text
-macros, not builtins. Likewise, when collecting macro arguments, a
-builtin token is preserved only when it occurs in isolation. A future
-version of @acronym{GNU} M4 may lift these restrictions.
+Also note that as of M4 1.6, @code{defn} with multiple arguments can
+join text with builtin tokens. However, when collecting macro
+arguments, a builtin token is preserved only when it occurs in
+isolation. A future version of @acronym{GNU} M4 may lift this
+restriction.
@example
$ @kbd{m4 -d}
@@ -2290,13 +2293,12 @@ define(`a', `A')define(`AA', `b')
traceon(`defn', `define')
@result{}
defn(`a', `divnum', `a')
-@error{}m4:stdin:3: Warning: defn: cannot concatenate builtin `divnum'
-@error{}m4trace: -1- defn(`a', `divnum', `a') -> ``A'`A''
+@error{}m4trace: -1- defn(`a', `divnum', `a') -> ``A'<divnum>`A''
@result{}AA
define(`mydivnum', defn(`divnum', `divnum'))mydivnum
-@error{}m4:stdin:4: Warning: defn: cannot concatenate builtin `divnum'
-@error{}m4:stdin:4: Warning: defn: cannot concatenate builtin `divnum'
-@error{}m4trace: -2- defn(`divnum', `divnum')
+@error{}m4trace: -2- defn(`divnum', `divnum') -> `<divnum><divnum>'
+@error{}m4:stdin:4: Warning: define: cannot concatenate builtin `divnum'
+@error{}m4:stdin:4: Warning: define: cannot concatenate builtin `divnum'
@error{}m4trace: -1- define(`mydivnum', `')
@result{}
traceoff(`defn', `define')
@@ -2314,10 +2316,10 @@ define(`mydivnum', `a'defn(`divnum'))mydivnum
define(`q', ``$@@'')
@result{}
define(`foo', q(`a', defn(`divnum')))foo
-@error{}m4:stdin:10: Warning: define: cannot quote builtin
-@result{}a,
+@error{}m4:stdin:10: Warning: define: cannot concatenate builtins
+@result{}foo
ifdef(`foo', `yes', `no')
-@result{}yes
+@result{}no
@end example
@node Pushdef
@@ -2665,7 +2667,7 @@ ifdef(`no_such_macro', `yes', `no', `extra argument')
@result{}no
@end example
-As of M4 1.4.11, @code{ifdef} transparently handles builtin tokens
+As of M4 1.6, @code{ifdef} transparently handles builtin tokens
generated by @code{defn} (@pxref{Defn}) that occur in either
@var{string}, although a warning is issued for invalid macro names.
@@ -2781,7 +2783,7 @@ ifelse(`foo', `bar', `3', `gnu', `gnats', `6', `7', `8')
@result{}7
@end example
-As of M4 1.4.11, @code{ifelse} transparently handles builtin tokens
+As of M4 1.6, @code{ifelse} transparently handles builtin tokens
generated by @code{defn} (@pxref{Defn}). Because of this, it is always
safe to compare two macro definitions, without worrying whether the
macro might be a builtin.
@@ -2857,8 +2859,8 @@ ifelse(`-01234567890123456789', `-'e(long)`-', `yes', `no')
@result{}no
@end example
-@comment It would be nice to pass builtin tokens through m4wrap, as well
-@comment as allowing concatenation of builtins in ifelse and user macros.
+@comment It would be nice to allow concatenation of builtins without
+@comment using $@ handling.
@example
define(`e', `$@@')define(`q', ``$@@'')define(`u', `$*')
@result{}
@@ -2878,33 +2880,25 @@ cmp(`q(defn(`defn'))', `q(`<defn>')')-fixme
cmp(`q(defn(`defn'))', ``'')-fixme
@error{}m4:stdin:7: Warning: ifelse: cannot quote builtin
@result{}no-fixme
-cmp(`q(`1', `2', defn(`defn'))', `q(`1', `2', defn(`d'))')-fixme
-@error{}m4:stdin:8: Warning: ifelse: cannot quote builtin
-@error{}m4:stdin:8: Warning: ifelse: cannot quote builtin
-@result{}yes-fixme
-cmp(`q(`1', `2', defn(`defn'))', `q(`1', `2', `<defn>')')-fixme
-@error{}m4:stdin:9: Warning: ifelse: cannot quote builtin
-@result{}no-fixme
-cmp(`q(`1', `2', defn(`defn'))', ```1',`2',<defn>'')-fixme
-@error{}m4:stdin:10: Warning: ifelse: cannot quote builtin
-@result{}no-fixme
-cmp(`q(`1', `2', defn(`defn'))', ```1',`2',`''')-fixme
-@error{}m4:stdin:11: Warning: ifelse: cannot quote builtin
-@result{}yes-fixme
+cmp(`q(`1', `2', defn(`defn'))', `q(`1', `2', defn(`d'))')
+@result{}yes
+cmp(`q(`1', `2', defn(`defn'))', `q(`1', `2', `<defn>')')
+@result{}no
+cmp(`q(`1', `2', defn(`defn'))', ```1',`2',<defn>'')
+@result{}no
+cmp(`q(`1', `2', defn(`defn'))', ```1',`2',`''')
+@result{}no
define(`cat', `$1`'ifelse(`$#', `1', `', `$0(shift($@@))')')
@result{}
-cat(`define(`foo',', defn(`divnum'), `)foo')-fixme
-@error{}m4:stdin:13: Warning: ifelse: cannot quote builtin
-@result{}-fixme
-cat(e(`define(`bar',', defn(`divnum'), `)bar'))-fixme
-@error{}m4:stdin:14: Warning: ifelse: cannot quote builtin
-@result{}-fixme
-m4wrap(`u('q(`cat(`define(`baz','', defn(`divnum'), ``)baz')')`)-fixme
+cat(`define(`foo',', defn(`divnum'), `)foo')
+@result{}0
+cat(e(`define(`bar',', defn(`divnum'), `)bar'))
+@result{}0
+m4wrap(`u('q(`cat(`define(`baz','', defn(`divnum'), ``)baz')')`)
')
-@error{}m4:stdin:15: Warning: m4wrap: cannot quote builtin
@result{}
^D
-@result{}-fixme
+@result{}0
@end example
@end ignore
@@ -3804,7 +3798,7 @@ echo(`1', `long string')
@error{}m4trace: -1- echo(`1', `long s...') -> ``1',`l...'
@result{}1,long string
indir(`echo', defn(`changequote'))
-@error{}m4trace: -2- defn(`change...')
+@error{}m4trace: -2- defn(`change...') -> `<changequote>'
@error{}m4trace: -1- indir(`echo', <changequote>) -> ``<changequote>''
@result{}
@end example
@@ -4601,7 +4595,7 @@ not if @code{m4exit} is used to exit @code{m4}.
It is safe to call @code{m4wrap} from wrapped text, where all the
recursively wrapped text is deferred until the current wrapped text is
-exhausted. As of M4 1.4.11, when @code{m4wrap} is not used recursively,
+exhausted. As of M4 1.6, when @code{m4wrap} is not used recursively,
the saved pieces of text are reread in the same order in which they were
saved (FIFO---first in, first out), as required by @acronym{POSIX}.
@@ -4716,6 +4710,24 @@ m4wrap(`m4wrap(`)')len(abc')
@error{}m4:stdin:1: len: end of file in argument list
@end example
+As of M4 1.6, @code{m4wrap} transparently handles builtin tokens
+generated by @code{defn} (@pxref{Defn}). However, for portability, it
+is better to defer the evaluation of @code{defn} along with the rest of
+the wrapped text, as is done for @code{foo} in the example below, rather
+than computing the builtin token up front, as is done for @code{bar}.
+
+@example
+m4wrap(`define(`foo', defn(`divnum'))foo
+')
+@result{}
+m4wrap(`define(`bar', ')m4wrap(defn(`divnum'))m4wrap(`)bar
+')
+@result{}
+^D
+@result{}0
+@result{}0
+@end example
+
@node File Inclusion
@chapter File inclusion
@@ -4934,6 +4946,20 @@ divert(`1')
f
m4exit
@end example
+
+@comment Catch regression in 1.4.10 with spilled diversions.
+
+@example
+ifdef(`__unix__', ,
+ `errprint(` skipping: syscmd does not have unix semantics
+')m4exit(`77')')dnl
+changequote(`[', `]')dnl
+syscmd([echo 'divert(1)hi
+format(%1000000d, 1)' | m4 | sed 1q])dnl
+@result{}hi
+sysval
+@result{}0
+@end example
@end ignore
Diversions make it possible to generate output in a different order than
@@ -7064,7 +7090,7 @@ of @samp{-} on the command line.
@item
@acronym{POSIX} requires @code{m4wrap} (@pxref{M4wrap}) to act in FIFO
(first-in, first-out) order, and most other implementations obey this.
-However, versions of @acronym{GNU} @code{m4} earlier than 1.4.11 used
+However, versions of @acronym{GNU} @code{m4} earlier than 1.6 used
LIFO order. Furthermore, @acronym{POSIX} states that only the first
argument to @code{m4wrap} is saved for later evaluation, but
@acronym{GNU} @code{m4} saves and processes all arguments, with output
@@ -7526,14 +7552,14 @@ foreachq(`x', ``1', `2', `3', `4'', `x
@result{}4
@end example
-Prior to M4 1.4.11, every instance of @samp{$@@} was rescanned as it was
+Prior to M4 1.6, every instance of @samp{$@@} was rescanned as it was
encountered. Thus, the @file{foreachq3.m4} alternative used much less
memory than @file{foreachq2.m4}, and executed as much as 10% faster,
since each iteration encountered fewer @samp{$@@}. However, the
implementation of rescanning every byte in @samp{$@@} was quadratic in
the number of bytes scanned (for example, making the broken version in
@file{foreachq.m4} cubic, rather than quadratic, in behavior). Once the
-underlying M4 implementation was improved in 1.4.11 to reuse results of
+underlying M4 implementation was improved in 1.6 to reuse results of
previous scans, both styles of @code{foreachq} become linear in the
number of bytes scanned, and the difference in timing is no longer
noticeable; in fact, after the change, the @file{foreachq2.m4} version