m4: Incompatibilities

1 
1 16.2 Facilities in System V 'm4' not in GNU 'm4'
1 ================================================
1 
1 The version of 'm4' from System V contains a few facilities that have
1 not been implemented in GNU 'm4' yet.  Additionally, POSIX requires some
1 behaviors that GNU 'm4' has not implemented yet.  Relying on these
1 behaviors is non-portable, as a future release of GNU 'm4' may change.
1 
1    * POSIX requires support for multiple arguments to 'defn', without
1      any clarification on how 'defn' behaves when one of the multiple
1      arguments names a builtin.  System V 'm4' and some other
1      implementations allow mixing builtins and text macros into a single
1      macro.  GNU 'm4' only supports joining multiple text arguments,
1      although a future implementation may lift this restriction to
1      behave more like System V.  The only portable way to join text
1      macros with builtins is via helper macros and implicit
1      concatenation of macro results.
1 
1    * POSIX requires an application to exit with non-zero status if it
1      wrote an error message to stderr.  This has not yet been
1      consistently implemented for the various builtins that are required
1      to issue an error (such as 'eval' (⇒Eval) when an argument
1      cannot be parsed).
1 
1    * Some traditional implementations only allow reading standard input
1      once, but GNU 'm4' correctly handles multiple instances of '-' on
1      the command line.
1 
1    * POSIX requires 'm4wrap' (⇒M4wrap) to act in FIFO (first-in,
1      first-out) order, but GNU 'm4' currently uses LIFO order.
1      Furthermore, POSIX states that only the first argument to 'm4wrap'
1      is saved for later evaluation, but GNU 'm4' saves and processes all
1      arguments, with output separated by spaces.
1 
1    * POSIX states that builtins that require arguments, but are called
1      without arguments, have undefined behavior.  Traditional
1      implementations simply behave as though empty strings had been
1      passed.  For example, 'a`'define`'b' would expand to 'ab'.  But GNU
1      'm4' ignores certain builtins if they have missing arguments,
1      giving 'adefineb' for the above example.
1 
11    * Traditional implementations handle 'define(`f',`1')' (⇒
      Define) by undefining the entire stack of previous definitions,
