[Top][All Lists]

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

doco m4 notes

From: Kevin Ryde
Subject: doco m4 notes
Date: Thu, 22 May 2003 08:50:10 +1000
User-agent: Gnus/5.090019 (Oort Gnus v0.19) Emacs/21.2 (gnu/linux)

GMP uses m4 to pre-process assembler files and over a period of time I
collected up the notes below about problems and variations struck.  I
wonder if this would be good for the autoconf manual, perhaps as a
section after "Limitations of Make".  If so I'll work up some .texi to

Obviously none of this affects autoconf itself since it always uses
gnu m4, it'd just be for anyone wanting to write portable m4.  The
question would be whether m4 rates high enough as a usual tool to be
worth having some notes.

(The basic flavours of m4 are V7 (old), SysV, BSD, GNU and new
OpenBSD.  I'll try to make such things clearer if it goes to a .texi

dnl  Variations in m4 affecting gmp:
dnl  $# - When a macro is called as "foo" with no brackets, BSD m4 sets $#
dnl       to 1, whereas GNU or SysV m4 set it to 0.  In all cases though
dnl       "foo()" sets $# to 1.  This is worked around in various places.
dnl  len() - When "len()" is given an empty argument, BSD m4 evaluates to
dnl       nothing, whereas GNU, SysV, and the new OpenBSD, evaluate to 0.
dnl       See m4_length() below which works around this.
dnl  translit() - GNU m4 accepts character ranges like A-Z, and the new
dnl       OpenBSD m4 does under option -g, but basic BSD and SysV don't.
dnl  popdef() - in BSD and SysV m4 popdef() takes multiple arguments and
dnl       pops each, but GNU m4 only takes one argument.
dnl  push back - BSD m4 has some limits on the amount of text that can be
dnl       pushed back.  The limit is reasonably big and so long as macros
dnl       don't gratuitously duplicate big arguments it isn't a problem.
dnl       Normally an error message is given, but sometimes it just hangs.
dnl  eval() &,|,^ - GNU and SysV m4 have bitwise operators &,|,^ available,
dnl       but BSD m4 doesn't (contrary to what the man page suggests) and
dnl       instead ^ is exponentiation.
dnl  eval() ?: - The C ternary operator "?:" is available in BSD m4, but not
dnl       in SysV or GNU m4 (as of GNU m4 1.4 and betas of 1.5).
dnl  eval() -2^31 - BSD m4 has a bug where an eval() resulting in -2^31
dnl       (ie. -2147483648) gives "-(".  Using -2147483648 within an
dnl       expression is ok, it just can't be a final result.  "-(" will of
dnl       course upset parsing, with all sorts of strange effects.
dnl  eval() <<,>> - SysV m4 doesn't support shift operators in eval() (on
dnl       Solaris 7 /usr/xpg4/m4 has them but /usr/ccs/m4 doesn't).  See
dnl       m4_lshift() and m4_rshift() below for workarounds.
dnl  m4wrap() sequence - in BSD m4, m4wrap() replaces any previous m4wrap()
dnl       string, in SysV m4 it appends to it, and in GNU m4 it prepends.
dnl       See m4wrap_prepend() below which brings uniformity to this.
dnl  m4wrap() 0xFF - old versions of BSD m4 store EOF in a C "char" under an
dnl       m4wrap() and on systems where char is unsigned by default a
dnl       spurious 0xFF is output.  This has been observed on recent Cray
dnl       Unicos Alpha and Apple MacOS X systems.  An autoconf test is used
dnl       to check for this, see the m4wrap handling below.  It might work
dnl       to end the m4wrap string with a dnl to consume the 0xFF, but that
dnl       probably induces the offending m4's to read from an already closed
dnl       "FILE *", which could be bad on a glibc style stdio.
dnl  __file__,__line__ - GNU m4 and OpenBSD 2.7 m4 provide these, and
dnl       they're used here to make error messages more informative.  GNU m4
dnl       gives an unhelpful "NONE 0" in an m4wrap(), but that's worked
dnl       around.
dnl  __file__ quoting - OpenBSD m4, unlike GNU m4, doesn't quote the
dnl       filename in __file__, so care should be taken that no macro has
dnl       the same name as a file, or an unwanted expansion will occur when
dnl       printing an error or warning.
dnl  changecom() - BSD m4 changecom doesn't quite work like the man page
dnl       suggests, in particular "changecom" or "changecom()" doesn't
dnl       disable the comment feature, and multi-character comment sequences
dnl       don't seem to work.  If the default `#' and newline aren't
dnl       suitable it's necessary to change it to something else,
dnl       eg. changecom(;).
dnl  OpenBSD 2.6 m4 - in this m4, eval() rejects decimal constants containing
dnl       an 8 or 9, making it pretty much unusable.  The bug is confined to
dnl       version 2.6 (it's not in 2.5, and has been fixed in 2.7).
dnl  SunOS /usr/bin/m4 - this m4 lacks a number of desired features,
dnl       including $# and $@, defn(), m4exit(), m4wrap(), pushdef(),
dnl       popdef().  /usr/5bin/m4 is a SysV style m4 which should always be
dnl       available, and "configure" will reject /usr/bin/m4 in favour of
dnl       /usr/5bin/m4 (if necessary).
dnl       The sparc code actually has modest m4 requirements currently and
dnl       could manage with /usr/bin/m4, but there's no reason to put our
dnl       macros through contortions when /usr/5bin/m4 is available or GNU
dnl       m4 can be installed.

reply via email to

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