[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
propose.
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
form.)
dnl Variations in m4 affecting gmp:
dnl
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
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
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
dnl popdef() - in BSD and SysV m4 popdef() takes multiple arguments and
dnl pops each, but GNU m4 only takes one argument.
dnl
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
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
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
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
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
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
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
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
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
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
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
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
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.
- doco m4 notes,
Kevin Ryde <=