1      and if doing 'undefine(`f')' first.  GNU 'm4' replaces just the top
1      definition on the stack, as if doing 'popdef(`f')' followed by
1      'pushdef(`f',`1')'.  POSIX allows either behavior.
1 
1    * POSIX 2001 requires 'syscmd' (⇒Syscmd) to evaluate command
1      output for macro expansion, but this was a mistake that is
1      anticipated to be corrected in the next version of POSIX. GNU 'm4'
1      follows traditional behavior in 'syscmd' where output is not
1      rescanned, and provides the extension 'esyscmd' that does scan the
1      output.
1 
11    * At one point, POSIX required 'changequote(ARG)' (⇒
      Changequote) to use newline as the close quote, but this was a
1      bug, and the next version of POSIX is anticipated to state that
1      using empty strings or just one argument is unspecified.
1      Meanwhile, the GNU 'm4' behavior of treating an empty end-quote
1      delimiter as ''' is not portable, as Solaris treats it as repeating
1      the start-quote delimiter, and BSD treats it as leaving the
1      previous end-quote delimiter unchanged.  For predictable results,
1      never call changequote with just one argument, or with empty
1      strings for arguments.
1 
1    * At one point, POSIX required 'changecom(ARG,)' (⇒Changecom)
1      to make it impossible to end a comment, but this is a bug, and the
1      next version of POSIX is anticipated to state that using empty
1      strings is unspecified.  Meanwhile, the GNU 'm4' behavior of
1      treating an empty end-comment delimiter as newline is not portable,
1      as BSD treats it as leaving the previous end-comment delimiter
1      unchanged.  It is also impossible in BSD implementations to disable
1      comments, even though that is required by POSIX. For predictable
1      results, never call changecom with empty strings for arguments.
1 
1    * Most implementations of 'm4' give macros a higher precedence than
1      comments when parsing, meaning that if the start delimiter given to
1      'changecom' (⇒Changecom) starts with a macro name, comments
1      are effectively disabled.  POSIX does not specify what the
1      precedence is, so this version of GNU 'm4' parser recognizes
1      comments, then macros, then quoted strings.
1 
1    * Traditional implementations allow argument collection, but not
1      string and comment processing, to span file boundaries.  Thus, if
1      'a.m4' contains 'len(', and 'b.m4' contains 'abc)', 'm4 a.m4 b.m4'
1      outputs '3' with traditional 'm4', but gives an error message that
1      the end of file was encountered inside a macro with GNU 'm4'.  On
1      the other hand, traditional implementations do end of file
11      processing for files included with 'include' or 'sinclude' (⇒
      Include), while GNU 'm4' seamlessly integrates the content of
1      those files.  Thus 'include(`a.m4')include(`b.m4')' will output '3'
1      instead of giving an error.
1 
1    * Traditional 'm4' treats 'traceon' (⇒Trace) without arguments
1      as a global variable, independent of named macro tracing.  Also,
1      once a macro is undefined, named tracing of that macro is lost.  On
1      the other hand, when GNU 'm4' encounters 'traceon' without
1      arguments, it turns tracing on for all existing definitions at the
1      time, but does not trace future definitions; 'traceoff' without
1      arguments turns tracing off for all definitions regardless of
1      whether they were also traced by name; and tracing by name, such as
1      with '-tfoo' at the command line or 'traceon(`foo')' in the input,
1      is an attribute that is preserved even if the macro is currently
1      undefined.
1 
1      Additionally, while POSIX requires trace output, it makes no
1      demands on the formatting of that output.  Parsing trace output is
1      not guaranteed to be reliable, even between different releases of
1      GNU M4; however, the intent is that any future changes in trace
1      output will only occur under the direction of additional
1      'debugmode' flags (⇒Debug Levels).
1 
1    * POSIX requires 'eval' (⇒Eval) to treat all operators with
1      the same precedence as C.  However, earlier versions of GNU 'm4'
1      followed the traditional behavior of other 'm4' implementations,
1      where bitwise and logical negation ('~' and '!') have lower
1      precedence than equality operators; and where equality operators
1      ('==' and '!=') had the same precedence as relational operators
1      (such as '<').  Use explicit parentheses to ensure proper
1      precedence.  As extensions to POSIX, GNU 'm4' gives well-defined
1      semantics to operations that C leaves undefined, such as when
1      overflow occurs, when shifting negative numbers, or when performing
1      division by zero.  POSIX also requires '=' to cause an error, but
1      many traditional implementations allowed it as an alias for '=='.
1 
1    * POSIX 2001 requires 'translit' (⇒Translit) to treat each
1      character of the second and third arguments literally.  However, it
1      is anticipated that the next version of POSIX will allow the GNU
1      'm4' behavior of treating '-' as a range operator.
1 
1    * POSIX requires 'm4' to honor the locale environment variables of
1      'LANG', 'LC_ALL', 'LC_CTYPE', 'LC_MESSAGES', and 'NLSPATH', but
1      this has not yet been implemented in GNU 'm4'.
1 
1    * POSIX states that only unquoted leading newlines and blanks (that
1      is, space and tab) are ignored when collecting macro arguments.
1      However, this appears to be a bug in POSIX, since most traditional
1      implementations also ignore all whitespace (formfeed, carriage
1      return, and vertical tab).  GNU 'm4' follows tradition and ignores
1      all leading unquoted whitespace.
1 
1    * A strictly-compliant POSIX client is not allowed to use
1      command-line arguments not specified by POSIX. However, since this
1      version of M4 ignores 'POSIXLY_CORRECT' and enables the option
1      '--gnu' by default (⇒Invoking m4 Limits control.), a client
1      desiring to be strictly compliant has no way to disable GNU
1      extensions that conflict with POSIX when directly invoking the
1      compiled 'm4'.  A future version of 'GNU' M4 will honor the
1      environment variable 'POSIXLY_CORRECT', implicitly enabling
1      '--traditional' if it is set, in order to allow a
1      strictly-compliant client.  In the meantime, a client needing
1      strict POSIX compliance can use the workaround of invoking a shell
1      script wrapper, where the wrapper then adds '--traditional' to the
1      arguments passed to the compiled 'm4'.
1