[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: FYI: doc formatting, new tests

From: Eric Blake
Subject: Re: FYI: doc formatting, new tests
Date: Tue, 30 May 2006 13:48:50 +0000

Hi Gary,

> 2 possible improvements:
>  i) document it in the Compatibility node of the manual
> ii) follow the POSIX semantics only when POSIXLY_CORRECT is set.
> I think changing and/or adding functionality in a maintenance release to
> a stable branch is ill advised.

Agreed.   I was already working on this patch before your mail
came, but now feel justified in committing it.  For now, the new
m4wrap test fails with a core dump; next on my list is examining
John B's patch to fix nested m4wraps.

2006-05-30  Eric Blake  <address@hidden>

        * doc/m4.texinfo (M4wrap): Add test to expose m4wrap bug.
        Reported by John Brzustowski.
        (Incompatibilities): Document known POSIX incompatibilities.
        * THANKS: Update.

Index: doc/m4.texinfo
RCS file: /sources/m4/m4/doc/m4.texinfo,v
retrieving revision
diff -u -p -r1. m4.texinfo
--- doc/m4.texinfo      29 May 2006 19:40:03 -0000
+++ doc/m4.texinfo      30 May 2006 13:41:44 -0000
@@ -2042,11 +2042,29 @@ This is the first and last normal input 
 The saved input is only reread when the end of normal input is seen, and
 not if @code{m4exit} is used to exit @code{m4}.
address@hidden FIXME: this contradicts POSIX, which requires that "If the
address@hidden m4wrap macro is used multiple times, the arguments specified
address@hidden shall be processed in the order in which the m4wrap macros were
address@hidden processed."
 It is safe to call @code{m4wrap} from saved text, but then the order in
 which the saved text is reread is undefined.  If @code{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).
+Here is an example of implementing a factorial function using
+define(`f', `ifelse(`$1', `0', `Answer: 0!=1
+', eval(`$1>1'), `0', `Answer: $2$1=eval(`$2$1')
+', `m4wrap(`f(decr(`$1'), `$2$1*')')')')
address@hidden: 10*9*8*7*6*5*4*3*2*1=3628800
address@hidden example
 @node File Inclusion, Diversions, Input Control, Top
 @chapter File inclusion
@@ -3322,6 +3340,11 @@ This allows macros in GNU @code{m4} to t
 not only nine (@pxref{Arguments}).
+The @code{divert} (@pxref{Divert}) macro can manage more than 9
+diversions.  GNU @code{m4} treats all positive numbers as valid
+diversions, rather than discarding diversions greater than 9.
 Files included with @code{include} and @code{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 @samp{-I} option and the
@@ -3378,12 +3401,67 @@ more extensive than in most other versio
 @section Facilities in System V @code{m4} not in GNU @code{m4}
 The version of @code{m4} from System V contains a few facilities that
-have not been implemented in GNU @code{m4} yet.
+have not been implemented in GNU @code{m4} yet.  Additionally,
address@hidden requires some behaviors that GNU @code{m4} has not
+implemented yet.  Relying on these behaviors is non-portable, as a
+future release of GNU @code{m4} may change.
 @itemize @bullet
-System V @code{m4} supports multiple arguments to @code{defn}.  This is
-not implemented in GNU @code{m4}.  Its usefulness is unclear to me.
+System V @code{m4} supports multiple arguments to @code{defn}, and
address@hidden requires it.  This is not implemented in GNU @code{m4}.
address@hidden 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 @code{include} (@pxref{Include}) when a file is unreadable,
address@hidden (@pxref{Eval}) when an argument cannot be parsed, or using
address@hidden (@pxref{M4exit}) with a non-numeric argument).
address@hidden requires an application to exit with non-zero status if
+it encounters a read error on stdin or write error on stdout, but GNU
address@hidden still exits with status 0 even if the disk is full.
address@hidden requires @code{m4wrap} (@pxref{M4wrap}) to act in FIFO
+(first-in, first-out) order, but GNU @code{m4} uses LIFO order.
+Furthermore, @acronym{POSIX} states that only the first argument to
address@hidden is saved for later evaluation, bug GNU @code{m4} saves and
+processes all arguments, with output separated by spaces.
address@hidden requires that all builtins that require arguments, but
+are called without arguments, behave as though empty strings had been
+passed.  For example, @code{a`'define`'b} would expand to @code{ab}.
+But GNU @code{m4} ignores certain builtins if they have missing
+arguments, giving @code{adefineb} for the above example.
+Traditional implementations treat @code{define(`f',1} (@pxref{Define})
+as though it were @code{undefine(`f')pushdef(`f',1)}, effectively
+replacing the entire stack of previously pushdef'd definitions with a
+single definition.  GNU @code{m4} behaves as
address@hidden(`f')pushdef(`f',1)}, keeping all previous definitions on
+the stack intact.
address@hidden requires @code{syscmd} (@pxref{Syscmd}) to evaluate
+command output for macro expansion, but this appears to be a mistake
+in @acronym{POSIX} since traditional implementations did not do this.
+GNU @code{m4} follows traditional behavior in @code{syscmd}, and
+provides the extension @code{esyscmd} that provides the @acronym{POSIX}
address@hidden requires @code{maketemp} (@pxref{Maketemp}) to replace
+the trailing @samp{X} characters with the @code{m4} process id, giving
+the same result on identical input, without creating any files, which
+leaves the door open for a data race in which other processes can create
+a file by the same name.  GNU @code{m4} actually creates a temporary
+file for each invocation of @code{maketemp}, which means that the output
+of the macro is different even if the input is identical.
 @end itemize
 @node Other Incompatibilities,  , Incompatibilities, Compatibility

reply via email to

[Prev in Thread] Current Thread [Next in Thread]