summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2021-05-07 14:47:04 -0500
committerEric Blake <eblake@redhat.com>2021-05-07 14:47:04 -0500
commit0b98fb45910bba58a0a64192443b1d71fbf19ecf (patch)
tree7c751929d43352234572cfe4d770c944b7c9b2c8
parentd69fa5284851b2b7aac25ffac638b6b379994db5 (diff)
downloadm4-0b98fb45910bba58a0a64192443b1d71fbf19ecf.tar.gz
maint: Redirect developers to active branch
_This_ branch does not contain actively-developed code. More likely, you want to check out branch-1.4 (latest stable), branch-1.6 (some speedups over 1.4, but not yet released), or branch-2.0 (many more experimental changes, and even further from release). * README: Document the status of this git repository.
-rw-r--r--.autom4te.cfg4
-rw-r--r--.gitattributes5
-rw-r--r--.gitignore91
-rw-r--r--.gitmodules3
-rw-r--r--.prev-version1
-rw-r--r--.x-update-copyright1
-rw-r--r--AUTHORS43
-rw-r--r--COPYING674
-rw-r--r--ChangeLog.old12324
-rw-r--r--HACKING334
-rw-r--r--Makefile.am453
-rw-r--r--NEWS1228
-rw-r--r--NO-THANKS186
-rw-r--r--README90
-rw-r--r--TODO150
-rwxr-xr-xbootstrap5100
-rw-r--r--bootstrap.conf160
-rwxr-xr-xbuild-aux/gl/build-aux/bootstrap.in2769
-rwxr-xr-xbuild-aux/gl/build-aux/extract-trace420
-rw-r--r--build-aux/gl/build-aux/funclib.sh1304
-rwxr-xr-xbuild-aux/gl/build-aux/inline-source164
-rw-r--r--build-aux/gl/build-aux/options-parser608
-rw-r--r--build-aux/gl/lib/clean-temp.c.diff14
m---------build-aux/gnulib0
-rw-r--r--build-aux/m4/debug.m494
-rw-r--r--build-aux/m4/gmp.m477
-rw-r--r--build-aux/m4/gnulib-cache.m4120
-rw-r--r--build-aux/m4/m4-error.m441
-rw-r--r--build-aux/m4/m4-getopt.m435
-rw-r--r--build-aux/m4/m4-gettext.m435
-rw-r--r--build-aux/m4/m4-obstack.m450
-rw-r--r--build-aux/m4/m4-regex.m439
-rw-r--r--build-aux/m4/m4-rename.m446
-rw-r--r--build-aux/m4/m4-syscmd.m460
-rw-r--r--build-aux/m4/stackovf.m491
-rwxr-xr-xbuild-aux/thanks-gen20
-rw-r--r--cfg.mk63
-rw-r--r--configure.ac362
-rw-r--r--doc/Makefile.am38
-rw-r--r--doc/STYLE100
-rw-r--r--doc/examples/COPYING8
-rw-r--r--doc/examples/WWW/COPYING8
-rw-r--r--doc/examples/WWW/Makefile45
-rw-r--r--doc/examples/WWW/_footer.htm10
-rw-r--r--doc/examples/WWW/_header.htm231
-rw-r--r--doc/examples/WWW/m4lib/COPYING8
-rw-r--r--doc/examples/WWW/m4lib/bugs.m453
-rw-r--r--doc/examples/WWW/m4lib/changelog.m418
-rw-r--r--doc/examples/WWW/m4lib/download.m424
-rw-r--r--doc/examples/WWW/m4lib/features.m458
-rw-r--r--doc/examples/WWW/m4lib/feedback.m420
-rw-r--r--doc/examples/WWW/m4lib/html.m4122
-rw-r--r--doc/examples/WWW/m4lib/index.m436
-rw-r--r--doc/examples/WWW/m4lib/layout.m465
-rw-r--r--doc/examples/WWW/m4lib/lists.m432
-rw-r--r--doc/examples/WWW/m4lib/menu.m474
-rw-r--r--doc/examples/WWW/m4lib/modules.m418
-rw-r--r--doc/examples/WWW/m4lib/news.m418
-rw-r--r--doc/examples/WWW/m4lib/readme.m418
-rw-r--r--doc/examples/WWW/m4lib/setup.m47
-rw-r--r--doc/examples/WWW/m4lib/test.m429
-rw-r--r--doc/examples/WWW/m4lib/thanks.m418
-rw-r--r--doc/examples/WWW/m4lib/thissite.m442
-rw-r--r--doc/examples/WWW/m4lib/tmpl.m411
-rw-r--r--doc/examples/WWW/m4lib/todo.m418
-rw-r--r--doc/examples/WWW/m4lib/uses.m443
-rw-r--r--doc/examples/WWW/m4lib/visions.m4232
-rw-r--r--doc/examples/WWW/m4lib/whatis.m448
-rw-r--r--doc/examples/capitalize.m412
-rw-r--r--doc/examples/capitalize2.m419
-rw-r--r--doc/examples/comments.m47
-rw-r--r--doc/examples/curry.m47
-rw-r--r--doc/examples/ddivert.m44
-rw-r--r--doc/examples/debug.m44
-rw-r--r--doc/examples/esyscmd.m46
-rw-r--r--doc/examples/exp.m43
-rw-r--r--doc/examples/foreach.m48
-rw-r--r--doc/examples/foreach2.m410
-rw-r--r--doc/examples/foreachq.m49
-rw-r--r--doc/examples/foreachq2.m410
-rw-r--r--doc/examples/foreachq3.m49
-rw-r--r--doc/examples/foreachq4.m413
-rw-r--r--doc/examples/forloop.m46
-rw-r--r--doc/examples/forloop2.m412
-rw-r--r--doc/examples/forloop3.m413
-rw-r--r--doc/examples/fstab.m46
-rw-r--r--doc/examples/hanoi.m417
-rw-r--r--doc/examples/incl-test.m43
-rw-r--r--doc/examples/incl.m43
-rw-r--r--doc/examples/include.m47
-rw-r--r--doc/examples/indir.m410
-rw-r--r--doc/examples/join.m415
-rw-r--r--doc/examples/loop.m418
-rw-r--r--doc/examples/misc.m48
-rw-r--r--doc/examples/modtest.m48
-rw-r--r--doc/examples/multiquotes.m417
-rw-r--r--doc/examples/patsubst.m48
-rw-r--r--doc/examples/pushpop.m425
-rw-r--r--doc/examples/quote.m49
-rw-r--r--doc/examples/regexp.m412
-rw-r--r--doc/examples/reverse.m44
-rw-r--r--doc/examples/shadow.m458
-rw-r--r--doc/examples/stack.m416
-rw-r--r--doc/examples/stack_sep.m417
-rw-r--r--doc/examples/stdlib.m445
-rw-r--r--doc/examples/sysv-args.m414
-rw-r--r--doc/examples/time.m421
-rw-r--r--doc/examples/time2.m419
-rw-r--r--doc/examples/trace.m430
-rw-r--r--doc/examples/translit.m48
-rw-r--r--doc/examples/undivert.incl1
-rw-r--r--doc/examples/undivert.m45
-rw-r--r--doc/examples/wrap.m410
-rw-r--r--doc/examples/wrapfifo.m410
-rw-r--r--doc/examples/wraplifo.m410
-rw-r--r--doc/examples/wraplifo2.m49
-rw-r--r--doc/m4.texi10411
-rw-r--r--m4/builtin.c123
-rw-r--r--m4/debug.c260
-rw-r--r--m4/hash.c671
-rw-r--r--m4/hash.h81
-rw-r--r--m4/input.c2223
-rw-r--r--m4/m4.c159
-rw-r--r--m4/m4module.h556
-rw-r--r--m4/m4private.h626
-rw-r--r--m4/macro.c1784
-rw-r--r--m4/module.c344
-rw-r--r--m4/output.c1119
-rw-r--r--m4/path.c414
-rw-r--r--m4/resyntax.c127
-rw-r--r--m4/symtab.c968
-rw-r--r--m4/syntax.c954
-rw-r--r--m4/system_.h173
-rw-r--r--m4/utility.c292
-rw-r--r--modules/evalparse.c1029
-rw-r--r--modules/format.c425
-rw-r--r--modules/gnu.c1077
-rw-r--r--modules/m4.c1324
-rw-r--r--modules/m4.h53
-rw-r--r--modules/mpeval.c453
-rw-r--r--modules/stdlib.c288
-rw-r--r--modules/time.c240
-rw-r--r--modules/traditional.c52
-rw-r--r--po/Makevars44
-rw-r--r--po/POTFILES.in31
-rw-r--r--src/freeze.c1000
-rw-r--r--src/m4.h43
-rw-r--r--src/main.c762
-rw-r--r--src/stackovf.c454
-rw-r--r--tests/atlocal.in27
-rw-r--r--tests/builtins.at1325
-rw-r--r--tests/freeze.at539
-rwxr-xr-xtests/generate.awk216
-rw-r--r--tests/import.c110
-rw-r--r--tests/iso8859.m4bin1465 -> 0 bytes
-rw-r--r--tests/m4.in46
-rw-r--r--tests/macros.at589
-rw-r--r--tests/modtest.c101
-rw-r--r--tests/modules.at344
-rw-r--r--tests/null.errbin3639 -> 0 bytes
-rw-r--r--tests/null.m4bin7738 -> 0 bytes
-rw-r--r--tests/null.outbin631 -> 0 bytes
-rw-r--r--tests/options.at863
-rw-r--r--tests/others.at980
-rw-r--r--tests/shadow.c91
-rwxr-xr-xtests/stackovf.test105
-rw-r--r--tests/testsuite.at180
167 files changed, 9 insertions, 63373 deletions
diff --git a/.autom4te.cfg b/.autom4te.cfg
deleted file mode 100644
index f47eaeee..00000000
--- a/.autom4te.cfg
+++ /dev/null
@@ -1,4 +0,0 @@
-# Disable the autom4te.cache directory.
-begin-language: "Autoconf-without-aclocal-m4"
-args: --no-cache
-end-language: "Autoconf-without-aclocal-m4"
diff --git a/.gitattributes b/.gitattributes
deleted file mode 100644
index f7c0ed7c..00000000
--- a/.gitattributes
+++ /dev/null
@@ -1,5 +0,0 @@
-# See ./bootstrap for some helpful ~/.gitconfig or .git/config settings
-# needed for using these attributes effectively.
-*.texi* diff=texinfo
-null.* diff merge
-iso8859.m4 diff merge
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index e0841d1e..00000000
--- a/.gitignore
+++ /dev/null
@@ -1,91 +0,0 @@
-*~
-.#*
-*.a
-*.bak
-.deps
-.dirstamp
-*.exe
-*.gmo
-*.header
-*.la
-.libs
-*.lo
-*.log
-*.mo
-*.o
-*.orig
-*.patch
-.patch_number
-*.po
-*.pot
-*.rej
-*.sin
-/.tarball-version
-/.version
-ABOUT-NLS
-/aclocal.m4
-/aclocal.m4t
-autom4te.cache
-build-aux/
-!build-aux/gl/
-!build-aux/gnulib/
-!build-aux/m4/
-!build-aux/thanks-gen
-/ChangeLog
-/config.cache
-/config.h
-/config.h.in
-/config.log
-/config.status
-/configure
-cscope.*
-CVS
-/doc/.gitignore
-/doc/m4.1
-/doc/m4.??
-/doc/m4.???
-/doc/m4.html
-/doc/m4.info*
-/doc/manual
-/doc/stamp-vti
-/doc/version.texi
-/GNUmakefile
-/INSTALL
-libtool
-/m4-*
-/m4/gnu
-/m4/obstack.h
-/m4/pathconf.h
-/m4/system.h
-/maint.mk
-Makefile
-Makefile.in
-Makefile.inc
-/patches
-/po/.reference
-/po/*.sed
-/po/LINGUAS
-/po/Makefile.in.in
-/po/Makevars.template
-/po/POTFILES
-/po/Rules-quot
-/po/stamp-po
-/src/assure*
-/src/getopt*
-/src/m4
-/src/version-etc*
-/src/xstrto*
-/stamp-h
-/stamp-h1
-/stamp-h.in
-/stamp-vcl
-/tests/at-*
-/tests/atconfig
-/tests/atlocal
-/tests/m4
-/tests/generated.at
-/tests/gnu
-/tests/package.m4
-/tests/testsuite
-/tests/testsuite.dir
-/tests/testsuite.log
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 0d4d08ae..00000000
--- a/.gitmodules
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "gnulib"]
- path = build-aux/gnulib
- url = git://git.sv.gnu.org/gnulib.git
diff --git a/.prev-version b/.prev-version
deleted file mode 100644
index f689e8c1..00000000
--- a/.prev-version
+++ /dev/null
@@ -1 +0,0 @@
-1.4.18
diff --git a/.x-update-copyright b/.x-update-copyright
deleted file mode 100644
index d0a3998e..00000000
--- a/.x-update-copyright
+++ /dev/null
@@ -1 +0,0 @@
-ltdl/m4/gnulib-cache.m4
diff --git a/AUTHORS b/AUTHORS
deleted file mode 100644
index 73ce2f95..00000000
--- a/AUTHORS
+++ /dev/null
@@ -1,43 +0,0 @@
-Authors of GNU M4.
-
-The following contributors have warranted legal paper exchanges with
-the Free Software Foundation for their contributions to GNU M4. Also
-see the files ChangeLog and THANKS. This list results from searching
-for /\bM4\b/ in the file /gd/gnuorg/copyright.list on the
-fencepost.gnu.org machine.
-
-Rene' Seindal seindal@diku.dk 1990-03-28
-James L. Avera jima@netcom.com 1993-10-04
-Pete Chown pete.chown@dale.dircon.co.uk 1994-06-28
-John Gerard Makecki johnm@vlibs.com 1995-04-24
-Francois Pinard pinard@iro.umontreal.ca 1996-02-01
-Thomas Tanner tanner@ffii.org 1999-06-23
-Gary V. Vaughan gary@gnu.org 2000-10-02
-Yuji Minejima ? 2001-05-09
-Akim Demaille akim@freefriends.org 2001-11-01
-Andrew James Bettison andrewb@zip.com.au 2001-11-19
-Noah Jeffrey Misch noah@cs.caltech.edu 2004-07-05
-Michael Elizabeth Chastain mec@shout.net 2001-12-27
-William C. Cox bill@qswtools.com 2004-12-04
-Alexandre Duret-Lutz adl@gnu.org 2004-12-04
-John Gatewood Ham zappaman@buraphalinux.org 2005-11-01
-Eric Benjamin Blake ebb9@byu.net 2006-01-18
-John Brzustowski jbrzusto@fastmail.fm 2006-03-06
-Ralf Wildenhues Ralf.Wildenhues@gmx.de 2006-03-20
-Markus Duft markus.duft@salomon.at 2006-08-03
-Joel E. Denny jdenny@clemson.edu 2009-08-18
-David Warme David.Warme@Group-W-Inc.com 2010-03-10
-Raphael Poss m4-patches@raphael.poss.name 2010-10-04
-Tim Rice tim@multitalents.net 2011-01-24
-
-========================================================================
-
-Copyright (C) 2000, 2006-2007, 2010, 2013-2014, 2017 Free Software
-Foundation, Inc.
-
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
-Texts. A copy of the license is included in the ``GNU Free
-Documentation License'' file as part of this distribution.
diff --git a/COPYING b/COPYING
deleted file mode 100644
index a9e5a4cc..00000000
--- a/COPYING
+++ /dev/null
@@ -1,674 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007, 2013-2014, 2017 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
- The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works. By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users. We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors. You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
- To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights. Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received. You must make sure that they, too, receive
-or can get the source code. And you must show them these terms so they
-know their rights.
-
- Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
- For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software. For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
- Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so. This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software. The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable. Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products. If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
- Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary. To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- TERMS AND CONDITIONS
-
- 0. Definitions.
-
- "This License" refers to version 3 of the GNU General Public License.
-
- "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
- "The Program" refers to any copyrightable work licensed under this
-License. Each licensee is addressed as "you". "Licensees" and
-"recipients" may be individuals or organizations.
-
- To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy. The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
- A "covered work" means either the unmodified Program or a work based
-on the Program.
-
- To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy. Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
- To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies. Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
- An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License. If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
- 1. Source Code.
-
- The "source code" for a work means the preferred form of the work
-for making modifications to it. "Object code" means any non-source
-form of a work.
-
- A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
- The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form. A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
- The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities. However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work. For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
- The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
- The Corresponding Source for a work in source code form is that
-same work.
-
- 2. Basic Permissions.
-
- All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met. This License explicitly affirms your unlimited
-permission to run the unmodified Program. The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work. This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
- You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force. You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright. Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
- Conveying under any other circumstances is permitted solely under
-the conditions stated below. Sublicensing is not allowed; section 10
-makes it unnecessary.
-
- 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
- No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
- When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
- 4. Conveying Verbatim Copies.
-
- You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
- You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
- 5. Conveying Modified Source Versions.
-
- You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
- a) The work must carry prominent notices stating that you modified
- it, and giving a relevant date.
-
- b) The work must carry prominent notices stating that it is
- released under this License and any conditions added under section
- 7. This requirement modifies the requirement in section 4 to
- "keep intact all notices".
-
- c) You must license the entire work, as a whole, under this
- License to anyone who comes into possession of a copy. This
- License will therefore apply, along with any applicable section 7
- additional terms, to the whole of the work, and all its parts,
- regardless of how they are packaged. This License gives no
- permission to license the work in any other way, but it does not
- invalidate such permission if you have separately received it.
-
- d) If the work has interactive user interfaces, each must display
- Appropriate Legal Notices; however, if the Program has interactive
- interfaces that do not display Appropriate Legal Notices, your
- work need not make them do so.
-
- A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit. Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
- 6. Conveying Non-Source Forms.
-
- You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
- a) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by the
- Corresponding Source fixed on a durable physical medium
- customarily used for software interchange.
-
- b) Convey the object code in, or embodied in, a physical product
- (including a physical distribution medium), accompanied by a
- written offer, valid for at least three years and valid for as
- long as you offer spare parts or customer support for that product
- model, to give anyone who possesses the object code either (1) a
- copy of the Corresponding Source for all the software in the
- product that is covered by this License, on a durable physical
- medium customarily used for software interchange, for a price no
- more than your reasonable cost of physically performing this
- conveying of source, or (2) access to copy the
- Corresponding Source from a network server at no charge.
-
- c) Convey individual copies of the object code with a copy of the
- written offer to provide the Corresponding Source. This
- alternative is allowed only occasionally and noncommercially, and
- only if you received the object code with such an offer, in accord
- with subsection 6b.
-
- d) Convey the object code by offering access from a designated
- place (gratis or for a charge), and offer equivalent access to the
- Corresponding Source in the same way through the same place at no
- further charge. You need not require recipients to copy the
- Corresponding Source along with the object code. If the place to
- copy the object code is a network server, the Corresponding Source
- may be on a different server (operated by you or a third party)
- that supports equivalent copying facilities, provided you maintain
- clear directions next to the object code saying where to find the
- Corresponding Source. Regardless of what server hosts the
- Corresponding Source, you remain obligated to ensure that it is
- available for as long as needed to satisfy these requirements.
-
- e) Convey the object code using peer-to-peer transmission, provided
- you inform other peers where the object code and Corresponding
- Source of the work are being offered to the general public at no
- charge under subsection 6d.
-
- A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
- A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling. In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage. For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product. A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
- "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source. The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
- If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information. But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
- The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed. Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
- Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
- 7. Additional Terms.
-
- "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law. If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
- When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it. (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.) You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
- Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
- a) Disclaiming warranty or limiting liability differently from the
- terms of sections 15 and 16 of this License; or
-
- b) Requiring preservation of specified reasonable legal notices or
- author attributions in that material or in the Appropriate Legal
- Notices displayed by works containing it; or
-
- c) Prohibiting misrepresentation of the origin of that material, or
- requiring that modified versions of such material be marked in
- reasonable ways as different from the original version; or
-
- d) Limiting the use for publicity purposes of names of licensors or
- authors of the material; or
-
- e) Declining to grant rights under trademark law for use of some
- trade names, trademarks, or service marks; or
-
- f) Requiring indemnification of licensors and authors of that
- material by anyone who conveys the material (or modified versions of
- it) with contractual assumptions of liability to the recipient, for
- any liability that these contractual assumptions directly impose on
- those licensors and authors.
-
- All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10. If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term. If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
- If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
- Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
- 8. Termination.
-
- You may not propagate or modify a covered work except as expressly
-provided under this License. Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
- However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
- Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
- Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
- 9. Acceptance Not Required for Having Copies.
-
- You are not required to accept this License in order to receive or
-run a copy of the Program. Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance. However,
-nothing other than this License grants you permission to propagate or
-modify any covered work. These actions infringe copyright if you do
-not accept this License. Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
- 10. Automatic Licensing of Downstream Recipients.
-
- Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License. You are not responsible
-for enforcing compliance by third parties with this License.
-
- An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations. If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
- You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License. For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
- 11. Patents.
-
- A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based. The
-work thus licensed is called the contributor's "contributor version".
-
- A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version. For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
- Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
- In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement). To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
- If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients. "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
- If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
- A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License. You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
- Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
- 12. No Surrender of Others' Freedom.
-
- If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all. For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
- 13. Use with the GNU Affero General Public License.
-
- Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work. The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
- 14. Revised Versions of this License.
-
- The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation. If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
- If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
- Later license versions may give you additional or different
-permissions. However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
- 15. Disclaimer of Warranty.
-
- THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
- 16. Limitation of Liability.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
- 17. Interpretation of Sections 15 and 16.
-
- If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
- If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
- <program> Copyright (C) <year> <name of author>
- This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
- You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<http://www.gnu.org/licenses/>.
-
- The GNU General Public License does not permit incorporating your program
-into proprietary programs. If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License. But first, please read
-<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/ChangeLog.old b/ChangeLog.old
deleted file mode 100644
index ab146a8e..00000000
--- a/ChangeLog.old
+++ /dev/null
@@ -1,12324 +0,0 @@
-2010-03-02 Giuseppe Scrivano <gscrivano@gnu.org> (tiny change)
-
- Support bootstrap --gnulib-srcdir=DIR.
- * bootstrap: Add --gnulib-srcdir option, which overrides
- GNULIB_SRCDIR, for consistency with gnulib bootstrap.
-
-2010-03-01 Eric Blake <eblake@redhat.com>
-
- Mention release of version 1.4.14.
- * gnulib: Update to latest.
- * README: Drop CVS mention.
- * HACKING: Tweak release instructions.
- * NEWS: Mention the release.
- * .prev-version: Record previous version.
- * cfg.mk (old_NEWS_hash): Auto-update.
-
-2010-02-24 Eric Blake <eblake@redhat.com>
-
- Improve parsing example.
- * doc/m4.texinfo (Input processing): Double-quote argument to
- translit, for robustness.
- * THANKS: Update.
- Reported by Chris Penev.
-
-2010-01-29 Eric Blake <ebb9@byu.net>
-
- Document upcoming release.
- * gnulib: Update to latest.
- * doc/m4.texinfo (History): Mention 1.4.14.
- * Makefile.am (src/getopt.h): Drop dependence on now-obsolete
- link-warning.h.
-
-2010-01-08 Eric Blake <ebb9@byu.net>
-
- Address remaining 'make syntax-check' findings.
- * gnulib: Update to latest.
- * Makefile.am (tests/package.m4): Avoid @@ substitution.
- (src_m4_LDADD): Link with libiconv.
- * m4/m4private.h (STREQ): New macro.
- * m4/resyntax.c (m4_regexp_syntax_encode): Use it.
- * src/main.c (process_file): Likewise.
- (includes): Drop unused header.
- * m4/macro.c (m4_arg_equal): Adjust comment.
- * m4/syntax.c: Likewise.
- * m4/system_.h: Avoid useless preprocessor parenthesis.
- * ltdl/m4/stackovf.m4 (M4_SYS_STACKOVF): Likewise.
- * src/stackovf.c: Likewise.
- (setup_stackovf_trap): Mark diagnostics.
- * modules/mpeval.c (includes): Move quotearg.h inclusion...
- * modules/evalparse.c (includes): ...to where it is used.
- * cfg.mk (local-checks-to-skip): Exempt tests that cause spurious
- failures, but first fix what they were intended to detect.
- (_makefile_at_at_check_exceptions): Allow an exception.
-
-2010-01-07 Eric Blake <ebb9@byu.net>
-
- Use correct license on auxiliary documentation.
- * gnulib: Update to latest.
- * AUTHORS: Use GFDL 1.3, not 1.2.
- * README-alpha: Likewise.
- * README: Likewise.
- * THANKS: Likewise.
- * doc/STYLE: Likewise.
- * modules/README: Likewise.
- * NEWS: Place under GFDL.
- * TODO: Likewise.
- * cfg.mk (old_NEWS_hash): Update.
-
- Address 'make sc_error_message_uppercase' failures.
- * m4/output.c (m4_freeze_diversions): Silence false positive.
- * src/main.c (main): Use 'warning', not 'Warning', in messages.
- * m4/utility.c (m4_verror_at_line): Likewise.
- * doc/m4.texinfo (Operation modes, Macro Arguments, Undefine)
- (Defn, Pushdef, Indir, Builtin, Ifdef, Ifelse, Dumpdef, Trace)
- (Debuglen, Debugfile, Dnl, Changeresyntax, Standard Modules)
- (Index macro, Regexp, Substr, Translit, Patsubst, Format, Incr)
- (Eval, Mkstemp, Syncoutput, Improved forloop)
- (Improved fatal_error): Adjust expected output.
- * tests/builtins.at (define, mkdtemp, mkstemp): Likewise.
- * tests/freeze.at (loading format 1, reloading unknown builtin):
- Likewise.
- * tests/macros.at (Arity and defn, 'Arity, defn, and freeze')
- (pushdef/popdef): Likewise.
- * tests/null.err: Likewise.
- * tests/options.at (deprecated options, POSIXLY_CORRECT)
- (--fatal-warnings, --regexp-syntax, --syncoutput): Likewise.
- * tests/others.at (nul character, stdin seekable): Likewise.
- * tests/modules.at (AT_CHECK_M4_MODTEST, modules: text):
- Likewise.
-
- Address 'make sc_cast_of_argument_to_free' failures.
- * m4/m4private.h (DELETE): Adjust comment and fix parentheses.
- * m4/m4.c (m4_delete): Use it to avoid warning.
- * m4/module.c (install_builtin_table, module_remove): Likewise.
- * m4/symtab.c (m4_symbol_value_delete, m4_symbol_value_copy):
- Likewise.
- * .x-sc_cast_of_argument_to_free: New file.
- * Makefile.am (syntax_check_exceptions): Distribute exceptions.
-
- More whitespace cleanup.
- * HACKING: Nuke trailing whitespace.
- * examples/WWW/Makefile: Likewise.
- * examples/WWW/_footer.htm: Likewise.
- * examples/WWW/_header.htm: Likewise.
- * examples/WWW/m4lib/bugs.m4: Likewise.
- * examples/WWW/m4lib/html.m4: Likewise.
- * examples/WWW/m4lib/menu.m4: Likewise.
- * examples/WWW/m4lib/visions.m4: Likewise.
- * examples/esyscmd.m4: Likewise.
- * examples/fstab.m4: Avoid space-tab.
- * examples/patsubst.m4: Likewise.
- * NEWS: Prefer space over tab for alignment.
- * THANKS: Likewise.
- * TODO: Likewise.
- * bootstrap: Likewise.
- * configure.ac: Likewise.
- * ltdl/m4/stackovf.m4: Likewise.
- * m4/hash.c: Likewise.
- * m4/hash.h: Likewise.
- * m4/input.c: Likewise.
- * m4/m4.c: Likewise.
- * m4/m4module.h: Likewise.
- * m4/m4private.h: Likewise.
- * m4/macro.c: Likewise.
- * m4/module.c: Likewise.
- * m4/output.c: Likewise.
- * m4/path.c: Likewise.
- * m4/resyntax.c: Likewise.
- * m4/symtab.c: Likewise.
- * m4/syntax.c: Likewise.
- * m4/system_.h: Likewise.
- * modules/evalparse.c: Likewise.
- * modules/format.c: Likewise.
- * modules/gnu.c: Likewise.
- * modules/import.c: Likewise.
- * modules/load.c: Likewise.
- * modules/m4.c: Likewise.
- * modules/m4.h: Likewise.
- * modules/modtest.c: Likewise.
- * modules/mpeval.c: Likewise.
- * modules/perl.c: Likewise.
- * modules/shadow.c: Likewise.
- * modules/stdlib.c: Likewise.
- * modules/time.c: Likewise.
- * modules/traditional.c: Likewise.
- * src/freeze.c: Likewise.
- * src/main.c: Likewise.
- * src/stackovf.c: Likewise.
- * tests/stackovf.test: Likewise.
- * doc/STYLE: Mention the change.
-
-2010-01-05 Eric Blake <ebb9@byu.net>
-
- Document new indentation policy.
- * HACKING: Document indentation policy.
- * .x-sc_prohibit_tab_based_indentation: New file.
- * cfg.mk (sc_prohibit_tab_based_indentation): New rule.
- * Makefile.am (syntax_check_exceptions): Ship exception.
-
- Switch to indentation by space, not tab.
- * .gitmodules: Convert leading tabs to spaces.
- * TODO: Likewise.
- * bootstrap: Likewise.
- * configure.ac: Likewise.
- * examples/WWW/m4lib/html.m4: Likewise.
- * examples/WWW/m4lib/layout.m4: Likewise.
- * examples/WWW/m4lib/menu.m4: Likewise.
- * ltdl/m4/debug.m4: Likewise.
- * ltdl/m4/gmp.m4: Likewise.
- * ltdl/m4/m4-obstack.m4: Likewise.
- * ltdl/m4/stackovf.m4: Likewise.
- * m4/builtin.c: Likewise.
- * m4/debug.c: Likewise.
- * m4/hash.c: Likewise.
- * m4/hash.h: Likewise.
- * m4/input.c: Likewise.
- * m4/m4.c: Likewise.
- * m4/m4module.h: Likewise.
- * m4/m4private.h: Likewise.
- * m4/macro.c: Likewise.
- * m4/module.c: Likewise.
- * m4/output.c: Likewise.
- * m4/path.c: Likewise.
- * m4/resyntax.c: Likewise.
- * m4/symtab.c: Likewise.
- * m4/syntax.c: Likewise.
- * m4/utility.c: Likewise.
- * modules/evalparse.c: Likewise.
- * modules/format.c: Likewise.
- * modules/gnu.c: Likewise.
- * modules/load.c: Likewise.
- * modules/m4.c: Likewise.
- * modules/m4.h: Likewise.
- * modules/mpeval.c: Likewise.
- * modules/perl.c: Likewise.
- * modules/stdlib.c: Likewise.
- * modules/time.c: Likewise.
- * src/freeze.c: Likewise.
- * src/m4.h: Likewise.
- * src/main.c: Likewise.
- * src/stackovf.c: Likewise.
- * tests/builtins.at: Likewise.
- * tests/freeze.at: Likewise.
- * tests/generate.awk: Likewise.
- * tests/modules.at: Likewise.
- * tests/others.at: Likewise.
- * tests/stackovf.test: Likewise.
- * tests/testsuite.at: Likewise.
-
- Update copyright year.
- All files impacted, via 'make update-copyright'. Additionally:
- * .gitignore: Ignore backup files.
-
- Prepare to bulk update copyright year.
- * gnulib: Update.
- * ltdl/m4/gnulib-cache.m4: Import update-copyright module.
- * cfg.mk (update-copyright-env): Enforce longhand behavior.
- * .x-update-copyright: New file.
- * Makefile.am (syntax_check_exceptions): Distribute exception.
- * ltdl/m4/debug.m4: Add FSF copyright.
- * ltdl/m4/m4-error.m4: Fix FSF name in copyright.
- * ltdl/m4/m4-getopt.m4: Likewise.
- * ltdl/m4/m4-gettext.m4: Likewise.
- * ltdl/m4/m4-obstack.m4: Likewise.
- * ltdl/m4/m4-regex.m4: Likewise.
- * ltdl/m4/m4-rename.m4: Likewise.
- * ltdl/m4/m4-syscmd.m4: Likewise.
- * modules/modtest.m4: Likewise.
- * modules/perl.m4: Likewise.
- * modules/shadow.m4: Likewise.
- * modules/stdlib.m4: Likewise.
- * modules/time.m4: Likewise.
- * modules/time2.m4: Likewise.
- * tests/iso8859.m4: Likewise.
-
- Use gnulib maintainer-makefile module.
- * ltdl/m4/gnulib-cache.m4: Import maintainer-makefile module.
- * cfg.mk (local-checks-to-skip): Drop changelog-check; add
- sc_cast_of_x_alloc_return_value.
- (gnu_ftp_host-alpha, gnu_ftp_host-beta, gnu_ftp_host-major)
- (gnu_rel_host): Delete; provided by maint.mk.
- (old_NEWS_hash): New macro.
- * .prev-version: New file.
- * .x-sc_require_config_h: Likewise.
- * .x-sc_require_config_h_first: Likewise.
- * Makefile.am (syntax_check_exceptions, EXTRA_DIST): Ship new
- files.
- * maint.mk: Remove from version control; use gnulib instead.
- * .gitignore: Update.
-
- Update to latest gnulib.
- * gnulib: Update.
- * ltdl/m4/gnulib-cache.m4: Import xoset.
- * m4/output.c (includes): Ensure that gnulib oset usage will
- call xalloc_die on memory failure.
- * Makefile.am (src/getopt.h): Update snippet from gnulib.
- (LINK_WARNING_H, ARG_NONNULL_H): New macros.
-
- Fix testsuite failure on newer glibc.
- * tests/testsuite.at (AT_CHECK_M4): Tolerate alternate getopt
- spellings.
- * tests/options.at (deprecated options, unknown option)
- (--debugmode): Adjust expected output accordingly.
- Reported by Ralf Wildenhues.
-
-2009-11-26 Eric Blake <ebb9@byu.net>
-
- Update to newer gnulib.
- * gnulib: Update.
- * ltdl/m4/gnulib-cache.m4: Import inttypes, setenv, and unsetenv
- modules.
- * modules/m4.c (m4_make_temp): Adjust gen_tempname client.
- * bootstrap (src_modules): Pick up getopt-gnu and its
- dependencies.
- * configure.ac (gl_VERSION_ETC): Support ./configure
- --with-packager.
- (AC_CHECK_FUNCS_ONCE): Rely on gnulib for setenv, unsetenv.
- * ltdl/m4/m4-getopt.m4: Rewrite to match current gnulib.
- * Makefile.am (src/getopt.h): Likewise.
- * modules/stdlib.c (setenv, unsetenv): Rely on gnulib.
-
-2009-08-24 Eric Blake <ebb9@byu.net>
-
- Pick up gnulib fixes for sub-process execution.
- * gnulib: Update.
- * tests/others.at (stdin and stdout closed): New test, to avoid
- regression introduced on 1.4 branch on 2008-07-17.
- * NEWS: Document the change.
-
- A status of 127 does not always imply esyscmd failure.
- * modules/gnu.c (esyscmd): Silence gnulib message; regression
- introduced 2009-03-13.
- * doc/m4.texinfo (Sysval): Test this.
- * NEWS: Document the change.
-
-2009-06-26 Eric Blake <ebb9@byu.net>
-
- Use bitrotate for hashing.
- * gnulib: Update to latest.
- * ltdl/m4/gnulib-cache.m4: Import bitrotate module.
- * m4/hash.c (m4_hash_string_hash): Use it.
-
- Fix description of limits on diversions.
- * doc/m4.texinfo (Diversions): Fix grammar. Be less pessimistic
- about limitations.
- * THANKS: Update.
- Reported by Elias Benali.
-
-2009-06-17 Eric Blake <ebb9@byu.net>
-
- Stress test for hash resizing.
- * tests/builtins.at (define): Enhance test.
-
-2009-06-15 Eric Blake <ebb9@byu.net>
-
- Document why bootstrap might touch state of tree.
- * bootstrap: Fix typos. Add comment.
- * HACKING: Add notes about this scenario.
- * gnulib: Update to latest version.
- * .gitignore: Track gnulib changes.
-
- Drop .cvsignore and redundant .gitignore files.
- * .cvsignore: Delete. We are moving further away from CVS.
- * build-aux/.cvsignore: Likewise.
- * doc/.cvsignore: Likewise.
- * examples/.cvsignore: Likewise.
- * ltdl/.cvsignore: Likewise.
- * m4/.cvsignore: Likewise.
- * modules/.cvsignore: Likewise.
- * po/.cvsignore: Likewise.
- * src/.cvsignore: Likewise.
- * tests/.cvsignore: Likewise.
- * .gitignore: Consolidate from other files.
- * build-aux/.gitignore: Delete, now that it is consolidated.
- * doc/.gitignore: Likewise.
- * examples/.gitignore: Likewise.
- * ltdl/.gitignore: Likewise.
- * m4/.gitignore: Likewise.
- * modules/.gitignore: Likewise.
- * po/.gitignore: Likewise.
- * src/.gitignore: Likewise.
- * tests/.gitignore: Likewise.
- * bootstrap: Simplify accordingly. Sync gnulib tree prior to
- libtoolize, to avoid libtool overwriting config.guess.
-
- Avoid compiler warning.
- * m4/macro.c (process_macro): Use correct type for isdigit.
-
-2009-06-13 Eric Blake <ebb9@byu.net>
-
- Avoid snprintf link failures.
- * ltdl/m4/gnulib-cache.m4: Import snprintf-posix module.
- Reported by Ralf Wildenhues.
-
-2009-06-12 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- Avoid pointer arithmetic on `void *'.
- * modules/m4.c (dump_symbol_CB): Cast obstack_base return value
- to `char *' before using it.
-
-2009-05-04 Eric Blake <ebb9@byu.net>
-
- Silence verbose testsuite runs.
- * tests/testsuite.at (m4_version_prereq): Bump to recent
- autoconf.git version where stdout-nolog was added.
- * tests/builtins.at (esyscmd, syscmd): Use new stdout-nolog.
- * tests/freeze.at (AT_TEST_FREEZE): Likewise.
- * tests/others.at (stderr closed): Likewise.
- * HACKING: Mention new requirement.
- * bootstrap: Likewise.
- Reported by Ralf Wildenhues.
-
-2009-04-21 Eric Blake <ebb9@byu.net>
-
- Be more explicit about default quoting characters.
- * doc/m4.texinfo (Quoted strings): Call out characters by name.
- * THANKS: Update.
- Suggested by Mehul Sanghvi.
-
-2009-04-16 Eric Blake <ebb9@byu.net>
-
- Use gnulib rename module.
- * ltdl/m4/gnulib-cache.m4: Import rename module. At the moment,
- we don't tickle either of the platform bugs that it fixes, but it
- is better to be safe than sorry.
-
- Require newer automake features.
- * configure.ac (AM_INIT_AUTOMAKE): Add dist-xz, color-tests,
- parallel-tests, and silent-rules. Drop dist-lzma.
- * HACKING: Update minimum requirements.
- * gnulib: Update to latest version.
-
- Mention release of 1.4.13.
- * NEWS: Update to match release on branch-1.4.
- * doc/m4.texinfo (History): Update release history.
- (copying): Finish conversion to GFDL 1.3, started 2008-11-04.
-
-2009-03-23 Eric Blake <ebb9@byu.net>
-
- Exploit git submodule by adding appropriate symlinks.
- * bootstrap: No longer copy files from gnulib.
- * COPYING: Change to symlink pointing into gnulib.
- * INSTALL: Likewise.
- * build-aux/compile: Likewise.
- * build-aux/config.guess: Likewise.
- * build-aux/config.sub: Likewise.
- * build-aux/depcomp: Likewise.
- * build-aux/install-sh: Likewise.
- * build-aux/mdate-sh: Likewise.
- * build-aux/missing: Likewise.
- * build-aux/texinfo.tex: Likewise.
- * .cvsignore: Reflect these changes.
- * .gitignore: Likewise.
- * build-aux/.cvsignore: New file.
- * build-aux/.gitignore: Likewise.
-
- Make gnulib a git submodule.
- * .gitmodules: New file.
- * gnulib: Record which version of gnulib has been tested.
- * bootstrap: Aid in submodule usage.
- * cfg.mk (gnulib_dir): Alter default location of gnulib.
- * HACKING: Mention how to use submodule.
-
-2009-03-21 Eric Blake <ebb9@byu.net>
-
- Use memcmp2 to simplify lexicographic comparisons.
- * ltdl/m4/gnulib-cache.m4: Import memcmp2.
- * modules/m4.c (dumpdef_cmp_CB): Use it.
-
-2009-03-19 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- Fix m4.1 build race, exposed by parallelism through GNUmakefile.
- * Makefile.am (SUBDIRS): Add doc.
- (Documentation rules): Move ...
- * doc/Makefile.am: ... to this new file.
- * configure.ac (AC_CONFIG_FILES): Generate doc/Makefile.
-
-2009-03-13 Eric Blake <ebb9@byu.net>
-
- Try to tolerate spaces in directory names in testsuite.
- * tests/null.m4: Provide shell quoting, in case __program__
- contains spaces.
-
- Fix awk script portability.
- * checks/get-them: In gsub, properly escape {.
- Reported by Gary V. Vaughan.
-
- Make bootstrap easier on Solaris.
- * bootstrap: Add GNULIB_SRCDIR. Useful when a wrapper script
- gnulib-tool exists earlier on the path to work around /bin/sh
- failure in parsing $GNULIB_SRCDIR/gnulib-tool.
-
-2009-03-13 Eric Blake <ebb9@byu.net>
-
- Allow configuration choice in syscmd shell.
- * ltdl/m4/m4-syscmd.m4: New file.
- * configure.ac (M4_SYSCMD): Use it to provide
- --with-syscmd-shell.
- (AC_CHECK_HEADERS_ONCE): No longer need to worry about
- <sys/wait.h>.
- * modules/m4.c (syscmd): Use it to avoid hard-coding the shell
- location.
- * modules/gnu.c (esyscmd): Likewise.
- * doc/m4.texinfo (Syscmd, Esyscmd): Document this.
- * README: Document new configure option.
- * NEWS: Likewise.
-
- Use gnulib pipe module instead of popen(3).
- * ltdl/m4/gnulib-cache.m4: Import pipe and wait-process modules.
- * modules/gnu.c (M4_SYSVAL_EXITBITS, M4_SYSVAL_TERMSIGBITS):
- Delete.
- (esyscmd): Rewrite with pipe module.
- Resolves a failure on AIX, reported by Gary V. Vaughan.
-
- Use gnulib execute module instead of system(3).
- * ltdl/m4/gnulib-cache.m4: Import execute module.
- * m4/utility.c (m4_info_name): New function.
- * m4/m4module.h (m4_info_name): New prototype.
- * modules/m4.c (syscmd): Rewrite with execute module.
- (M4_SYSVAL_EXITBITS, M4_SYSVAL_TERMSIGBITS, m4_sysval): Move
- computation...
- * modules/gnu.c (M4_SYSVAL_EXITBITS, M4_SYSVAL_TERMSIGBITS)
- (esyscmd): ...here.
- Resolves a failure on AIX, reported by Gary V. Vaughan.
-
-2009-03-05 Eric Blake <ebb9@byu.net>
-
- Improve web-manual maintainer rule.
- * maint.mk (web-manual): Factor package-specific detail...
- * cfg.mk (manual_title): ...to new variable.
-
-2009-02-23 Eric Blake <ebb9@byu.net>
-
- Speed up translit when from argument is short.
- * modules/m4.c (translit): Use memchr2 when possible.
- * tests/builtins.at (translit): Add tests.
- * NEWS: Document this.
-
-2009-02-18 Eric Blake <ebb9@byu.net>
-
- Prefer buffer over byte operations.
- * modules/format.c (format): Use memchr for speed.
- * modules/gnu.c (substitute): Likewise.
- * m4/macro.c (locate_dollar): Inline into only caller...
- (process_macro): ...and rearrange for readability.
- * m4/input.c (consume_buffer): Allow C++ compilation.
- * doc/m4.texinfo (Changesyntax): Enhance test.
-
- Speed up esyscmd with buffer reads.
- * modules/gnu.c (esyscmd): Read blocks directly into obstack,
- rather than repeatedly reading bytes. Detect read errors.
-
- Avoid risk of stack overflow.
- * m4/output.c (insert_file): Avoid stack allocation of large
- buffer.
-
- Synchronize THANKS with branch.
- * THANKS: Import more names.
-
- Improve handling of $ in syntax table.
- * m4/m4module.h (m4_is_syntax_single_dollar): New function.
- (M4_SYNTAX_DOLLAR, M4_SYNTAX_LBRACE, M4_SYNTAX_RBRACE): Change to
- be context rather than basic syntax categories.
- (M4_SYNTAX_MASKS): Adjust macro.
- * m4/m4private.h (struct m4_syntax_table): Add dollar and
- is_single_dollar members.
- (m4_is_syntax_single_dollar): Add fast alternative.
- * m4/syntax.c (m4_syntax_create, reset_syntax_set): Adjust to
- account for change to context categories.
- (m4_set_syntax): Manage is_single_dollar.
- (m4_is_syntax_single_dollar): New function.
- * m4/macro.c (locate_dollar): New helper function.
- (process_macro): Use it to speed up macro expansion.
- * m4/input.c (m4__next_token): Adjust client.
- * doc/m4.texinfo (Changesyntax): Document this.
-
-2009-02-17 Eric Blake <ebb9@byu.net>
-
- Sync changecom documentation with branch.
- * doc/m4.texinfo (Changecom): Tweak wording.
- * NEWS: Import changes from the branch.
-
- Stage 29b: Process quotes and comments by buffer, not bytes.
- Search for quote and comment delimiters by buffer when possible.
- Memory impact: none.
- Speed impact: noticeable improvement, from fewer function calls.
- * ltdl/m4/gnulib-cache.m4: Import memchr2 module.
- * m4/input.c (m4__next_token): Add buffer reads to quote and
- comment parsing.
- * NEWS: Document this.
-
-2009-02-16 Eric Blake <ebb9@byu.net>
-
- Stage 29a: Process dnl and macro names by buffer, not bytes.
- Enhance input engine to provide lookahead buffer, rather than
- forcing clients to call next_char for every byte. Utilize this
- for the simplest clients.
- Memory impact: none.
- Speed impact: noticeable improvement, from fewer function calls.
- * ltdl/m4/gnulib-cache.m4: Import freadptr and freadseek modules.
- * m4/input.c (struct input_funcs): Add virtual functions
- buffer_func and consume_func.
- (file_buffer, file_consume, string_buffer, string_consume)
- (composite_buffer, composite_consume, eof_buffer): Implement
- them.
- (file_funcs, string_funcs, composite_funcs, eof_funcs): Update
- vtables accordingly.
- (buffer_retry): New sentinel.
- (next_buffer, consume_buffer): New functions.
- (m4_skip_line, match_input, consume_syntax): Use them for faster
- parsing.
- Suggested by Bruno Haible.
-
- Unify single and multi-character delimiter handling.
- * m4/input.c (MATCH): Add a parameter.
- (m4__next_token): Simplify logic and reduce redundancy.
- (m4__next_token_is_open): Adjust caller.
- * m4/syntax.c (m4_set_comment, m4_set_quotes): Handle delimiters
- of differing lengths.
- (m4_set_syntax): Recognize restoration of single delimiters.
-
- Revamp changesyntax vs. changequote interactions.
- * m4/m4module.h (M4_SYNTAX_VALUE): Delete unused macro.
- (M4_SYNTAX_SUSPECT): New macro.
- * m4/m4private.h (struct m4_syntax_table): Add suspect field.
- * m4/syntax.c (check_is_single_quotes, check_is_single_comments)
- (check_is_macro_escaped): Delete, by inlining body...
- (m4_set_syntax): ...into here. Improves handling between
- changesyntax and changequote/changecom.
- (add_syntax_set, subtract_syntax_set, set_syntax_set): Simplify,
- and let suspect field track needed cleanup.
- (m4_set_quotes, m4_set_comment): Adjust meaning of
- is_single_quotes and is_single_comment flags to always be true if
- only one delimiter exists, regardless of its length. Ensure that
- the syntax categories M4_SYNTAX_LQUOTE and M4_SYNTAX_BCOMM are
- only used on 1-byte delimiters.
- (add_syntax_attribute, remove_syntax_attribute): Change signature
- to allow the use of fewer casts. Adjust the suspect field when
- necessary.
- (m4_reset_syntax, set_quote_age): Adjust callers.
- * m4/input.c (m4__next_token, m4__next_token_is_open): Simplify
- callers.
- * doc/m4.texinfo (Changesyntax): Update documentation and tests.
-
- Improve changesyntax documentation.
- * doc/m4.texinfo (Changesyntax): Merge two tables into one
- multitable.
-
- Fix regression in multicharacter quotes, from 2008-01-26.
- * m4/input.c (m4__next_token): Fix typo.
- * tests/builtins.at (changequote): Enhance test.
-
-2009-02-13 Eric Blake <ebb9@byu.net>
-
- Speed up parsing when detecting input file change.
- * m4/input.c (next_char): Clear input_change flag. Bug introduced
- 2006-10-25.
-
-2009-02-12 Eric Blake <ebb9@byu.net>
-
- Avoid quadratic code when walking definition stack.
- * examples/stack_sep.m4: Use linear, not quadratic
- implementation.
- * doc/m4.texinfo (Improved copy): Fix documentation, based on
- recent autoconf bug fix.
- * tests/others.at (recursion): Enhance test.
-
-2009-02-11 Eric Blake <ebb9@byu.net>
-
- Stage 28c: Warn on embedded NUL in remaining cases.
- Ensure all remaining warnings can handle embedded NUL.
- Memory impact: none.
- Speed impact: none noticed.
- * m4/m4module.h (m4_debug_decode, m4_parse_truth_arg): Add
- parameter.
- * m4/macro.c (m4_macro_call): Improve diagnostic.
- * modules/m4.c (defn): Likewise.
- * m4/debug.c (m4_debug_decode): Handle embedded NUL.
- * m4/utility.c (m4_parse_truth_arg): Likewise.
- * modules/format.c (arg_int, arg_long, arg_double): Likewise.
- (arg_string): New function.
- (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE): Update callers.
- * src/main.c (main): Likewise.
- * src/freeze.c (reload_frozen_state): Likewise.
- * modules/gnu.c (debugmode, syncoutput): Likewise.
- * tests/options.at (--regexp-syntax): Adjust test.
- * tests/freeze.at (reloading nul): Likewise.
- * tests/null.m4: Likewise.
- * tests/null.out: Likewise.
- * tests/null.err: Likewise.
-
- Stage 28b: Warn on embedded NUL in file arguments.
- Quote warning messages related to file and other NUL-terminated
- system commands.
- Memory impact: none.
- Speed impact: none noticed.
- * m4/path.c (m4_path_search): Quote file names in message.
- * modules/m4.c (syscmd, include, m4_make_temp): Handle embedded
- NUL.
- * modules/gnu.c (debugfile, esyscmd): Likewise.
- * tests/others.at (nul character): Adjust test.
- * tests/builtins.at (mkdtemp, mkstemp): Likewise.
- * tests/null.m4: Likewise.
- * tests/null.out: Likewise.
- * tests/null.err: Likewise.
-
- Stage 28a: Warn on embedded NUL in numeric arguments.
- Quote warning messages related to numeric parsing in order to
- handle embedded NUL.
- Memory impact: none.
- Speed impact: none noticed.
- * m4/m4module.h (m4_numeric_arg): Adjust prototype.
- * m4/utility.c (m4_numeric_arg): Add parameter.
- * modules/gnu.c (debuglen): Adjust callers.
- * modules/m4.c (incr, decr, divert, undivert, m4exit, substr)
- (index): Likewise.
- * modules/evalparse.c (m4_evaluate): Likewise.
- * modules/stdlib.c (setenv, getpwuid, srand): Likewise.
- * modules/time.c (ctime, gmtime, localtime, mktime, strftime):
- Likewise.
- * doc/m4.texinfo (Changesyntax): Fix typo.
- * tests/others.at (nul character): Adjust test.
- * tests/null.m4: Likewise.
- * tests/null.out: Likewise.
- * tests/null.err: Likewise.
-
-2009-02-11 Eric Blake <ebb9@byu.net>
-
- Avoid regression in popdef(undef).
- * doc/m4.texinfo (Trace): Enhance test, to cover regression
- recently fixed on the branch.
-
-2009-02-09 Eric Blake <ebb9@byu.net>
-
- Enhance index to support starting offset.
- * modules/m4.c (index): Add optional third argument.
- * NEWS: Document this.
- * doc/m4.texinfo (Index macro): Likewise.
- (Macro Arguments): Adjust tests.
-
-2009-01-24 Eric Blake <ebb9@byu.net>
-
- Add URLs to --help output.
- * src/main.c (usage): Use enhanced version-etc features.
-
-2009-01-07 Eric Blake <ebb9@byu.net>
-
- Enhance substr to support replacement text.
- * doc/m4.texinfo (Substr): Document new semantics.
- * modules/m4.c (substr): Support optional fourth argument.
- * NEWS: Document this.
-
- Enhance substr to support negative values.
- * doc/m4.texinfo (Substr): Document new semantics, and how to
- simulate old.
- * modules/m4.c (substr): Support negative values.
- * NEWS: Document this.
-
-2009-01-05 Eric Blake <ebb9@byu.net>
-
- Maintainer cleanups.
- * HACKING: Remove mention of xdelta.
- * Makefile.am (EXTRA_DIST, MAINTAINERCLEANFILES): Let gnulib take
- care of distributing gendocs.sh.
- * maint.mk (web-manual): Use new feature of gendocs.
- * ltdl/m4/gnulib-cache.m4: Regenerate.
-
-2008-12-24 Eric Blake <ebb9@byu.net>
-
- Relax eval as allowed by POSIX 2008.
- * modules/evalparse.c (m4_evaluate): Warn, not error, on invalid
- operator. Quote expression in warning.
- * modules/mpeval.c (includes): Add quotearg.h.
- * doc/m4.texinfo (Eval, Improved forloop): Update tests.
- * NEWS: Update to reflect 1.6 support for `?:'.
-
-2008-12-23 Eric Blake <ebb9@byu.net>
-
- Add debugmode(o) to control dumpdef output location.
- * m4/m4module.h (M4_DEBUG_TRACE_OUTPUT_DUMPDEF): New enumerator.
- (M4_DEBUG_TRACE_VERBOSE): Update.
- * m4/debug.c (m4_debug_decode): Support new debug option.
- * src/freeze.c (produce_debugmode_state): Likewise.
- * modules/m4.c (dumpdef): When set, force dumpdef to stderr rather
- than the debug file.
- * src/main.c (usage): Document it.
- * doc/m4.texinfo (Debugmode, Dumpdef, Debugging options)
- (Debugfile): Likewise.
- * NEWS: Likewise.
- Based on an autoconf bug report by Paolo Bonzini.
-
- Make --debugfile argument optional.
- * src/main.c (long_options): Make the argument optional, to allow
- setting debug file back to stderr.
- (main): Make --debugfile order-dependent.
- (usage): Document this.
- * doc/m4.texinfo (Debugging options): Likewise.
- * NEWS: Likewise.
- * tests/options.at (--debugfile): Enhance test.
- (--safer): Adjust to new semantics.
-
-2008-12-22 Eric Blake <ebb9@byu.net>
-
- Use @var correctly.
- * doc/m4.texinfo (Operation modes, Preprocessor features)
- (Limits control, Frozen state, Debugging options)
- (Dynamic loading features): Use lower case names in @var.
- (Improved copy): Use @code, not @var, as appropriate.
-
-2008-12-18 Eric Blake <ebb9@byu.net>
-
- Deal with M4 1.4.x limitation on builtin tokens.
- * doc/m4.texinfo (Composition): Mention limitation on curry.
- (Improved copy): New node.
- (Stacks): Fix typo.
- * examples/stack.m4: Likewise.
- * examples/stack_sep.m4: New file.
- * Makefile.am (dist_pkgdata_DATA): Distribute it.
-
-2008-12-15 Eric Blake <ebb9@byu.net>
-
- Double size of temp file cache.
- * m4/output.c (tmp_file, tmp_file_owner): Split...
- (tmp_file1, tmp_file2, tmp_file1_owner, tmp_file2_owner): ...into
- two variables.
- (tmp_file2_recent): New variable.
- (m4_tmpopen, m4_tmpclose, m4_tmpremove, m4_tmprename)
- (m4_output_exit): Adjust callers.
-
- Use fewer seeks on cached files.
- * m4/output.c (m4_tmpfile): Use write, not append mode.
- (m4_tmpopen): Add parameter to decide when to skip seeks.
- (m4_tmprename, m4_make_diversion, insert_diversion_helper)
- (m4_freeze_diversions): Adjust callers.
-
- Cache most recently spilled diversion.
- * m4/output.c (tmp_file, tmp_file_owner): New variables, for
- 1-deep cache of spilled diversions.
- (m4_tmpfile): Open in append mode, since we might revisit
- diversion without closing it now.
- (m4_tmpopen): Check cache first.
- (m4_tmpclose): Update cache, rather than closing. Add parameter.
- (m4_tmpremove): Close cache before removing.
- (m4_tmprename): Deal with open files when renaming.
- (m4_output_exit): Close cache before exiting.
- (make_room_for, m4_make_diversion, insert_diversion_helper):
- Adjust callers.
- * ltdl/m4/m4-rename.m4 (M4_RENAME): New file.
- * configure.ac (M4_RENAME): Invoke it.
-
- Correctly track size of in-memory diversions.
- * m4/output.c (insert_diversion_helper): Correctly track total
- in-memory diversion size after undivert.
-
- Avoid quadratic behavior for some cases of divert/undivert.
- * m4/output.c (struct m4_diversion): Improve comments.
- (m4_tmpname, m4_make_diversion): Strengthen preconditions.
- (m4_tmprename): New function.
- (m4_output_init, m4_output_exit): Move after internal functions.
- (make_room_for): Don't bother copying uninitialized bytes.
- (insert_diversion_helper): Transfer metadata, rather than copying
- contents, when undiverting into a previously unused diversion.
- * tests/builtins.at (divert): Add a check to the test.
- * doc/m4.texinfo (Undivert): Enhance test.
- * NEWS: Document the speedup.
-
-2008-12-02 Eric Blake <ebb9@byu.net>
-
- Stage 27: Allow embedded NUL in text processing macros.
- Pass NUL through regular expressions, format, and translit, and
- diagnose it in eval and changeresyntax. Improve warning
- capabilities of format.
- Memory impact: none.
- Speed impact: none noticed.
- * modules/m4.c (m4_expand_ranges): Don't append extra bytes.
- (translit): Manage NUL bytes.
- * modules/format.c (format): Likewise.
- * modules/gnu.c (substitute, regexp_substitute): Likewise.
- (m4_resyntax_encode_safe): Add parameter.
- (regexp, patsubst, renamesyms): Update callers.
- (regexp_compile): Adjust error message.
- * modules/evalparse.c (m4_evaluate): Use consistent message.
- (end_text): New variable.
- (eval_init_lex): Add parameter.
- (eval_lex): Detect embedded NUL.
- * src/freeze.c (reload_frozen_state): Likewise.
- * doc/m4.texinfo (Format): Update to cover new behavior.
- (Eval): Mention that result is unquoted.
- * tests/freeze.at (reloading nul): Enhance test.
- * tests/null.m4: Likewise.
- * tests/null.err: Update expected output.
- * tests/null.out: Likewise.
- * tests/options.at (--regexp-syntax): Likewise.
-
-2008-11-28 Eric Blake <ebb9@byu.net>
-
- Resync NEWS with branches.
- * NEWS: Mention 1.4.12, update state of 1.6.
-
-2008-11-26 Eric Blake <ebb9@byu.net>
-
- Keep COPYING in repository.
- * Makefile.am (MAINTAINERCLEANFILES): Don't remove COPYING.
- * .cvsignore: Don't ignore it.
- * .gitignore: Likewise.
- * COPYING: Store in repository, per automake 1.10.2
- recommendation.
-
-2008-11-26 Eric Blake <ebb9@byu.net>
-
- Document optimized forloop.
- * doc/m4.texinfo (Improved forloop): Mention alternate style that
- avoids define overhead.
- * examples/forloop3.m4: New file.
- * Makefile.am (dist_pkgdata_DATA): Distribute it.
-
- Document copy composite using stack_foreach and curry.
- * doc/m4.texinfo (Stacks): New node, to document pushdef stack
- manipulation.
- (Ifelse): Move define_blind...
- (Composition): ...to this new node. Document currying, then use
- it to implement copy and rename.
- * examples/curry.m4: New file.
- * examples/stack.m4: Likewise.
- * Makefile.am (dist_pkgdata_DATA): Distribute them.
-
-2008-11-04 Eric Blake <ebb9@byu.net>
-
- Upgrade to FDL 1.3.
- * ltdl/m4/gnulib-cache.m4: Replace fdl module with fdl-1.3.
- * Makefile.am (doc_m4_TEXINFOS, MAINTAINERCLEANFILES): Reflect
- file change.
- * doc/m4.texinfo (GNU Free Documentation License): Likewise.
-
-2008-10-22 Eric Blake <ebb9@byu.net>
-
- Give nicer error if user modifies testsuite but lacks autoconf.
- * Makefile.am (AUTOM4TE): Use missing in the definition.
-
-2008-10-09 Eric Blake <ebb9@byu.net>
-
- Allow user to choose which sed to use in testsuite.
- * tests/atlocal.in (SED): Inherit from configure results.
- * tests/builtins.at (__m4_@&t@version__, divert, esyscmd)
- (mkstemp, syscmd): Use $SED.
- * tests/generate.awk (new_test): Likewise.
- * tests/options.at (deprecated options, unknown option)
- (--debugmode, --help and --version): Likewise.
- * tests/testsuite.at (AT_CHECK_M4): Likewise.
- * tests/others.at (directory, stderr closed, stdin seekable)
- (stdout closed): Likewise.
- (nul character): Likewise. Also, skip test if sed can't handle
- NUL bytes.
-
- Clean up testsuite invocation.
- * tests/atlocal.in: Fix copyright notice.
- * Makefile.am (TESTS_ENVIRONMENT): Delete; it wasn't being used.
- (check-local, installcheck-local): Adjust clients. Add missing
- dependency.
-
-2008-09-25 Eric Blake <ebb9@byu.net>
-
- Tweak error message on command line failure.
- * m4/m4private.h (includes): Use "quotearg.h".
- * src/main.c (process_file, main): Use nicer quotes for file name
- in error messages.
- * m4/input.c (file_clean, m4_push_file): Likewise.
- * m4/module.c (m4__module_open): Likewise.
- * src/freeze.c (produce_frozen_state, reload_frozen_state):
- Likewise.
- * modules/gnu.c (debugfile): Likewise.
- * modules/m4.c (undivert, include): Likewise.
- * tests/others.at (directory, stdin closed): Update tests.
- * tests/options.at (file names, --debugmode): Likewise.
- * doc/m4.texinfo (Debugmode): Likewise.
-
- Unify error handling for reading directories.
- * m4/path.c (m4_path_search): Factor open attempts...
- (m4_fopen): ...into new function, to reject directories.
- * tests/others.at (directory): Enhance test.
- * doc/m4.texinfo (Include): Document that directories cannot be
- input files.
-
- Avoid bugs on platforms that mishandle trailing /.
- * ltdl/m4/gnulib-cache.m4: Import fopen module.
- * tests/others.at (directory): New test.
-
-2008-09-16 Eric Blake <ebb9@byu.net>
-
- Fix bootstrap for Solaris /bin/sh.
- * bootstrap: Avoid shell quoting pitfall.
-
-2008-09-01 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- Typos in source code comments.
- * modules/m4.c: Fix typos in comments.
- * m4/input.c: Likewise.
- * src/main.c: Likewise.
-
-2008-08-29 Eric Blake <ebb9@byu.net>
-
- Fix manual date information.
- * doc/m4.texinfo: UPDATED refers to the day the manual was built,
- not the release date of M4.
- Based on a bison patch by Akim Demaille.
-
-2008-08-27 Eric Blake <ebb9@byu.net>
-
- Tweak -d examples.
- * doc/m4.texinfo (Invoking m4): Fix example, since order of -d
- matters.
- (Dumpdef): Fix typo.
-
-2008-08-23 Eric Blake <ebb9@byu.net>
-
- Allow debugmode control over whether defn(undef) warns.
- * ltdl/m4/gnulib-cache.m4: Import verify module.
- * m4/m4module.h (M4_DEBUG_TRACE_DEREF, M4_DEBUG_TRACE_INITIAL):
- New values.
- (M4_DEBUG_TRACE_VERBOSE, M4_DEBUG_TRACE_DEFAULT): Adjust.
- * m4/m4.c (m4_create): Start with debugmode = d.
- * src/main.c (usage): Mention this.
- (main): Let -E impact debug mode.
- * m4/utility.c (m4_symbol_value_lookup): Squelch undefined warning
- if flag is clear.
- * modules/gnu.c (builtin, inder): Likewise.
- * m4/debug.c (m4_debug_decode): Parse new mode.
- * src/freeze.c (produce_debugmode_state): Accomodate new mode.
- * doc/m4.texinfo (Debugging options): Mention change in the
- default behavior.
- (Debugmode): Mention new flag d.
- (Operation modes): Mention interaction with -E.
- (Undefine, Defn, Pushdef, Indir, Builtin, Dumpdef): Document and
- test its effect.
- * tests/options.at (--debugmode): Update tests.
- * tests/freeze.at (reloading debugmode): Likewise.
- * NEWS: Document this.
- Reported by Ralf Wildenhues; without this patch, M4 1.6+ would be
- incompatible with Autoconf 2.62.
-
-2008-08-22 Eric Blake <ebb9@byu.net>
-
- Improve --debugmode behavior.
- * m4/m4module.h (m4_debug_decode): Simplify interface.
- * m4/debug.c (m4_debug_decode): Remove parameter, and handle
- setting the new value.
- * modules/gnu.c (debugmode): Adjust caller.
- * src/freeze.c (reload_frozen_state): Likewise.
- * src/main.c (main): Likewise.
- (usage): Fix default for --debug.
- * doc/m4.texinfo (Debugging options): Add an example.
-
-2008-08-21 Eric Blake <ebb9@byu.net>
-
- Avoid regression in defn(undef).
- * doc/m4.texinfo (Trace): Enhance test, to cover regression
- recently fixed on the branch.
-
-2008-08-18 Eric Blake <ebb9@byu.net>
-
- Remove deprecated -N option; fixes a regression from 2006-09-14.
- * src/main.c (DIVERSIONS_OPTION): Delete.
- (long_options, OPTSTRING, main): Remove -N/--diversions option.
- * doc/m4.texinfo (Limits control): Remove it from the manual.
- * NEWS: Mention that it is gone.
- * tests/options.at (deprecated options): Update test.
-
- Improve 'git diff' of manual source.
- * .gitattributes (*.texi*): Add diff attribute.
- * bootstrap: Tell git how to use it.
- Inspired by Jim Meyering's similar patch for coreutils.
-
-2008-08-07 Bruno Haible <bruno@clisp.org> (tiny change)
-
- Run m4 tests prior to gnulib unit tests.
- * Makefile.am (SUBDIRS): Swap order of directories.
-
-2008-08-03 Eric Blake <ebb9@byu.net>
-
- Stage 26: Allow embedded NUL in macro definitions.
- Clean up final few locations that did not track macro definitions
- by length, to allow embedded NUL. Make m4_arg_len callers aware
- of issue of flattening builtins when determining length.
- Memory impact: none.
- Speed impact: none noticed.
- * m4/m4module.h (m4_arg_len): Add parameter.
- (M4ARGLEN): Provide default for the parameter.
- * m4/m4private.h (includes): Share xmemdup0.h among all libm4
- files.
- * m4/macro.c (m4_arg_len): Fail if builtins are not flattened.
- * m4/syntax.c (includes): Rely on m4private.h for xmemdup0.
- * m4/symtab.c (includes): Likewise.
- (m4_symbol_value_copy): Use xmemdup0.
- * m4/module.c (install_macro_table): Likewise.
- * src/freeze.c (reload_frozen_state): Likewise.
- * tests/freeze.at (reloading nul): Enhance test.
- * tests/null.m4: Likewise.
- * tests/null.err: Update expected output.
- * tests/null.out: Likewise.
-
- Fix regression in commenting unbalanced quotes, from 2008-02-16.
- * m4/m4private.h (m4__token_type): Add M4_TOKEN_COMMENT.
- * m4/input.c (m4__next_token, m4_print_token): Supply new token
- type for comments.
- * m4/macro.c (expand_token): Penalize comments, as they can
- contain unbalanced quotes; latent bug since 2007-12-07, exposed by
- passing $@ references built from comments.
- (expand_argument): Adjust caller.
- * tests/others.at (Comments): Enhance test to catch it.
- * NEWS: Mention the fix.
-
-2008-07-30 Eric Blake <ebb9@byu.net>
-
- Fix regression in trace output, introduced 2008-05-08.
- * m4/input.c (m4__push_symbol): When cloning chains, break pointer
- back to original chain; latent bug from 2008-02-02 that did not
- cause misbehavior until trace output read unfinished chain.
- * tests/builtins.at (debug): Add test for this.
-
-2008-07-28 Eric Blake <ebb9@byu.net>
-
- Optimize iteration examples.
- * examples/forloop2.m4: Avoid excess indir, by passing current
- counter value as parameter.
- * examples/foreachq3.m4: Avoid unneeded ifelse, by injecting an
- ignored argument.
- * doc/m4.texinfo (Improved forloop, Improved foreach): Update the
- documentation to match.
-
-2008-07-26 Eric Blake <ebb9@byu.net>
-
- Give example for O(n) foreach on m4 1.4.x.
- * examples/foreachq4.m4: New file.
- * Makefile.am (dist_pkgdata_DATA): Distribute it.
- * tests/others.at (recursion): Test it.
- * doc/m4.texinfo (Improved foreach): Document linear foreach with
- m4 1.4.5 and greater.
-
-2008-07-19 Eric Blake <ebb9@byu.net>
-
- Resynchronize docs from branch.
- * doc/m4.texinfo (Undefine, Pushdef): Mention warning on undefined
- name, particularly since the old documentation didn't match code.
- (Standard Modules): Add caveat about using __m4_version__.
-
-2008-07-11 Eric Blake <ebb9@byu.net>
-
- Bump required automake to 1.10a; regression introduced 2008-01-22.
- * configure.ac (AM_INIT_AUTOMAKE): Undo requirement downgrade to
- 1.10.1, since we also rely on pkglibexecdir.
- * HACKING: Fix minimum requirement.
- * bootstrap: Likewise.
- * THANKS: Update.
- Reported by Joel E. Denny.
-
- Avoid bogus whitespace in @ovar, @dvar.
- * doc/m4.texinfo (ovar, dvar): Add @c.
- Based on patch by Ralf Wildenhues to Autoconf manual.
-
-2008-06-23 Eric Blake <ebb9@byu.net>
-
- Adjust to new gnulib-tool layout.
- * ltdl/m4/gnulib-cache.m4: Reformat.
-
- Fix bootstrap comment.
- * bootstrap: DOWNLOAD_PO was previously removed.
-
-2008-06-19 Eric Blake <ebb9@byu.net>
-
- Revert speed regression from 2008-06-16.
- * m4/output.c (m4_shipout_int): Avoid obstack_printf in hot path.
- * modules/m4.c (numb_obstack): Likewise.
- * m4/input.c (MATCH): Use fewer conditionals, and factor
- adjustment of S...
- (match_input): ...here for smaller code size.
- * m4/syntax.c (m4_reset_syntax, m4_set_quotes, m4_set_comment):
- Supply trailing NUL to delimiters, to meet contract of faster
- MATCH.
-
-2008-06-18 Eric Blake <ebb9@byu.net>
-
- Whitespace cleanup.
- * m4/m4module.h: Use consistent spacing for pointer parameters.
- * m4/m4private.h: Likewise.
-
- Stage 25b: Handle embedded NUL in changesyntax and friends.
- Track quote and comment delimiters by length, to allow embedded
- NUL. Improve changesyntax to support assigning syntax to NUL.
- Memory impact: none.
- Speed impact: none noticed.
- * m4/m4module.h (m4_set_quotes, m4_set_comment, m4_set_syntax):
- Add parameter.
- (m4_reset_syntax): New prototype.
- * m4/syntax.c (add_syntax_set, subtract_syntax_set)
- (set_syntax_set, m4_set_quotes, m4_set_comment): Add parameter, to
- handle embedded NUL.
- (m4_set_syntax): Likewise. Also, split code to reset the table...
- (m4_reset_syntax): ...into a new function.
- (m4_syntax_create): Adjust callers.
- * m4/input.c (match_input, MATCH): Add parameter.
- (m4__next_token, m4__next_token_is_open): Adjust callers.
- * modules/m4.h (m4_expand_ranges_func): Add parameter.
- * modules/m4.c (dumpdef): Handle NUL in dumped quotes.
- (changequote, changecom, translit, m4_expand_ranges): Track
- delimiter length.
- * modules/gnu.c (changesyntax): Handle embedded NUL.
- * src/freeze.c (reload_frozen_state): Adjust callers.
- * tests/freeze.at (reloading nul): Enhance test.
- * tests/null.m4: Likewise.
- * tests/null.out: Update expected output.
- * tests/null.err: Likewise.
-
-2008-06-16 Eric Blake <ebb9@byu.net>
-
- Stage 25a: Use obstack_printf for easier output.
- Convert macro tracing and other locations to use obstack_printf
- rather than hand-rolled equivalents. Ensure that embedded NUL in
- trace output does not truncate the trace string.
- Memory impact: none.
- Speed impact: noticeable penalty, from obstack_printf overhead.
- * ltdl/m4/gnulib-cache.m4: Import obstack-printf-posix module.
- * m4/macro.c (trace_format): Delete; use obstack_printf instead.
- (trace_header, trace_pre, trace_post): All callers updated.
- * m4/output.c (m4_shipout_int, m4_tmpname): Use obstack_printf.
- (m4_divert_text): Speed up syncline output.
- * modules/m4.c (dumpdef): Handle embedded NUL.
- (numb_obstack): Speed up eval output.
- (maketemp): Use obstack_printf.
- * modules/format.c (format): Likewise.
-
- Add missing const qualifications.
- * m4/resyntax.c (m4_resyntax_map): Declare array elements as
- const.
- * modules/gnu.c (m4_builtin_table, m4_macro_table): Likewise.
- * modules/import.c (m4_builtin_table): Likewise.
- * modules/load.c (m4_builtin_table, m4_macro_table): Likewise.
- * modules/m4.c (m4_builtin_table): Likewise.
- * modules/modtest.c (m4_builtin_table, m4_macro_table): Likewise.
- * modules/mpeval.c (m4_builtin_table, m4_macro_table): Likewise.
- * modules/perl.c (m4_builtin_table, m4_macro_table): Likewise.
- * modules/shadow.c (m4_builtin_table, m4_macro_table): Likewise.
- * modules/stdlib.c (m4_builtin_table): Likewise.
- * modules/time.c (m4_builtin_table): Likewise.
- * modules/traditional.c (m4_macro_table): Likewise.
-
-2008-06-10 Eric Blake <ebb9@byu.net>
-
- Avoid corrupted frozen file if NUL appears on block boundary.
- * m4/output.c (insert_file): Separate consecutive quotearg blocks
- with \<newline>, in case last byte of first block was NUL.
-
-2008-06-03 Eric Blake <ebb9@byu.net>
-
- Fix printf type mismatches.
- * m4/m4module.h (m4_bad_argc): Alter parameter type.
- * m4/m4private.h (struct m4_call_info): Alter call_id type.
- * m4/macro.c (expand_macro, m4__adjust_refcount): Use correct
- specifiers.
- * m4/utility.c (m4_bad_argc): Likewise.
-
- Borrow bootstrap ideas from gnulib.
- * bootstrap (options, DOWNLOAD_PO): Remove --download-po; the
- advertized subset of languages didn't work. Use --skip-po
- instead, for consistency with gnulib bootstrap.
- (func_get_translations): Use rsync, not wget.
- (func_update_po): Use a reference directory, to avoid changing
- timestamps on unchanged .po files.
- * TODO: Update accordingly.
-
- Fix fallout from previous patch.
- * doc/m4.texinfo (Builtin): Adjust expected output.
-
-2008-06-02 Eric Blake <ebb9@byu.net>
-
- Stage 24c: Improve display of macro names with embedded NUL.
- Quote instances of problematic characters in macro names when
- presented to user. Track location via call_info rather than
- munging context for every expansion.
- Memory impact: none.
- Speed impact: slight penalty, due to more bookkeeping.
- * m4/m4module.h (m4_push_string_init): Add parameters.
- * m4/m4private.h (struct m4_macro_args): Remove argv0 and
- argv0_len, now redundant with info.
- (m4__push_wrapup_init): Add parameter.
- * m4/input.c (m4_push_string_init, m4__push_wrapup_init): Track
- location from caller, rather than context.
- (composite_peek, composite_read, match_input): Adjust callers.
- * m4/utility.c (m4_symbol_value_lookup): Quote macro name.
- (m4_verror_at_line): Allow NUL in macro name.
- * m4/macro.c (trace_flush, m4_trace_prepare, trace_pre): Allow NUL
- in trace.
- (expand_macro): No longer munge context location.
- (collect_arguments, m4_arg_text, m4_arg_empty, m4_arg_len)
- (m4_make_argv_ref, m4_push_arg, m4_wrap_args): Adjust callers.
- * modules/gnu.c (builtin, indir): Likewise.
- * tests/null.m4: Enhance test.
- * tests/null.err: Adjust expected output.
- * tests/null.out: Likewise.
-
- Stage 24b: Allow embedded NUL in macro names.
- Use length rather than NUL-termination when tracking macro names.
- All APIs dealing with symbol table changed.
- Memory impact: none.
- Speed impact: slight penalty, due to more bookkeeping.
- * m4/m4module.h (m4_symtab_apply_func, m4_symbol_lookup)
- (m4_symbol_pushdef, m4_symbol_define, m4_symbol_popdef)
- (m4_symbol_rename, m4_symbol_delete): Add length parameter.
- (m4_string): New type.
- * ltdl/m4/gnulib-cache.m4: Import xmemdup0 module.
- * m4/hash.c (m4_hash_string_hash, m4_hash_string_cmp): Account for
- length.
- * m4/symtab.c (m4_symtab_delete, m4_symtab_apply, symtab_fetch)
- (m4__symtab_remove_module_references, symbol_destroy_CB)
- (m4_symbol_lookup, m4_symbol_pushdef, m4_symbol_define)
- (m4_symbol_popdef, m4_symbol_rename, m4_set_symbol_name_traced)
- (m4_symbol_delete): Likewise.
- * modules/m4.h (struct m4_dump_symbol_data): Adjust type to allow
- passing length.
- * m4/macro.c (expand_token): Adjust all callers.
- * m4/module.c (install_builtin_table, install_macro_table):
- Likewise.
- * m4/utility.c (m4_symbol_value_lookup): Likewise.
- * modules/gnu.c (indir, renamesyms, m4symbols): Likewise.
- * modules/m4.c (define, undefine, pushdef, popdef)
- (dumpdef_cmp_CB, dump_symbol_CB, m4_dump_symbols, dumpdef)
- (traceon, traceoff): Likewise.
- * src/main.c (main): Likewise.
- * src/freeze.c (dump_symbol_CB, reload_frozen_state): Likewise.
- * tests/freeze.at (reloading nul): Augment test.
- * tests/null.out: Adjust expected output.
-
- Stage 24a: Use full call context in error reporting.
- Replace const char *macro_name with const m4_call_info *call, so
- that the next patch can pass the length of macro_name with
- embedded NUL. Simplifies handling of global state.
- Memory impact: none.
- Speed impact: none noticed.
- * m4/m4module.h (m4_error, m4_warn): Change parameter type.
- (m4_error_at_line, m4_warn_at_line): Delete.
- (m4_debug_set_output, m4_skip_line, m4_bad_argc, m4_numeric_arg)
- (m4_parse_truth_arg, m4_symbol_value_lookup): Adjust all clients.
- * m4/m4private.h (m4__next_token): Likewise.
- * m4/utility.c (m4_verror_at_line): Alter parameter, and use
- caller's location if caller is provided.
- (m4_error, m4_warn): Change parameter type.
- (m4_error_at_line, m4_warn_at_line): Delete.
- (m4_bad_argc, m4_numeric_arg, m4_parse_truth_arg)
- (m4_symbol_value_lookup): Adjust all callers.
- * m4/debug.c (set_debug_file, m4_debug_set_output): Likewise.
- * m4/input.c (m4_skip_line, m4__next_token): Likewise.
- * m4/macro.c (expand_argument, collect_arguments, m4_macro_call)
- (process_macro): Likewise.
- * modules/m4.h (m4_make_temp_func): Likewise.
- * modules/evalparse.c (m4_evaluate): Likewise.
- * modules/format.c (arg_int, arg_long, arg_double, format):
- Likewise.
- * modules/gnu.c (builtin, changeresyntax, changesyntax, debugfile)
- (debuglen, debugmode, esyscmd, indir, mkdtemp, patsubst, regexp)
- (renamesyms, syncoutput, regexp_compile, substitute)
- (regexp_substitute, m4_resyntax_encode_safe): Likewise.
- * modules/m4.c (define, undefine, pushdef, popdef, ifdef, ifelse)
- (m4_dump_symbols, defn, syscmd, incr, decr, divert, undivert, dnl)
- (include, maketemp, mkstemp, m4exit, traceon, traceoff, substr):
- Likewise.
- * modules/stdlib.c (setenv, getpwuid, srand): Likewise.
- * modules/time.c (ctime, gmtime, localtime, mktime, strftime):
- Likewise.
- * tests/options.at (--syncoutput): Add test for invalid
- command-line argument. Split xfailed portion...
- (--syncoutput and diversions): ...into new test.
- (unknown option): New test.
- * tests/freeze.at (reloading unknown builtin): Update expected
- output.
-
- Adjust to recent gnulib change.
- * configure.ac (AB_INIT): Delete, now that gnulib does this.
-
-2008-05-28 Eric Blake <ebb9@byu.net>
-
- Improve frozen debugmode behavior.
- * m4/debug.c (m4_debug_decode): Make empty debugmode additive.
- * src/main.c (main): Interleave -d with files.
- * tests/options.at (--debugmode): Update test.
- * tests/freeze.at (reloading debugmode): New test.
- * doc/m4.texinfo (Debugging options, Debugmode): Document the
- change.
- * NEWS: Likewise.
-
-2008-05-27 Eric Blake <ebb9@byu.net>
-
- Fix some testsuite failures on Solaris 8.
- * tests/builtins.at (esyscmd, syscmd): Skip tests if system(2) is
- broken.
- * tests/others.at (stderr closed): Likewise. Also support Solaris
- wording for EBADF.
- (stdin closed): Skip test if closed stdin gets reopened.
- (stdout closed): Support Solaris wording for EBADF.
- * tests/testsuite.at (AT_CHECK_M4): Likewise.
-
- Fix configure message nesting, broken since 2001-09-20.
- * ltdl/m4/gmp.m4 (M4_LIB_GMP): Don't cache result; the test is
- not expensive, and AC_MSG_WARN doesn't work in AC_CACHE_CHECK.
-
- Support 'make dist' with BSD make.
- * Makefile.am (TESTSUITE_AT, MAINTAINERCLEANFILES): Qualify uses
- of the generated file tests/generated.at.
- (EXTRA_DIST, $(TESTSUITE)): Likewise for tests/package.m4.
- * tests/others.at (stdout closed): Accomodate OpenBSD /bin/sh.
-
-2008-05-24 Eric Blake <ebb9@byu.net>
-
- Test NUL in frozen files.
- * tests/testsuite.at (AT_CHECK_M4): Add parameter.
- * tests/freeze.at (reloading nul): New test.
- (AT_TEST_FREEZE): Inhibit -d when reloading frozen file.
- (reloading unknown builtin): Likewise.
-
-2008-05-23 Eric Blake <ebb9@byu.net>
-
- Improve handling of frozen file errors.
- * src/freeze.c (produce_frozen_state): Detect write failures.
- (reload_frozen_state): Use close_stream.
- * tests/freeze.at (freezing failure): New test.
- * THANKS: Update.
- Reported by Jean-Charles Longuet.
-
-2008-05-19 Eric Blake <ebb9@byu.net>
-
- In frozen file, split consecutive strings with newline.
- * src/freeze.c (dump_symbol_CB): Add newline to 'T', 'F'.
- (produce_frozen_state): Likewise for 'Q', 'C'.
- (reload_frozen_state): Parse the new layout.
- [GET_DIRECTIVE]: Fix format 1 regression from 2008-05-13.
- * tests/freeze.at (loading format 2): Rewrite to new format.
- (reloading unknown builtin): Likewise.
- (loading format 1): Make sure backslash-newline is not
- interpreted.
- * doc/m4.texinfo (Frozen file format 2): Document the format.
- * NEWS: Document this change.
-
- Fix xgettext options.
- * po/Makevars (XGETTEXT_OPTIONS): The " must be passed to
- xgettext.
-
- Fix spelling of René Seindal's name in --version output.
- * ltdl/m4/gnulib-cache.m4: Import propername module.
- * src/main.c (AUTHORS): Rewrite in terms of proper_name.
- * po/Makevars (XGETTEXT_OPTIONS): Detect new functions.
- * HACKING: Mention new prerequisite of gperf.
-
-2008-05-18 Eric Blake <ebb9@byu.net>
-
- Allow freezing the trace status of macros.
- * src/freeze.c (produce_symbol_dump): Let undefined traced macros
- through.
- (dump_symbol_CB): Also freeze trace state.
- * tests/freeze.at (reloading traced macros): New test.
- * doc/m4.texinfo (Using frozen files): Update documentation to
- mention new state.
- (Frozen file format 1): Improve synchronization with branch.
- (Frozen file format 2): Reorder directives, and add `d', `t'.
- * NEWS: Document this change.
-
-2008-05-15 Eric Blake <ebb9@byu.net>
-
- Fix frozen file regression in pushdef stacks from 2001-09-01.
- * src/freeze.c (dump_symbol_CB): Push all values on the stack, not
- just the current definition.
- (reverse_symbol_value_stack): New helper method.
- * tests/freeze.at (AT_TEST_FREEZE): New helper macro.
- (reloading pushdef stack): New test.
- (reloading unknown builtin): Enhance test.
-
-2008-05-13 Eric Blake <ebb9@byu.net>
-
- Fix frozen file regression in diversions from 2007-01-21.
- * m4/output.c (insert_diversion_helper): Add parameter.
- (m4_insert_file): Move contents...
- (insert_file): ...to this new helper, with added parameter.
- (m4_insert_diversion, m4_undivert_all, m4_freeze_diversions):
- Update callers.
- * src/freeze.c (produce_mem_dump): Simplify.
- * tests/freeze.at (large diversion): Test for this.
-
- Improve error message when frozen file is invalid.
- * src/freeze.c (decode_char): Add parameter. Allow \<newline>
- line continuations.
- (reload_frozen_state): Track current line.
- * tests/freeze.at (loading format 1, loading format 2): Update to
- test this.
-
-2008-05-10 Eric Blake <ebb9@byu.net>
-
- Detect integer overflow when loading frozen file.
- * src/freeze.c (reload_frozen_state) [GET_NUMBER]: Rewrite to fail
- immediately on overflow.
- * tests/freeze.at (loading format 2): Test this.
- Reported by Jim Meyering.
-
-2008-05-08 Eric Blake <ebb9@byu.net>
-
- Stage 23: allow tracing of indirect macro calls.
- Track all trace information as part of the argv struct, rather
- than temporarily resetting global state. Teach indir to trace
- macros that it invokes.
- Memory impact: slight penalty, due to larger argv struct.
- Speed impact: none noticed.
- * m4/m4module.h (m4_input_block): Remove.
- (m4_call_info): New opaque type.
- (m4_trace_prepare, m4_arg_info): New prototypes.
- (m4_macro_call, m4_push_string_finish, m4_input_print): Change
- prototypes.
- * m4/m4private.h (struct m4_macro_args): Add info field.
- (struct m4_call_info): New structure.
- (m4_arg_info): New accessor.
- * m4/input.c (m4_input_block): Make typedef local.
- (m4_push_string_init): Initialize length.
- (m4_push_string_finish, m4_input_print): Change signature, so that
- printing can be done before finalization.
- (struct input_funcs): Add parameter to print_func.
- (file_print, string_print, composite_print): Adjust accordingly.
- * m4/macro.c (trace_header, trace_flush, trace_pre, trace_post):
- Change signatures for stacked trace messages, and for using call
- context.
- (trace_prepre): Export and rename...
- (m4_trace_prepare): ...to this, for use by indir. Alter signature
- to use call context.
- (collect_arguments): Alter signature, to manage new field.
- (expand_macro): Change call context management. Move tracing...
- (m4_macro_call): ...here. Remove redundant parameter.
- (m4_arg_argc): New function.
- (m4_make_argv_ref): Replace unused skip parameter with new trace
- parameter; manage new field.
- * modules/gnu.c (builtin, indir): Adjust callers.
- * src/main.c (usage): Update debugmode flag summary.
- * tests/null.m4: Enhance test.
- * tests/null.err: Update expected output.
- * tests/macros.at (Tracing Hanoi Towers): Likewise.
- * doc/m4.texinfo (Trace): Mention more about trace formatting.
- (Debugmode): Enhance description of 'c' and 'x'. Enhance test to
- cover line numbering details in traces.
- (Debuglen): Enhance test to cover indir tracing.
- * NEWS: Mention these changes.
- Reported by Akim Demaille in the autoconf TODO file in 2000.
-
-2008-05-07 Eric Blake <ebb9@byu.net>
-
- Test for traceon regression just fixed in branch-1.6.
- * doc/m4.texinfo (Trace): Enhance test.
- * NEWS: Port news item from branch.
-
-2008-05-05 Eric Blake <ebb9@byu.net>
-
- Stage 22: allow builtin token concatenation outside $@.
- Adjust the input and argument parsing engines to append builtins
- alongside text. Make define warn when builtins must be
- flattened.
- Memory impact: slight penalty, with fewer builtins flattened.
- Speed impact: slight penalty, from more bookkeeping.
- * m4/m4module.h (m4_is_arg_composite): New prototype.
- (m4_symbol_value_copy): Change return type.
- (m4_arg_text): Add parameter.
- (M4ARG): Adjust callers.
- * m4/m4private.h: Adjust comments.
- * m4/symtab.c (m4_symbol_value_copy): Detect when builtins are
- flattened.
- * m4/input.c (init_builtin_token): Add parameter, and allow
- concatenating builtins.
- (m4__next_token): Adjust caller.
- * m4/macro.c (m4_is_arg_composite): New function.
- (expand_argument): Allow builtin concatenation.
- (m4_arg_text): Add parameter.
- (m4__arg_adjust_refcount, m4__arg_print): Adjust callers.
- (m4_arg_equal): Fix comparison of builtin tokens.
- * modules/m4.c (define, pushdef): Warn when flattening builtins.
- * doc/m4.texinfo (Define): Remove dead comment.
- (Defn): Update to reflect code changes.
- * tests/builtins.at (defn): Remove xfail.
- * NEWS: Document this change.
-
-2008-05-03 Eric Blake <ebb9@byu.net>
-
- Document define_blind.
- * doc/m4.texinfo (Ifelse): Add a new composite macro.
- * THANKS: Update.
- Suggested by Mike R.
-
-2008-05-01 Eric Blake <ebb9@byu.net>
-
- Avoid -Wshadow compiler warnings.
- * m4/output.c (threshold_diversion_CB): s/div/diversion/.
- * m4/macro.c (make_argv_ref, arg_symbol, m4_arg_symbol)
- (m4_is_arg_text, m4_is_arg_func, m4_arg_text, m4_arg_empty)
- (m4_arg_len, m4_arg_func, m4__arg_print, m4_make_argv_ref)
- (m4_push_arg, m4__push_arg_quote): s/index/arg/.
- * modules/format.c (format): Likewise.
- * modules/m4.c (ifelse): Likewise.
-
- Improve debugmode testing, based on recent branch-1.6 regressions.
- * doc/m4.texinfo (Debugmode): Enhance tests.
- * tests/generate.awk: Run tests from stdin, not input.m4. Support
- stderr munging when using -I examples.
-
- Fix regression in define from 2008-02-22.
- * m4/m4module.h (m4_symbol_value_copy): Add parameter.
- * m4/symtab.c (m4_symbol_value_copy): Support copying $@
- back-references.
- * m4/macro.c (expand_argument): Update callers.
- * modules/m4.c (define, pushdef): Likewise.
- * tests/builtins.at (define): Enhance test to catch this.
-
-2008-04-21 Eric Blake <ebb9@byu.net>
-
- Simplify previous patch.
- * tests/m4.in: Compress assignment.
- Suggested by Gary V. Vaughan.
-
- Fix --disable-shared testsuite regression from previous patch.
- * tests/m4.in: Export M4MODPATH, so that recursive m4 invocations
- will also work.
-
- Fix spelling of attribution to Christopher Strachey.
- * doc/m4.texinfo (History, Inhibiting Invocation): Fix typo.
- * THANKS: Update.
- Reported by Fernando Carrijo.
-
-2008-04-17 Eric Blake <ebb9@byu.net>
-
- Fix testsuite bug when SIGPIPE is ignored.
- * tests/builtins.at (divert): Consume all of m4's output, to avoid
- spurious write failure.
- * src/main.c (main): In batch mode, restore default handling of
- SIGPIPE.
- * doc/m4.texinfo (Operation modes): Document SIGPIPE behavior.
- * THANKS: Update.
- Reported by Bob Proulx, via his autobuilder.
-
-2008-04-15 Eric Blake <ebb9@byu.net>
-
- Fix 'make installcheck' after './configure --prefix-progname'.
- * tests/testsuite.at (AT_CHECK_M4): Allow overriding the m4
- program name.
- (HELP_OTHER, PREPARE_TESTS): Document and use $M4.
- * tests/builtins.at (patsubst): Avoid space-tab.
- (divert, mkdtemp, mkstemp): Adjust tests to use $M4.
- * tests/options.at (--debugfile): Likewise.
- * tests/others.at (stdin seekable): Likewise.
- (fstab): Avoid space-tab.
- * Makefile.am (installcheck-local): Accomodate transformed name.
- (DISTCHECK_CONFIGURE_FLAGS): Ensure no regressions, by using gm4
- during 'make distcheck'.
- * cfg.mk: New file, borrowed from branch.
-
- Update prerequisite tools to match recent releases.
- * configure.ac (AC_PREREQ): Rely on released autoconf.
- (LT_PREREQ): Rely on released libtool.
- * tests/testsuite.at (m4_version_prereq): Update dependence.
- * bootstrap: Mention prerequisites.
-
- Work around OS/2 limitation of printf(1).
- * tests/null.m4: Use m4, not printf, to generate NUL byte.
- * tests/null.out: Check for esyscmd failure.
- Reported by Elbert Pol.
-
-2008-04-14 Eric Blake <ebb9@byu.net>
-
- Stage 21b: $@ concatenates builtins, m4wrap takes builtins.
- Improve arg_print to handle builtin tokens when printing to a
- known chain, rather than always flattening builtins. This allows
- m4wrap and $@ back-references to handle embedded builtin tokens.
- Memory impact: none.
- Speed impact: slight penalty, from more bookkeeping.
- * m4/m4module.h (m4_push_builtin): Add parameter.
- (m4_builtin_print, m4_push_wrapup_init, m4_push_wrapup_finish)
- (m4_arg_print, m4_symbol_value_print): Rename and reduce scope...
- * m4/m4private.h (m4__builtin_print, m4__push_wrapup_init)
- (m4__push_wrapup_finish, m4__arg_print, m4__symbol_value_print):
- ...to these, in some cases adding a parameter.
- (m4__append_builtin): New prototype.
- * m4/builtin.c (m4_builtin_print): Alter signature to print
- builtin to a growing symbol chain.
- * m4/symtab.c (m4__symbol_value_print): Alter signature.
- (m4_symbol_print, dump_symbol_CB): Adjust callers.
- * m4/input.c (builtin_peek, builtin_read, builtin_unget)
- (builtin_print, builtin_funcs): Delete, handled via composite
- blocks now.
- (struct m4_input_block): Delete u.builtin member.
- (init_builtin_token): Only use composite block.
- (m4__append_builtin): New function.
- (m4_push_builtin, m4__push_wrapup_init): Alter signature.
- (m4__push_symbol): Allow builtin tokens.
- (m4__push_wrapup_finish): Rename.
- (composite_print, m4_print_token): Adjust callers.
- * m4/macro.c (m4_wrap_args, collect_arguments): Allow builtin
- tokens.
- (m4__arg_print): Alter signature.
- (trace_prepre, trace_pre, m4_arg_text, m4_arg_equal): Adjust
- callers.
- * modules/m4.c (m4wrap): Allow builtin tokens.
- (defn, errprint): Adjust callers.
- * modules/gnu.c (builtin): Likewise.
- * doc/m4.texinfo (M4wrap): New test.
- (Debuglen): Adjust expected output.
-
- Stage 21a: Optimize checks for end of input.
- Create a new polymorphic input block type, which always fails with
- CHAR_EOF, so that remaining input routines no longer have to check
- for NULL input block.
- Memory impact: none.
- Speed impact: noticeable improvement, from fewer conditionals.
- * m4/input.c (eof_funcs, input_eof): New objects.
- (eof_peek, eof_read, eof_unget): New functions.
- (file_clean, m4_push_string_init, pop_input, m4_push_wrapup_init)
- (m4_pop_wrapup, next_char, peek_char, unget_input, m4_input_init)
- (m4_input_exit): Use placeholder to guarantee non-NULL isp and
- wsp.
- (next_char): Rename retry to allow_unget, and change sense for
- easier manipulation. All callers changed.
-
- Improve OS/2 detection.
- * modules/gnu.c (m4_macro_table): Ensure all possible identifiers
- are defined, not just the first. The testsuite ensures that
- exactly one gets defined.
- * m4/system_.h [__EMX__]: OS/2 is not Unix-compatible, no matter
- what other pre-defined macros it has.
- * THANKS: Update.
- Reported by Elbert Pol.
-
- Ensure __m4_version__ is unquoted.
- * tests/builtins.at (__m4_@&t@version__): Augment test.
-
- Avoid GNU make failure on tarball.
- * Makefile.am (EXTRA_DIST): Distribute cfg.mk and maint.mk.
-
-2008-04-10 Eric Blake <ebb9@byu.net>
-
- Allow back-referenced macro names; fixes 2008-03-13 regression.
- * m4/m4module.h (m4_symbol_value_lookup): Change prototype.
- * m4/utility.c (m4_symbol_value_lookup): Change signature.
- * modules/m4.c (undefine, popdef, ifdef, m4_dump_symbols, defn):
- Adjust all callers.
- * tests/others.at (ifndef): New test.
-
- Be namespace clean for M4 version; fixes 2008-04-08 regression.
- * configure.ac (version): Rename...
- (M4_VERSION): ...to this, since using 'version' broke po.m4.
-
-2008-04-09 Eric Blake <ebb9@byu.net>
-
- Mention 1.4.11 release.
- * doc/m4.texinfo (History, Defn, Ifdef, Ifelse, M4wrap)
- (Extensions, Improved foreach): Distinguish 1.4.11 and 1.6.
- (Format): Add test of C99 hex-float parsing.
- * NEWS: Mention 1.4.11 release.
- * tests/builtins.at (divert): Add additional test.
-
-2008-04-08 Eric Blake <ebb9@byu.net>
-
- Overhaul inter-version releases to work with git.
- * configure.ac (version): New variable, which has nicer version
- contents when using git 1.5.5+, hardcoded to 1.9a otherwise.
- (TIMESTAMP): Delete, since CVS id expansion died with transition
- to git.
- (AM_INIT_AUTOMAKE): Use version to decide gnu vs. gnits.
- * build-aux/mkstamp: Delete, no longer used.
- * Makefile.am (CONFIG_STATUS_DEPENDENCIES): Kill, to speed up
- rebuilds when timestamps don't matter.
- (MKSTAMP): Delete, no longer used.
- (EXTRA_DIST): No longer worry about mkstamp.
- (.version): New rule and distributed file.
- (doc/m4.1, tests/package.m4): Depend on .version, not
- configure.ac, for timestamp.
- * ltdl/m4/gnulib-cache.m4: Import git-version-gen module.
- * modules/gnu.c (__m4_version__): TIMESTAMP no longer exists.
- * src/main.c (main): Likewise.
-
-2008-03-28 Eric Blake <ebb9@byu.net>
-
- Use GNUmakefile module.
- * ltdl/m4/gnulib-cache.m4: Import gnumakefile module.
- * Makefile.am: Split off maintainer rules...
- * maint.mk: ...into this new file.
-
-2008-03-18 Eric Blake <ebb9@byu.net>
-
- Stage 20b: make m4wrap obey POSIX fifo ordering.
- Improve input engine to support location changes within symbol
- chains, then convert m4wrap to always build symbol chain.
- Memory impact: none.
- Speed impact: slight penalty, from more m4wrap bookkeeping.
- * m4/m4module.h (m4_wrap_args): Add prototype.
- * m4/m4private.h (enum m4__symbol_chain_type): Add M4__CHAIN_LOC.
- (struct m4__symbol_chain): Add struct u_l.
- * m4/input.c (m4_push_wrapup_init, m4_push_wrapup_finish): Use
- new link type.
- (composite_peek, composite_read, composite_clean): Handle location
- link.
- * m4/macro.c (m4_wrap_args): New function.
- * modules/m4.c (m4wrap): Use it.
- * doc/m4.texinfo (M4wrap): Sync with branch and POSIX.
- (Extensions): Document extension of multiple arguments.
- (Location, Improved m4wrap): Adjust example to match FIFO order.
- * tests/builtins.at (wrap): Likewise.
- * NEWS: Document this change.
-
-2008-03-17 Eric Blake <ebb9@byu.net>
-
- Stage 20a: reduce unget's in input engine.
- Now that out-of-range input placeholders like CHAR_BUILTIN are
- consumed outside of next_char, next_token should always consume
- rather than peek at the first character. Fewer peeks results in
- less ungetc overhead.
- Memory impact: none.
- Speed impact: noticeable improvement, from fewer function calls.
- * m4/input.c (struct input_funcs): Alter read_func prototype.
- (next_char, file_read, buildin_read, string_read, composite_read):
- Add allow_argv parameter.
- (init_builtin_token, init_argv_symbol): Require all prior input to
- be consumed.
- (m4_skip_line, match_input, consume_syntax): Adjust callers.
- (m4__next_token): Consume first byte without peek.
-
- Update for fresh bootstrap.
- * ltdl/m4/gnulib-cache.m4: Updated copyright from upstream.
-
-2008-03-15 Eric Blake <ebb9@byu.net>
-
- Document join, in order to fix bug in m4wrap example.
- * examples/join.m4: New file.
- * examples/wraplifo2.m4: Likewise.
- * Makefile.am (EXTRA_DIST): Add new files.
- * doc/m4.texinfo (Improved m4wrap): New node.
- (Defn, Location): Enhance tests.
- (Shift): Document the composite macro join.
- (Incompatibilities): Move documentation of LIFO vs. FIFO...
- (M4wrap): ...here, to match improved example.
-
-2008-03-13 Eric Blake <ebb9@byu.net>
-
- Stage 19c: allow builtin tokens in more macros.
- Allow builtin tokens inside symbol chains, although for now, they
- are not allowed inside comments or quotes. Enable builtin token
- handling in more macros, if only to consistently diagnose invalid
- macro names.
- Memory impact: none.
- Speed impact: slight impact, due to more bookkeeping.
- * m4/m4module.h (m4_symbol_value_lookup, m4_builtin_print): New
- prototypes.
- * m4/m4private.h (enum m4__symbol_chain_type): Add
- M4__CHAIN_FUNC.
- (struct m4__symbol_chain): Add builtin member.
- * m4/utility.c (m4_symbol_value_lookup): New method.
- * m4/builtin.c (m4_builtin_print): New function.
- * m4/symtab.c (m4_symbol_value_print): Use it.
- * m4/input.c (builtin_print): Likewise.
- (m4__push_symbol): Allow pushing builtin tokens.
- (composite_peek, composite_read, composite_unget, composite_clean)
- (composite_print): Handle builtin tokens.
- (init_builtin_token): Allow builtin tokens from composite input.
- (m4__next_token): Flatten builtins inside comment or string.
- * m4/macro.c (expand_argument): Strengthen assertion.
- (collect_arguments, m4_arg_equal, m4_arg_print, m4_push_args):
- Handle builtin tokens.
- (arg_symbol): Add parameter, and allow NULL level.
- (m4_arg_symbol, m4__push_arg_quote): Adjust callers.
- (m4_arg_text): Ensure all builtins have been flattened.
- * modules/m4.c (defn, dumpdef, popdef, traceoff, traceon)
- (undefine, m4_dump_symbols): Warn on invalid macro names.
- (ifdef, ifelse, shift): Handle builtin tokens.
- * modules/gnu.c (m4symbols): Likewise.
- * doc/m4.texinfo (Defn, Ifdef, Ifelse): Document and test the new
- behavior.
- (Debuglen): Likewise, and remove xfail.
- * NEWS: Mention the change.
-
- Stage 19b: invert sense of bit for handling builtin tokens.
- Pass builtin tokens by default, rather than as the exception, so
- that the logic can consistently refer to flattening arguments.
- Memory impact: none.
- Speed impact: none.
- * m4/m4module.h (M4BUILTIN_ENTRY): New convenience macro.
- (M4_BUILTIN_GROKS_MACRO): Rename...
- (M4_BUILTIN_FLATTEN_ARGS): ...and invert sense.
- (m4_symbol_value_groks_macro, m4_symbol_groks_macro): Likewise...
- (m4_symbol_value_flatten_args, m4_symbol_flatten_args): ...to
- this.
- * m4/m4private.h (VALUE_MACRO_ARGS_BIT)
- (m4_symbol_value_groks_macro): Likewise...
- (VALUE_FLATTEN_ARGS_BIT, m4_symbol_value_flatten_args): ...to
- this.
- * m4/symtab.c (m4_symbol_value_groks_macro): Likewise...
- (m4_symbol_value_flatten_args): ...to this.
- * m4/macro.c (collect_arguments): Accomodate changed sense.
- * m4/module.c (m4__module_open): Require arguments if flattening
- is requested.
- * m4/input.c (m4_push_string_finish): For now, flatten all
- builtins pushed as back-references.
- * modules/gnu.c (m4_builtin_table, builtin): Adjust all clients.
- * modules/import.c (m4_builtin_table): Likewise.
- * modules/load.c (m4_builtin_table): Likewise.
- * modules/modtest.c (m4_builtin_table): Likewise.
- * modules/mpeval.c (m4_builtin_table): Likewise.
- * modules/perl.c (m4_builtin_table): Likewise.
- * modules/shadow.c (m4_builtin_table): Likewise.
- * modules/stdlib.c (m4_builtin_table): Likewise.
- * modules/time.c (m4_builtin_table): Likewise.
- * modules/m4.c (m4_builtin_table): Likewise.
- (mkstemp): Undo #undef hack from 2006-10-23, now that macro names
- are stringized without preprocessor expansion.
- * doc/m4.texinfo (Defn): Update comments to match reality.
- (Debuglen): Update test now that user macros pass builtin tokens.
-
- Stage 19a: sort and cache builtins loaded by a module.
- Rather than repeatedly using dlsym to browse the builtin table,
- copy off the table at module load time. Then, the input engine
- merely refers to the copy instead of duplicating information.
- Memory impact: slight penalty, due to more memory per module, but
- offset by less memory in input engine.
- Speed impact: slight improvement, due to faster builtin lookups.
- * m4/m4module.h (m4_set_symbol_value_builtin): Delete. Use
- m4_builtin_find_by_* instead.
- (m4_builtin_find_by_func): Change return type.
- * m4/m4private.h (m4__builtin): New struct.
- (m4_module): Add sorted list of loaded builtins.
- (struct m4_symbol_value): Change type of builtin value.
- (m4__set_symbol_value_builtin): New prototype and fast accessor.
- (m4_get_symbol_value_func, m4_get_symbol_value_builtin): Adjust to
- new field type.
- * m4/symtab.c (m4_set_symbol_value_builtin): Rename...
- (m4__set_symbol_value_builtin): ...and populate additional fields,
- based on new type.
- (m4_get_symbol_value_func, m4_get_symbol_value_builtin): Adjust to
- new field type.
- * m4/module.c (install_builtin_table): Use cached table.
- (compare_builtin_CB): New helper function.
- (m4__module_open): Populate table.
- (module_remove): Free table.
- * m4/builtin.c (compare_builtin_name_CB): New helper function.
- (m4_builtin_find_by_name): Rewrite to use sorted table.
- (m4_builtin_find_by_func): Change return type.
- * m4/input.c (struct m4_input_block): Simplify u_b, since most
- fields can be determined from builtin.
- (builtin_peek, builtin_read, builtin_unget, init_builtin_token)
- (m4__next_token): Alter parsing so that only init_builtin_token
- consumes a builtin.
- (builtin_print, m4_push_builtin): Adjust all users.
- * tests/macros.at (Arity, defn, and freeze): Fix typo.
-
- Consistently cast malloc results, for C++ compilation.
- * m4/builtin.c (m4_builtin_find_by_name): Add cast.
- * m4/hash.c (m4_hash_new, m4_get_hash_iterator_next, node_new)
- (m4_hash_resize, maybe_grow): Likewise.
- * m4/m4.c (m4_create): Likewise.
- * m4/macro.c (expand_macro): Likewise.
- * m4/output.c (m4_tmpname): Likewise.
- * m4/path.c (search_path_add): Likewise.
- * m4/symtab.c (m4_symtab_create, m4_symbol_value_create)
- (symtab_fetch): Likewise.
- * m4/syntax.c (m4_syntax_create): Likewise.
- * modules/gnu.c (regexp_compile): Likewise.
- * src/main.c (main): Likewise.
- * src/freeze.c (reload_frozen_state): Likewise.
-
-2008-03-06 Eric Blake <ebb9@byu.net>
-
- Fix nested builtin(`shift',$@) regression from 2008-02-23.
- * m4/macro.c (make_argv_ref): Don't output expansion text when
- making wrapper for builtin or indir.
- * tests/builtins.at (builtin): New test.
- * NEWS: Document the fix.
- Reported by Andreas Schwab.
-
-2008-03-04 Eric Blake <ebb9@byu.net>
-
- The gnulib module free was deprecated.
- * ltdl/m4/gnulib-cache.m4: Remove free module.
-
-2008-02-29 Eric Blake <ebb9@byu.net>
-
- Import news from 1.4.10b.
- * NEWS: Update from branch.
-
-2008-02-23 Eric Blake <ebb9@byu.net>
-
- Stage 18: try harder to reuse argv in recursion.
- When pushing arguments that contain an existing $@ ref, reuse the
- ref rather than creating another layer of wrappers.
- Memory impact: noticeable improvement, due to better $@ reuse.
- Speed impact: noticeable improvement, due to O(n^2) to O(n)
- reduction in unboxed recursion.
- * m4/macro.c (make_argv_ref): Avoid wrapping $@ when possible.
- (m4_push_args): Let make_argv_ref take care of pending data.
- * doc/m4.texinfo (Improved foreach): Tweak wording to match new
- performance capability.
- * tests/others.at (recursion): Add tests to avoid performance
- regression.
-
-2008-02-22 Eric Blake <ebb9@byu.net>
-
- Update NEWS.
- * NEWS: Document change to __gnu__ on 2008-02-11.
-
- Stage 17: pass argv through quoted strings.
- Allow the concatenation of $@ references with other text input
- inside quoted contexts, which requires distinguishing between a
- wrapper around many arguments vs. a reference serving as part of a
- single argument. Also optimize based on whether argv contains
- builtin tokens that might need flattening to the empty string.
- Memory impact: noticeable improvement, due to O(n^2) to O(n)
- reduction from total reuse of $@ references.
- Speed impact: noticeable improvement, due to O(n^2) to O(n)
- reduction in boxed recursion.
- * m4/m4module.h (m4_arg_equal, m4_arg_len): Add parameter.
- (M4ARGLEN): Adjust definition.
- * m4/m4private.h (struct m4__symbol_chain): Add has_func member.
- (struct m4_symbol_value): Add wrapper and has_func members.
- (struct m4_macro_args): Add flatten and has_func members.
- * m4/input.c (append_quote_token): Return argv refs inside quoted
- strings.
- (init_argv_symbol): Populate new fields.
- * m4/macro.c (expand_argument, collect_arguments, make_argv_ref)
- (m4_make_argv_ref): Likewise.
- (arg_symbol, arg_mark, m4_is_arg_text, m4_is_arg_func): Use new
- fields.
- (m4_arg_equal, m4_arg_len): Handle quoted argv references, and add
- new parameter.
- * modules/m4.c (ifelse): Adjust caller.
-
-2008-02-22 Gary V. Vaughan <gary@gnu.org>
-
- Fix regression in argument collection, from 2008-01-21.
- * m4/input.c (m4__next_token): When DEBUG_INPUT is defined,
- undo argument collection optimisation for strings, so that
- m4_print_token doesn't abort when it otherwise receives an
- unprintable M4_SYMBOL_VOID type token.
-
-2008-02-20 Eric Blake <ebb9@byu.net>
-
- Stage 16: cache quotes and improve m4_arg_print.
- Cache rather than always copying quotes when pushing $@ refs; in
- particular, reconstruct single-byte quotes on the fly. Allow NUL
- through m4wrap. Improve sharing of code that prints arguments.
- Memory impact: slight improvement, due to cached quotes.
- Speed impact: slight improvement, due to less copying.
- * m4/m4module.h (m4_symbol_value_print, m4_symbol_print)
- (m4_arg_print): Adjust prototypes.
- (m4_dump_args): Delete.
- (m4_push_wrapup): Split...
- (m4_push_wrapup_init, m4_push_wrapup_finish): ...into these
- prototypes.
- * m4/m4private.h (struct m4_syntax_table): Add cached_quote
- member.
- (m4__quote_cache, m4__quote_uncache): New prototypes.
- * m4/syntax.c (m4_syntax_create): Initialize the cache.
- (m4__quote_cache): New function.
- (m4_set_syntax): Update caller.
- * m4/symtab.c (m4_symbol_value_print): Add parameter.
- (m4_symbol_print, dump_symbol_CB): Adjust all callers.
- * m4/utility.c (m4_dump_args): Delete; callers should use
- m4_arg_print instead.
- * m4/input.c (m4_push_wrapup_init, m4_push_wrapup_finish): Split
- implementation, and allow embedded NUL.
- (m4_print_token, pop_input, composite_print, composite_peek):
- (composite_read, append_quote_token): Adjust all callers.
- * m4/macro.c (trace_prepre, m4_arg_text, make_argv_ref):
- Likewise.
- (m4_arg_print): Add parameters.
- (trace_pre): Rewrite in terms of m4_arg_print.
- * modules/m4.c (errprint): Likewise.
- (m4wrap): Rewrite to allow embedded NUL.
- (dumpdef): Adjust caller.
- * doc/m4.texinfo (Debuglen): Enhance debuglen test.
- * tests/null.m4: Test for NUL in m4wrap.
- * tests/null.out: Update expected output.
-
- Fix out-of-bounds read for sanitized macro names, from 2008-02-06.
- * m4/utility.c (m4_verror_at_line): Properly terminate the string.
- Reported by Ralf Wildenhues.
-
- * doc/m4.texinfo (Debuglen, Changesyntax): Fix typos.
-
-2008-02-19 Eric Blake <ebb9@byu.net>
-
- Clean up example on filtering defined symbols.
- * doc/m4.texinfo (Foreach, Improved foreach): Document another
- shortcoming in foreach.m4, and improve filter example by using
- foreach2.m4.
-
- * src/main.c (usage): Fix typo.
-
-2008-02-18 Eric Blake <ebb9@byu.net>
-
- Avoid some magic numbers.
- * m4/m4private.h (CHAR_EOF, CHAR_BUILTIN, CHAR_QUOTE, CHAR_ARGV)
- (CHAR_RETRY): Define in terms of UCHAR_MAX.
- * m4/syntax.c (m4_syntax_create, set_syntax_set)
- (reset_syntax_set, check_is_single_quotes)
- (check_is_single_comments, check_is_macro_escaped)
- (m4_set_quotes, m4_set_comment): Likewise.
- * modules/gnu.c (regexp_compile): Likewise.
- * modules/m4.c (translit): Likewise.
- * src/freeze.c (produce_syntax_dump): Likewise.
- Reported by Ralf Wildenhues.
-
-2008-02-16 Eric Blake <ebb9@byu.net>
-
- Add regression test for multi-character quote recursion.
- * examples/foreach2.m4: Use $0 rather than spelling out name.
- * examples/foreachq2.m4: Likewise.
- * examples/forloop2.m4: Likewise.
- * examples/hanoi.m4: Likewise.
- * examples/trace.m4: Likewise.
- * doc/m4.texinfo (Improved forloop): Document advantage of $0.
- (Improved foreach): Adjust dump from file.
-
- Stage 15: return argv refs back to collect_arguments.
- Collect an entire $@ reference at once rather than one argument at
- a time, outside of quotes (but inside quotes, $@ is still
- flattened for now). The skip_last field allows concatenation of
- $@ with other text when collecting arguments.
- Memory impact: noticeable improvement, due to better reuse of $@.
- Speed impact: noticeable improvement, due to less parsing.
- * m4/m4private.h (CHAR_ARGV): New input engine sentinel.
- (enum m4__token_type): Add M4_TOKEN_ARGV.
- (struct m4__symbol_chain): Add skip_last member to argv link.
- (m4__next_token): Add parameter.
- * m4/input.c (peek_char, file_peek, builtin_peek, string_peek)
- (composite_peek, m4__next_token): Add new parameter.
- (composite_read, append_quote_token): Support argv in quotes.
- (init_argv_symbol): New function.
- (m4__push_symbol, match_input, consume_syntax)
- (m4__next_token_is_open, m4_print_token): Adjust callers.
- * m4/macro.c (m4_macro_expand_input, m4__arg_adjust_refcount)
- (arg_mark, m4_arg_text, make_argv_ref): Likewise.
- (expand_argument, collect_arguments): Handle new token.
- (arg_symbol): Drill through $@ reference.
- * m4/syntax.c (set_quote_age): Detect disabled comments.
- * m4/symtab.c (dump_symbol_CB) [DEBUG_SYM]: Fix debug code.
-
-2008-02-15 Eric Blake <ebb9@byu.net>
-
- * modules/gnu.c (regexp_compile): Use a fastmap for regex speed.
-
-2008-02-13 Eric Blake <ebb9@byu.net>
-
- Fix texinfo grammar.
- * doc/m4.texinfo (Eval, Incompatibilities): Use @. after capital.
- (History): Use @: after abbreviations.
- (M4exit): Use correct Latin abbreviation.
- (Dumpdef, Debugmode, Frozen file format 2): Use correct spacing
- between sentences.
-
-2008-02-11 Eric Blake <ebb9@byu.net>
-
- Allow builtin text macros to specify number of arguments.
- * m4/m4module.h (struct m4_macro): Add argument limits to builtin
- text macros.
- * m4/module.c (install_macro_table): Allow text macros to warn on
- extra arguments.
- * modules/gnu.c (m4_macro_table): Update all clients.
- * modules/load.c (m4_macro_table): Likewise.
- * modules/mpeval.c (m4_macro_table): Likewise.
- * modules/perl.c (m4_macro_table): Likewise.
- * modules/shadow.c (m4_macro_table): Likewise.
- * modules/traditional.c (m4_macro_table): Likewise.
- * modules/modtest.c (m4_macro_table): Likewise. Also add text
- macros, for testing this.
- * doc/m4.texinfo (Standard Modules): Update text, and enhance
- test.
- * tests/modules.at (modules: text): New test.
-
- Fix regression in command line -D option, from 2006-08-25.
- * m4/m4private.h (m4_symbol_value_create): Delete fast accessor.
- * m4/m4module.h: Fix typo.
- * m4/symtab.c (m4_symbol_value_create): Prime the maximum number
- of arguments.
- * tests/macros.at (Command line define): Enhance test.
- * tests/others.at (nul character): Enhance test.
- * tests/null.m4: Likewise.
- * tests/null.out: Likewise.
-
- Use gnulib's git-merge-changelog driver when available.
- * .gitattributes: Add merge attributes for ChangeLog.
- * bootstrap: Install driver, if not already present.
-
-2008-02-06 Eric Blake <ebb9@byu.net>
-
- Fix security hole introduced 2007-11-23.
- * m4/utility.c (m4_verror_at_line): Properly escape macro names.
- * src/main.c (main): Manage quoteargs defaults.
- * doc/m4.texinfo (Indir): Document and test this.
-
- Using raw strtod is not portable.
- * ltdl/m4/gnulib-cache.m4: Import the strtod module.
-
-2008-02-02 Eric Blake <ebb9@byu.net>
-
- Consistently use size_t for number of arguments.
- * m4/m4module.h (m4_builtin_func): Alter prototype.
- (struct m4_builtin): Adjust type of min_args, max_args.
- (M4BUILTIN, M4BUILTIN_HANDLER): Adjust all builtins.
- (m4_bad_argc, m4_dump_args, m4_macro_call, m4_arg_argc)
- (m4_arg_symbol, m4_is_arg_text, m4_is_arg_func, m4_arg_text)
- (m4_arg_equal, m4_arg_empty, m4_arg_len, m4_arg_func)
- (m4_arg_print, m4_push_arg): Adjust all clients.
- * m4/m4private.h (struct m4__symbol_chain, m4_symbol_value)
- (m4_macro_args): Adjust type of various fields.
- (m4__push_arg_quote): Adjust all clients.
- * m4/input.c (m4_pop_wrapup): Likewise.
- * m4/macro.c (m4_macro_call, trace_pre, make_argv_ref)
- (arg_symbol, m4_arg_symbol, m4_is_arg_text, m4_is_arg_func)
- (m4_arg_text, m4_arg_equal, m4_arg_empty, m4_arg_len)
- (m4_arg_func, m4_arg_print, m4_make_argv_ref, m4_push_arg)
- (m4__push_arg_quote, m4_push_args, m4_arg_argc): Likewise.
- * m4/utility.c (m4_bad_argc, m4_dump_args): Likewise.
- * modules/evalparse.c (m4_evaluate): Likewise.
- * modules/gnu.c (changesyntax): Likewise.
- * modules/m4.c (m4_dump_symbols, undefine, popdef, ifelse, defn)
- (undivert, traceon, traceoff): Likewise.
- * modules/m4.h (m4_dump_symbols_func): Likewise.
- * modules/perl.c (perleval): Likewise.
-
- Stage 14b: allow pushing argv references.
- Push a $@ reference to the input engine in one go, rather than
- pushing each element. For now, argument collection still gets one
- argument of a $@ at a time; but the penalties of this patch make
- it easier to manage $@ efficiently in future patches.
- Memory impact: noticeable penalty, due to larger struct and O(n)
- to O(n^2) on unboxed recursion.
- Speed impact: noticeable penalty, due to more bookkeeping.
- * m4/m4private.h (struct m4__symbol_chain): Add comma and quotes
- fields.
- (struct m4_macro_args): Add level field.
- (m4__arg_adjust_refcount, m4__push_arg_quote): New prototypes.
- * m4/input.c (m4__push_symbol, composite_peek, composite_read)
- (composite_unget, composite_clean, composite_print): Support $@
- refs.
- * m4/macro.c (collect_arguments): Populate new field.
- (expand_macro): Move argv cleanup...
- (m4__arg_adjust_refcount): ...to this new function.
- (m4_arg_symbol, m4_make_argv_ref, m4_push_arg): Factor...
- (arg_symbol, make_argv_ref, m4__push_arg_quote): ...to these new
- helper functions, to add parameters.
- (m4_push_args): Adjust caller.
- * m4/symtab.c (m4_symbol_value_print): Likewise.
-
- Stage 14a: allow printing argv references.
- Refactor symbol-value printing code for better sharing, and to
- allow printing a contiguous text representation of a $@ ref.
- Memory impact: none.
- Speed impact: none.
- * m4/m4module.h (m4_arg_print): New prototype.
- (m4_symbol_value_print): Alter prototype.
- * m4/input.c (struct input_funcs): Add parameter to peek_func.
- (file_peek, builtin_peek, string_peek): Ignore new parameter.
- (composite_peek): Ignore new parameter, for now.
- (composite_clean, pop_input): Rework to minimize indirection, and
- to avoid infinite recursion in next patch.
- * m4/macro.c (trace_prepre, trace_pre): Adjust callers.
- (m4_arg_print): New function.
- * m4/symtab.c (m4_symbol_value_print): Update signature.
- (m4_symbol_print): Update caller.
- * m4/output.c (m4_shipout_string_trunc): Update comments.
- * m4/syntax.c (set_quote_age): Require comma as argument separator
- when dealing with $@ as a unit.
- * tests/builtins.at (ifelse): Augment test.
- * doc/m4.texinfo (Changesyntax): Document changesyntax deficiency.
-
-2008-01-31 Eric Blake <ebb9@byu.net>
-
- Kill hack for M4 1.4.4.
- * configure.ac (AM_GNU_GETTEXT_INTL_SUBDIR): Delete, now that
- we require new enough autoconf which in turn requires M4 1.4.5.
-
-2008-01-31 Gary V. Vaughan <gary@gnu.org>
- and Eric Blake <ebb9@byu.net>
-
- Depend on new libtool to use non-recursive build.
- * configure.ac (LT_PREREQ): Bump to alpha release version.
- (LTDL_INIT): Choose nonrecursive mode. Perform sanity check that
- installed libtool has correct symbols.
- * Makefile.am (SUBDIRS): Drop ltdl, now that it is built from the
- top level.
- (AM_CPPFLAGS): Drop directories covered by libtool.
- (AM_LDFLAGS): Drop -no-undefined, covered by libtool.
- (include_HEADERS, noinst_LTLIBRARIES, EXTRA_LTLIBRARIES): New
- macros, used by libtool.
- (lib_LTLIBRARIES): Also used by libtool.
- (ltdl/libltdlc.la): Delete, now that libtool does this.
- * bootstrap: Mention new requirements.
- (LIBTOOLIZE): Provide default program, and run libtoolize prior to
- autoreconf.
- (autoreconf): Also neutralize libtoolize, since it is run early.
- * HACKING: Mention updated prerequisites.
-
-2008-01-28 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- Fix build failure if installed libltdl is used.
- * Makefile.am (m4_libm4_la_DEPENDENCIES): Use $(LTDLDEPS).
-
-2008-01-28 Eric Blake <ebb9@byu.net>
-
- Depend on newer autoconf, for testsuite -C dir.
- * Makefile.am (CD_TESTDIR): Delete, no longer required.
- (check-local, installcheck-local, clean-local-tests): Use new -C
- option from autotest.
- * configure.ac (AC_PREREQ): Bump to 2.61a.347.
- * bootstrap: Mention new dependency.
- * HACKING: Likewise.
-
-2008-01-27 Eric Blake <ebb9@byu.net>
-
- Stage 13: push composite text tokens.
- Support pushing composite tokens, allowing back-references to be
- reused through multiple macro expansions. Add hueristic that
- avoids creating new reference when pushing existing references.
- Memory impact: noticeable improvement due to better reference
- reuse, except for O(n) to O(n^2) copying in boxed recursion.
- Speed impact: slight penalty, due to more bookkeeping.
- * m4/m4private.h (m4__push_symbol): Adjust prototype.
- * m4/input.c (m4__push_symbol): Add parameter, and support
- composite tokens.
- (append_quote_token): Add parameter, and support inlining of short
- text.
- (m4__next_token): Adjust caller.
- * m4/macro.c (m4_push_arg, m4_push_args): Likewise.
-
-2008-01-26 Eric Blake <ebb9@byu.net>
-
- Stage 12c: add macro for m4_arg_len.
- Make a common action easier to type.
- Memory impact: none.
- Speed impact: none.
- * m4/m4module.h (M4ARGLEN): New macro.
- * m4/macro.c (process_macro): Adjust all callers.
- * m4/utility.c (m4_dump_args): Likewise.
- * modules/m4.c (divert, maketemp, mkstemp, m4wrap, len, index)
- (substr): Likewise.
- * modules/gnu.c (builtin, indir, mkdtemp, patsubst, regexp)
- (renamesyms): Likewise.
- * modules/stdlib.c (setenv): Likewise.
-
- Stage 12b: add m4_string_pair.
- Make passing quote delimiters around more efficient.
- Memory impact: none.
- Speed impact: slight penalty, due to more bookkeeping.
- * m4/m4module.h (m4_string_pair): New type.
- (m4_get_syntax_quotes, m4_get_syntax_comments): New prototypes.
- (m4_symbol_value_print, m4_symbol_print, m4_shipout_string_trunc):
- Alter signature.
- * m4/m4private.h (struct m4_string): Delete.
- (struct m4_syntax_table): Combine quote and comment members.
- (m4_get_syntax_lquote, m4_get_syntax_rquote, m4_get_syntax_bcomm)
- (m4_get_syntax_ecomm): Adjust accessors.
- (m4_get_syntax_quotes, m4_get_syntax_comments): New fast
- accessors.
- * m4/symtab.c (m4_symbol_value_print, m4_symbol_print):
- Alter signatures.
- * m4/input.c (string_print, composite_print, m4_input_print):
- All callers updated.
- * m4/syntax.c (m4_syntax_delete, m4_set_syntax)
- (check_is_single_quotes, m4_set_quotes, set_quote_age)
- (m4_get_syntax_lquote, m4_get_syntax_rquote)
- (m4_get_syntax_quotes, check_is_single_comments, m4_set_comment)
- (m4_get_syntax_bcomm, m4_get_syntax_ecomm)
- (m4_get_syntax_comments): Likewise.
- * m4/macro.c (trace_prepre, trace_pre, m4_push_args): Likewise.
- * m4/output.c (m4_shipout_string, m4_shipout_string_trunc):
- Likewise.
- * modules/m4.c (dumpdef, m4_make_temp): Likewise.
- * src/freeze.c (produce_frozen_state): Likewise.
- * tests/freeze.at (reloading unknown builtin): Update test.
-
- Stage 12a: make m4_symbol_chain a union.
- Shrink size of symbol chains by using a union.
- Memory impact: slight improvement, due to smaller struct.
- Speed impact: slight improvement, due to less bookkeeping.
- * m4/m4private.h (enum m4__symbol_chain_type): New enum.
- (struct m4_symbol_chain): Rename...
- (struct m4__symbol_chain): ...to this, since it is internal.
- * m4/symtab.c (m4_symbol_value_copy, m4_symbol_value_print): All
- callers updated.
- * m4/input.c (struct m4_input_block, m4__push_symbol)
- (composite_peek, composite_read, composite_unget)
- (composite_clean, composite_print, m4__make_text_link)
- (append_quote_token): Likewise.
- * m4/macro.c (expand_macro, arg_mark, m4_arg_symbol, m4_arg_text)
- (m4_arg_equal, m4_arg_len, m4_make_argv_ref, m4_push_arg)
- (m4_push_args): Likewise.
-
-2008-01-23 Eric Blake <ebb9@byu.net>
-
- Adjust to recent libtool interface change.
- * configure.ac (LT_PREREQ): Require bleeding-edge libtool.
- (LT_WITH_LTDL): Delete, now that it is obsolete.
- (LTDL_INIT): Use new libtool macro.
-
-2008-01-22 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
- and Eric Blake <ebb9@byu.net>
-
- Rely on newer automake.
- * configure.ac (AM_INIT_AUTOMAKE): Require 1.10.1, and add lzma
- distribution.
- * bootstrap: Update automake requirement.
- (func_version): Fix --version output, broken since 2007-08-06.
- * HACKING: Likewise. Add lzma requirement.
- * Makefile.am (clean-local-src): Not needed any more with newest
- Automake.
- (clean-local): Adjust.
- * TODO: Remove completed item.
-
-2008-01-22 Eric Blake <ebb9@byu.net>
-
- Doc tweak.
- * doc/m4.texinfo (Renamesyms): Avoid underfull hbox, and improve
- example.
-
-2008-01-21 Eric Blake <ebb9@byu.net>
-
- Stage 11: full circle for single argument references.
- Pass quoted strings through to argument collection in a single
- action, so that an argument can be reused throughout macro
- recursion if it remains unchanged.
- Memory impact: noticeable improvement, due to more reuse in
- argument collection stacks; O(n^2) to O(n) on boxed recursion.
- Speed impact: noticeable improvement, due to less copying.
- * m4/m4module.h (m4_arg_text): Add parameter.
- (M4ARG): Adjust.
- * m4/m4private.h (CHAR_QUOTE): New input engine sentinel.
- (m4__make_text_link): New prototype.
- (struct m4_symbol_chain): Add quote_age member.
- (struct m4_symbol_value): Add end member to chained symbol.
- (struct m4_macro_args): Add wrapper member.
- * m4/symtab.c (m4_symbol_value_print): Print composite tokens.
- (m4_symbol_value_copy, m4_symbol_value_delete): Recognize
- composite tokens.
- * m4/input.c (make_text_link): Rename...
- (m4__make_text_link): ...to this, and export.
- (m4_push_string_finish): Adjust caller.
- (make_text_link, m4__push_symbol): Update new field.
- (file_read, builtin_read, string_read, composite_read, next_char):
- Add parameter.
- (m4_skip_line, match_input, consume_syntax): Adjust callers.
- (append_quote_token): New function.
- (m4__next_token): Pass quoted strings onto argument collection.
- (m4_print_token) [DEBUG_INPUT]: Update.
- * m4/macro.c (expand_argument): Collect composite arguments.
- (collect_arguments): Update new field.
- (expand_macro): Reduce ref-count of back-references after use.
- (arg_mark, m4_arg_symbol, m4_make_argv_ref): Adjust to new member
- names.
- (m4_is_arg_text): Also recognize composite symbols as text.
- (m4_arg_text, m4_arg_len): Merge composite symbols as needed.
- (m4_arg_equal): Compare composite symbols.
- (m4_push_arg, m4_push_args): Handle composite symbols.
- (m4_arg_symbol): Relax assertion.
- (process_macro): Use single-argument references.
- * m4/output.c (m4_shipout_string_trunc): Update comment.
- * tests/macros.at (Rescanning macros): Augment test.
-
-2008-01-16 Eric Blake <ebb9@byu.net>
-
- Stage 10: avoid extra copying of strings and comments.
- When collecting tokens that are immune to further expansion, avoid
- copying data from one obstack to another by outputting it into the
- destination obstack to begin with. Also reduce copying done in
- format builtin.
- Memory impact: slight improvement, due to better obstack usage.
- Speed impact: noticeable improvement, due less data copying.
- * ltdl/m4/gnulib-cache.m4: Import intprops and vasnprintf-posix
- modules.
- * m4/m4private.h (m4__token_type): Adjust prototype.
- * m4/input.c (m4__next_token): Support new parameter.
- * m4/macro.c (m4_macro_expand_input, expand_token)
- (expand_argument, collect_arguments): Adjust callers.
- * modules/m4.c (ntoa): Tighten buffer size.
- * m4/output.c (m4_tmpname): Guarantee no buffer overflow.
- * modules/format.c (arg_int, arg_long, arg_double): New helper
- functions, to detect overflow or unparsed characters.
- (ARG_INT, ARG_LONG, ARG_STR, ARG_DOUBLE): Adjust to check for
- missing or excess arguments.
- (format): Likewise, and also output directly into obstack if there
- is room.
- * doc/m4.texinfo (History): Update for new year.
- (Format): Test for new warnings.
-
-2008-01-15 Eric Blake <ebb9@byu.net>
-
- * TODO: Update with some newer URLs.
-
- Verify linear `index'.
- * tests/builtins.at (index): New test.
- (translit): Make test take longer, to make quadratic algorithms
- more apparent.
-
-2007-12-20 Eric Blake <ebb9@byu.net>
-
- Stage 9: share rather than copy single-arg refs.
- Use hooks of previous patch to create back-references to arguments
- in the input engine, and inline short text rather than always
- creating a FIFO link. Also start testing embedded NUL behavior.
- Until the argument collection engine also shares references, the
- memory usage increases.
- Memory impact: noticeable penalty, due to longer life of argv
- changing O(n) to O(n^2) on boxed recursion.
- Speed impact: slight improvement, due less data copying.
- * ltdl/m4/gnulib-cache.m4: Import memmem and quote modules.
- * m4/m4module.h (m4_arg_scratch): New prototype.
- * m4/m4private.h (m4__push_symbol): Add parameter.
- (m4_arg_scratch): Add fast accessor.
- (struct m4): Add expansion_level member, taken...
- * m4/macro.c (expansion_level): ...from here. Adjust all users.
- (expand_argument): Minor cleanup.
- (expand_macro): Track scratch space per macro call.
- (m4_arg_scratch): New function.
- (m4_make_argv_ref): Call new function.
- (m4_push_arg): Push reference to $0.
- (m4_push_args): Rework separator usage, since separators will
- usually be inlined.
- (process_macro): Allow embedded NUL.
- * m4/input.c (INPUT_INLINE_THRESHOLD): New define.
- (m4__push_symbol): Add parameter. Inline short strings, and save
- references through rescanning.
- * m4/symtab.c (m4_set_symbol_value_text): Weaken assertion.
- * modules/m4.c (errprint, index): Handle NUL transparently.
- (dumpdef, translit): Use scratch space, rather than expansion
- stack.
- * modules/gnu.c (renamesyms, m4symbols): Likewise.
- * tests/others.at (nul character): New test.
- (iso8859): Quote absolute file name, remove XFAIL.
- * tests/iso8859.m4: Avoid raw NUL in output.
- * tests/null.m4: New file.
- * tests/null.out: Likewise.
- * tests/null.err: Likewise.
- * Makefile.am (OTHER_FILES): Distribute new files.
- * .gitattributes: Treat new files as text.
-
-2007-12-17 Eric Blake <ebb9@byu.net>
-
- Stage 8: extend life of references into argv.
- Add hooks to lengthen the lifetime of arguments reused in a macro
- expansion, rather than always discarding arguments at the end of
- expand_macro. Rework the expand_macro obstacks to handle longer
- lifetimes. For now, the hooks remain unused.
- Memory impact: slight penalty, due to larger structs.
- Speed impact: slight penalty, due to more bookkeeping.
- * m4/system_.h (obstack_regrow): Delete.
- * m4/m4private.h (struct m4_symbol_chain): Add level field.
- (m4__push_symbol): Adjust prototype.
- (m4__adjust_refcount): New prototype.
- (DEBUG_MACRO) [DEBUG]: New debug control.
- (struct m4__macro_arg_stacks): New structure.
- (struct m4): Add arg_stacks, stacks_count fields.
- * m4/m4module.h (m4_make_argv_ref): Add parameter.
- * m4/macro.c (argc_stack, argv_stack): Delete, replaced by
- context->arg_stacks.
- (m4_macro_expand_input) [DEBUG_MACRO]: Add debug hooks,
- conditional on M4_DEBUG_MACRO envvar.
- (collect_arguments): Adjust signature.
- (expand_macro): Rework obstack handling.
- (m4__adjust_refcount, arg_mark): New functions.
- (m4_make_argv_ref): Populate new field.
- (m4_push_arg, m4_push_args): Track inuse.
- (process_macro): One less cast.
- * m4/m4.c (m4_delete): Clean up arg_stacks.
- * m4/input.c (make_text_link): Use new field.
- (m4__push_symbol, file_clean): Update signature.
- (composite_read): Bump refcount when done with reference.
- (composite_clean): New function.
- (pop_input): Adjust caller.
- * m4/debug.c (m4_debug_message): Make assertion match comment.
- * modules/gnu.c (builtin, indir): Adjust callers.
- * tests/builtins.at (ifelse): New test.
- (exp): Move and rename...
- * tests/others.at (countdown): ...to this.
- * doc/m4.texinfo (Improved foreach): Fix tracing usage in
- example.
-
-2007-12-13 Eric Blake <ebb9@byu.net>
-
- Yet more rewording.
- * doc/m4.texinfo (Inhibiting Invocation): Missed one instance in
- the previous patch.
-
- * THANKS: Update.
-
-2007-12-13 Paolo Bonzini <bonzini@gnu.org> (tiny change)
-
- * doc/m4.texinfo (Inhibiting Invocation): Fix quoting of a quoting
- example.
- Reported by Giovanni Toffetti.
-
-2007-12-11 Eric Blake <ebb9@byu.net>
-
- Stage 7: use chained input support in input parser.
- Allow the LIFO input engine to rescan a macro expansion composed
- of smaller chunks of FIFO data, rather than the old approach of a
- monolithic string. For now, all chunks are still copied.
- Memory impact: slight penalty, due to FIFO chain overhead.
- Speed impact: slight penalty, due to extra bookkeeping.
- * m4/m4private.h (m4__push_symbol): New prototype.
- (struct m4_symbol_chain): Add const-safety.
- * m4/symtab.c (m4_symbol_value_print): Simplify.
- (dump_symbol_CB): Update caller.
- * m4/input.c (struct m4_input_block): Alter u_c member, first
- introduced 2006-10-25, but unused until now.
- (composite_peek, composite_read, composite_unget)
- (composite_print, init_builtin_token): Rewrite accordingly.
- (m4_push_wrapup): No longer need trailing NUL.
- (m4__push_symbol, make_text_link): New functions.
- (m4_push_string_finish): Use them.
- * m4/macro.c (m4_push_arg, m4_push_args): Likewise.
- (expand_macro): Simplify logic of nesting_limit.
- * src/main.c (main): Likewise.
- * doc/m4.texinfo (Dumpdef): Augment test.
-
-2007-12-08 Eric Blake <ebb9@byu.net>
-
- Stage 6: convert builtins to push arg at a time.
- Add new methods to factor all builtins whose expansion includes an
- argument, making back-reference creation easier in future patches.
- Factor out length-limited printing to obstacks, and use -1 rather
- than 0 for unlimited length.
- Memory impact: none.
- Speed impact: slight improvement, due to better code sharing.
- * m4/m4module.h (m4_shipout_text): Rename...
- (m4_divert_text): ...to this, to avoid confusion with m4_shipout_*
- that does not worry about sync lines.
- (m4_shipout_string_trunc): New prototype.
- * m4/output.c (m4_shipout_text): Rename...
- (m4_divert_text): ...to this.
- (m4_shipout_string): Move guts...
- (m4_shipout_string_trunc): ...to this new function.
- * m4/macro.c (m4_push_arg, m4_push_args): New functions.
- (expand_token, process_macro): Update callers.
- * m4/input.c (string_print): Likewise.
- * modules/m4.c (ifdef, ifelse, shift, substr, translit, divert):
- Likewise.
- * modules/gnu.c (patsubst): Likewise.
- (debuglen): Use SIZE_MAX for unlimited debug length.
- * src/main.c (main): Likewise.
- * m4/m4.c (m4_create): Default max_debug_length to SIZE_MAX, not
- zero.
-
-2007-12-07 Eric Blake <ebb9@byu.net>
-
- Minor security fix: Quote output of mkstemp.
- * modules/m4.c (m4_make_temp): Produce quoted output.
- * doc/m4.texinfo (Mkstemp, Mkdtemp): Update the documentation and
- tests.
-
- Stage 5: add notion of quote age.
- Cache the quoting rules that were in effect when a string was
- parsed, to avoid reparsing that string if no changequote or other
- quote age change took place in the meantime. A quote_age of 0 is
- always safe, but does not benefit from caching.
- Memory impact: slight improvement, due to smaller struct in input
- engine.
- Speed impact: slight penalty, due to more bookkeeping.
- * m4/m4module.h (m4_get_symbol_value_quote_age): New prototype.
- (m4_set_symbol_value_text): Adjust prototype.
- (m4_has_syntax): Factor out the unsigned char cast.
- * m4/m4private.h (struct m4_syntax_table): Add syntax_age and
- quote_age members.
- (m4__quote_age, m4__safe_quotes): New accessor macros, no need for
- functions at this point.
- (struct m4_symbol_value, struct m4_macro_args): Add quote_age
- member.
- (m4_set_symbol_value_text): Adjust fast accessor.
- (m4_get_symbol_value_quote_age): New fast accessor.
- * m4/symtab.c (m4_set_symbol_value_text): Add parameter.
- (m4_get_symbol_value_quote_age): New function.
- (m4_symbol_value_copy): Adjust callers.
- * m4/macro.c (expand_token): Add parameter, and track quote age.
- (expand_argument, collect_arguments): Track quote age.
- (m4_macro_expand_input, process_macro, m4_make_argv_ref)
- (m4_macro_expand_input): Update callers.
- (m4_arg_text, m4_arg_len, m4_arg_func): Abort on type mismatch.
- * m4/input.c: Comment cleanups.
- (struct m4_input_block): Reduce size.
- (m4__next_token): Report quote age.
- (m4_push_builtin, init_builtin_token): Update callers.
- * m4/utility.c (skip_space): Adjust callers.
- * m4/module.c (install_macro_table): Likewise.
- * m4/syntax.c (m4_set_syntax): Initialize and update quote age.
- (m4_set_quotes, m4_set_comment): Detect no-op changes, and update
- quote age.
- (set_quote_age): New helper function.
- (check_is_single_quotes, check_is_single_comments): Adjust
- callers.
- * src/freeze.c (reload_frozen_state): Likewise.
- * src/main.c (main): Likewise.
- * modules/m4.c (define, pushdef): No need to set macro text.
- * tests/builtins.at (changequote, defn): New tests.
- * examples/wrapfifo.m4: New file.
- * examples/wraplifo.m4: New file.
- * Makefile.am (dist_pkgdata_DATA): Distribute new examples.
-
-2007-12-04 Eric Blake <ebb9@byu.net>
-
- Fix builds with OpenBSD make.
- * Makefile.am (HELP2MAN): New macro.
- (dist_man_MANS, doc/m4.1): Fix rules for building m4.1 into
- srcdir.
- * README: Update copyright.
- * HACKING: Mention help2man and makeinfo dependencies.
-
-2007-11-29 Eric Blake <ebb9@byu.net>
-
- Stage 4: route indir, builtin through ref; make argv opaque.
- Finish making struct opaque to all but the input engine, by
- reworking obstack usage in expand_macro to better support creation
- of a $@ reference. Canonicalize the empty argument, to allow
- pointer comparison optimizations.
- Memory impact: slight penalty, due to larger struct.
- Speed impact: slight improvement, due to fewer function calls.
- * m4/system_.h (obstack_regrow): Fix precedence.
- * m4/m4module.h (m4_arg_equal, m4_arg_empty, m4_make_argv_ref):
- New prototypes.
- (struct m4_macro_args): Move...
- * m4/m4private.h (struct m4_macro_args): ...here, making it opaque
- to modules. Add has_ref member.
- (bool_bitfield): New helper typedef.
- (struct m4_symbol_chain): Add flatten and len members.
- * m4/macro.c (empty_symbol): New placeholder, for optimizing
- comparison with empty string.
- (m4_macro_expand_input): Initialize it.
- (collect_arguments): Alter signature, and populate new fields.
- (trace_pre, trace_post): Remove redundant parameter.
- (expand_macro): Alter handling of obstacks.
- (m4_arg_symbol): Account for wrapped argv.
- (m4_arg_equal, m4_arg_empty, m4_make_argv_ref): New methods.
- (m4_arg_text, m4_arg_len, m4_arg_func): Use new methods.
- * modules/m4.c (ifelse, syscmd): Likewise.
- * modules/evalparse.c (m4_evaluate): Likewise.
- (undefine, popdef, m4_dump_symbols): Optimize.
- * modules/gnu.c (builtin, indir, esyscmd, debugfile): Use new
- methods.
- (changesyntax, regexp): Optimize.
- * m4/output.c (diversion_storage): Use typedef.
-
- Stage 3b: cache length, rather than computing it, in modules.
- Use cached token length in builtins and output engine.
- Memory impact: none.
- Speed impact: noticeable improvement, due to fewer function calls.
- * m4/hash.c (m4_hash_remove): Avoid double free on remove
- failure.
- * m4/output.c (m4_shipout_string): Change semantics of len param.
- (m4_shipout_int): Use cached length.
- * m4/input.c (m4_push_string_finish): Likewise.
- * modules/m4.h (m4_make_temp_func): Add parameter.
- * m4/macro.c (expand_token, m4_arg_len): Use cached length.
- (collect_arguments, expand_macro): Alter signature.
- (trace_format): Don't use out-of-scope buffer.
- (process_macro): All callers changed.
- * m4/utility.c (m4_dump_args): Likewise.
- * m4/symtab.c (m4_symbol_value_print): Likewise.
- * modules/gnu.c (__file__, __program__, builtin, indir)
- (m4symbols, mkdtemp, regexp_compile, regexp_substitute,
- renamesyms, patsubst, regexp, regexp_compile): Likewise.
- * modules/load.c (m4modules): Likewise.
- * modules/m4.c (defn, m4wrap, maketemp, m4_make_temp)
- (numb_obstack, ifdef, ifelse, divert, len, substr): Likewise.
- * modules/perl.c (perleval): Likewise.
- * modules/stdlib.c (getcwd, getenv, getlogin, getpwnam, getpwuid)
- (hostname, uname, setenv): Likewise.
- * modules/mpeval.c (numb_obstack): Likewise.
- * src/freeze.c (dump_symbol_CB): Likewise.
- * doc/m4.texinfo (Renamesyms, Dumpdef, Changesyntax): Adjust test.
- * tests/builtins.at (mkstemp): Likewise.
- * tests/others.at (iso8859): XFAIL this test, now that
- length-based handling allows NUL through part but not all of M4.
-
-2007-11-28 Eric Blake <ebb9@byu.net>
-
- Stage 3a: cache length, rather than computing it, in libm4.
- Cache the length of a token in the input engine and symbol table,
- to avoid repeating lots of strlen calls. Additionally, by using
- obstack length rather than strlen, the input engine can now
- support embedded NUL.
- Memory impact: slight penalty, due to larger struct.
- Speed impact: slight improvement, due to fewer function calls.
- * m4/m4module.h (struct m4_macro_args): Cache length.
- (m4_get_symbol_len, m4_get_symbol_value_len): New accessors.
- (m4_set_symbol_value_text): Change signature.
- * m4/m4private.h (struct m4_symbol_value): Store string length.
- (m4_get_symbol_value_text, m4_get_symbol_value_placeholder)
- (m4_set_symbol_value_placeholder): Update accordingly.
- (m4_set_symbol_value_text): Change signature.
- (m4_get_symbol_value_len): New accessor.
- * m4/input.c (struct m4_input_block, string_peek, string_read)
- (string_unget, string_print, m4_push_string_finish)
- (m4_push_wrapup): Track length of string input.
- (m4__next_token): Adjust all users of symbol text to track length,
- too.
- * m4/macro.c (expand_argument, collect_arguments): Likewise.
- * m4/module.c (install_macro_table): Likewise.
- * modules/gnu.c (builtin, indir): Likewise.
- * modules/m4.c (define, pushdef): Likewise.
- * src/main.c (main): Likewise.
- * src/freeze.c (reload_frozen_state): Likewise.
- * m4/symtab.c (m4_symbol_value_copy): Likewise.
- (m4_get_symbol_value_len): New function.
- (m4_get_symbol_value_text, m4_get_symbol_value_placeholder)
- (m4_set_symbol_value_text, m4_set_symbol_value_placeholder):
- Adjust implementation.
-
-2007-11-27 Eric Blake <ebb9@byu.net>
-
- Stage 2: use accessors, not direct reference, into argv.
- Outside of macro.c, use accessor methods rather than direct access
- into the argv struct.
- Memory impact: none.
- Speed impact: slight penalty, due to increased function calls.
- * m4/m4private.h (m4_arg_argc): New fast accessor.
- * m4/m4module.h (m4_arg_argc, m4_arg_symbol, m4_is_arg_text)
- (m4_is_arg_func, m4_arg_text, m4_arg_len, m4_arg_func): New
- prototypes.
- (m4_builtin_func, M4BUILTIN, M4BUILTIN_HANDLER, m4_dump_args)
- (m4_macro_call): Make argc unsigned.
- (M4ARG): Use new accessors.
- * modules/m4.c (define, pushdef): Likewise.
- (undefine, popdef, ifelse, m4_dump_symbols, defn, undivert)
- (traceon, traceoff): Make argc unsigned.
- * modules/m4.h (m4_dump_symbols_func): Likewise.
- * modules/evalparse.c (m4_evaluate): Likewise.
- * modules/gnu.c (builtin, indir): Use new accessors.
- (changesyntax): Make argc unsigned.
- * modules/perl.c (perleval): Likewise.
- * m4/utility.c (m4_dump_args): Use new accessors.
- * m4/macro.c (trace_pre): Likewise.
- (m4_arg_symbol, m4_arg_argc, m4_is_arg_text, m4_is_arg_func)
- (m4_arg_text, m4_arg_len, m4_arg_func): New functions.
- (expand_macro, trace_pre, trace_post, m4_macro_call): Update argc
- usage.
-
-2007-11-24 Eric Blake <ebb9@byu.net>
-
- Stage 1: convert m4_symbol_value** into new object.
- Pass a variable-size wrapper structure instead of an array to
- builtins, so that subsequent optimizations in the structure need
- not impact every builtin client.
- Memory impact: slight penalty, since struct is larger than array.
- Speed impact: slight penalty, due to increased bookkeeping.
- * ltdl/m4/gnulib-cache.m4: Import flexmember module.
- * m4/m4module.h (m4_macro_args): New type, will be opaque to
- modules later.
- (m4_builtin_func, M4BUILTIN, M4BUILTIN_HANDLER, m4_dump_args)
- (m4_macro_call): Alter signature to use m4_macro_args object.
- (M4ARG): Redefine to access new struct.
- * m4/m4private.h (M4_SYMBOL_COMP): New enumerator.
- (struct m4_symbol_chain): New type.
- (struct m4_symbol_value): Add chain alternative.
- * m4/macro.c (collect_arguments): Build new struct.
- (expand_macro, m4_macro_call, process_macro, trace_pre)
- (trace_post): Adjust implementation to use it.
- * m4/utility.c (m4_dump_args): Likewise.
- * modules/gnu.c (builtin, indir): Likewise.
- * modules/format.c (format): Likewise.
- * modules/m4.h (m4_dump_symbols_func): Likewise.
- * modules/m4.c (m4_dump_symbols, define, pushdef, defn, ifelse)
- (shift, include, errprint, m4wrap): Likewise.
- * modules/evalparse.c (m4_evaluate): Likewise.
-
- Pass only macro name to utility functions.
- * m4/m4module.h (m4_bad_argc, m4_numeric_arg): Adjust signature.
- * m4/utility.c (m4_bad_argc, m4_numeric_arg): Adjust
- implementation.
- * m4/macro.c (m4_macro_call): Adjust callers.
- * modules/gnu.c (builtin, debuglen): Likewise.
- * modules/m4.c (ifelse, incr, decr, divert, undivert, m4exit)
- (substr): Likewise.
- * modules/evalparse.c (m4_evaluate): Likewise.
- * modules/stdlib.c (setenv, getpwuid, srand): Likewise.
- * modules/time.c (ctime, gmtime, localtime, mktime, strftime):
- Likewise.
-
-2007-11-23 Eric Blake <ebb9@byu.net>
-
- Add macro name to debugfile messages.
- * m4/m4module.h (m4_debug_set_output): Add parameter.
- * m4/debug.c (m4_debug_set_output, set_debug_file): Pass macro
- name through.
- * modules/gnu.c (debugfile): Adjust caller.
- * modules/m4.c (m4exit): Likewise.
- * src/main.c (main): Likewise.
-
- Factor out handling of macro name in error messages.
- * m4/m4module.h (m4_error, m4_error_at_line, m4_warn)
- (m4_warn_at_line): Add new parameter.
- * m4/utility.c (m4_verror_at_line): New helper method.
- (m4_error, m4_error_at_line, m4_warn, m4_warn_at_line): Add new
- parameter.
- (m4_bad_argc, m4_numeric_arg, m4_parse_truth_arg): All callers
- changed.
- * m4/debug.c: Likewise.
- * m4/input.c: Likewise.
- * m4/macro.c: Likewise.
- * m4/module.c: Likewise.
- * m4/output.c: Likewise.
- * m4/path.c: Likewise.
- * modules/evalparse.c: Likewise.
- * modules/format.c: Likewise.
- * modules/gnu.c: Likewise.
- * modules/load.c: Likewise.
- * modules/m4.c: Likewise.
- * modules/mpeval.c: Likewise.
- * src/freeze.c: Likewise.
- * src/main.c: Likewise.
-
-2007-11-14 Eric Blake <ebb9@byu.net>
-
- Handle some defn corner cases differently.
- * doc/m4.texinfo (Defn): Update documentation; although this still
- doesn't match the branch, since it may be changed before 2.0.
- * m4/macro.c (expand_argument): Consistently ignore builtins in
- concatenation contexts.
- * m4/m4private.h (m4__symbol_type): Fix C89 compliance bug.
-
-2007-11-13 Eric Blake <ebb9@byu.net>
-
- Note: Patches titled Stage 0 through N form a series of patches
- which decreases the algorithmic complexity of tail recursion in
- macro expansions from O(n^2) to O(n) in both time and memory, then
- performs cleanups, such as handling of embedded NUL, made easier
- by the code refactoring.
-
- Stage 0: Fix memory leak in tail recursion.
- Free expansion text in the input engine as soon as it is parsed,
- rather than when the recursive expansion completes.
- Memory impact: noticeable improvement, due to reduction from
- O(n^2) to O(n) on recursion.
- Speed impact: minor improvement, due to better memory usage.
- * m4/input.c (pop_input): Add flag parameter and return type.
- (next_char): Adjust caller.
- (m4_push_string_init): Let go of memory earlier.
-
-2007-11-07 Eric Blake <ebb9@byu.net>
-
- * tests/macros.at (Rescanning macros): Test more corner cases.
-
-2007-11-06 Eric Blake <ebb9@byu.net>
-
- * build-aux/mkstamp: Rename from ltdl/config/mkstamp.
-
- * Makefile.am (tests/package.m4): Work around bash bug.
- Reported by Ralf Wildenhues.
-
-2007-11-05 Eric Blake <ebb9@byu.net>
-
- For consistency with other GNU projects, use build-aux directory.
- * configure.ac (AC_CONFIG_AUX_DIR): Change ltdl/config to
- build-aux.
- * bootstrap (config_aux_dir): Likewise.
- * Makefile.am (config_aux_dir): Likewise.
- * ltdl/m4/gnulib-cache.m4: Use --aux-dir option.
-
-2007-11-02 Eric Blake <ebb9@byu.net>
-
- Update some documentation about version control.
- * NEWS: M4 is now stored in git.
- * HACKING: Likewise.
- * README: Likewise.
- * bootstrap: Likewise.
- * commit: Delete, now that CVS commits are no longer necessary.
- * ltdl/config/mailnotify: No longer necessary; git's patch
- generation and mail capability is more powerful.
-
- Update to recent gnulib changes.
- * ltdl/m4/gnulib-cache.m4: Replace fprintf-posix, vasprintf-posix,
- xprintf, and xvasprintf with xprintf-posix and xvasprintf-posix.
-
-2007-11-01 Eric Blake <ebb9@byu.net>
-
- Improve error message when early end of file occurs.
- * doc/m4.texinfo (Macro Arguments, Changequote, Changecom)
- (M4wrap): Adjust to new messages.
- (Improved capitalize): Enhance test.
- * m4/m4private.h (m4__next_token): Adjust prototype.
- * m4/input.c (m4__next_token): Add new parameter, and improve
- error message.
- * m4/macro.c (m4_macro_expand_input, collect_arguments): Adjust
- callers.
- (expand_argument): Likewise, and add parameter.
-
-2007-10-31 Eric Blake <ebb9@byu.net>
-
- Test more corner cases.
- * tests/macros.at (Rescanning macros): Beef up test.
- * doc/m4.texinfo (Changecom): Beef up test.
- (Improved foreach): Document alternate foreachq style.
- * examples/foreachq3.m4: New file.
- * examples/loop.m4: New file.
- * Makefile.am (dist_pkgdata_DATA): Distribute them.
-
-2007-10-28 Eric Blake <ebb9@byu.net>
-
- More test coverage for autoconf usage patterns.
- * doc/m4.texinfo (Shift): Document cond macro, and add new test.
- * tests/macros.at (Rescanning macros): New test.
- * tests/builtins.at (include): Augment test.
-
-2007-10-28 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * Makefile.am: Adjust getopt handling to latest gnulib layout.
-
-2007-10-27 Eric Blake <ebb9@byu.net>
-
- Document one use of changequote(`(',`)').
- * doc/m4.texinfo (Changequote): Add new test, based on recent
- autoconf addition of m4_expand.
-
-2007-10-24 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * Makefile.am (dist_pkgdata_DATA): Add examples/capitalize2.m4.
-
-2007-10-22 Eric Blake <ebb9@byu.net>
-
- Never let printf failures go undetected.
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- xprintf'.
- * m4/system_.h: Include xprintf.h.
- * m4/debug.c (m4_debug_message_prefix, m4_debug_message): Wrap all
- use of printf, xprintf.
- * m4/input.c [DEBUG_INPUT]: Likewise.
- * m4/module.c [DEBUG_MODULES]: Likewise.
- * m4/output.c (m4_shipout_text, m4_shipout_int)
- (m4_freeze_diversions): Likewise.
- * m4/path.c [DEBUG_INCL]: Likewise.
- * m4/symtab.c [DEBUG_SYM]: Likewise.
- * m4/syntax.c [DEBUG_SYNTAX]: Likewise.
- * modules/modtest.c (export_test): Likewise.
- * src/freeze.c (produce_resyntax_dump, produce_syntax_dump)
- (produce_module_dump, dump_symbol_CB, produce_frozen_state):
- Likewise.
- * src/main.c (usage): Likewise.
- * po/POTFILES.in: Adjust to new file.
- * po/Makevars (XGETTEXT_OPTIONS): Likewise.
-
-2007-10-18 Eric Blake <ebb9@byu.net>
-
- Fix 'm4 -F file -t undefined'.
- * src/freeze.c (produce_symbol_dump): Skip trace placeholders.
- * src/freeze.c (dump_symbol_CB): Also skip void symbols.
- * tests/freeze.at (reloading unknown builtin): Test for this bug.
- * m4/m4module.h (m4_symtab_apply): Add parameter.
- * m4/symtab.c (m4_symtab_apply): Ignore trace placeholders when
- requested.
- (m4_symtab_delete, symtab_dump): Adjust callers.
- * modules/m4.c (m4_dump_symbols): Likewise.
-
-2007-10-09 Eric Blake <ebb9@byu.net>
-
- Fix regexp regression of 2007-09-29.
- * modules/gnu.c (substitute): Allow NULL buf when no
- subexpressions were present.
- (regexp): Handle \ escapes even with empty regex.
- * doc/m4.texinfo (Regexp, Patsubst): Catch this bug.
-
- Cache regex compilation for another autoconf speedup.
- * modules/gnu.c (gnu_buf): Replace...
- (REGEX_CACHE_SIZE, regex_cache): ...with new declarations.
- (m4_pattern_buffer): Add fields.
- (m4_regexp_compile): Rename...
- (regexp_compile): ...to this, and drop no_sub parameter.
- Implement caching.
- (M4FINISH_HANDLER): Clean up entire cache.
- (m4_regexp_search): Rename...
- (regex_search): ...to this, adjust to new struct contents, and add
- no_sub parameter.
- (m4_regexp_substitute): Rename...
- (regexp_substitute): ...to this.
- (substitute, patsubst, regexp, renamesyms): Adjust callers.
-
-2007-10-02 Eric Blake <ebb9@byu.net>
-
- Document quoting pitfalls in capitalize.
- * doc/m4.texinfo (Patsubst): Use the examples directory. Also
- document shortfall.
- (Improved capitalize): New node.
- * examples/capitalize.m4: Update to match manual.
- * examples/capitalize2.m4: New file.
-
-2007-10-01 Eric Blake <ebb9@byu.net>
-
- Another Autoconf usage pattern optimization.
- * modules/m4.c (m4_index): Optimize search for one byte.
- * doc/m4.texinfo (Index macro, Regexp, Patsubst): Test the new
- code paths.
-
-2007-09-29 Eric Blake <ebb9@byu.net>
-
- Optimize for Autoconf usage pattern.
- * modules/gnu.c (regexp, patsubst): Handle empty regex faster.
-
- * tests/testsuite.at (AT_CHECK_M4): Slight optimization.
-
-2007-09-24 Eric Blake <ebb9@byu.net>
-
- Create .gitignore alongside .cvsignore.
- * bootstrap (version control): Update to reflect git usage.
-
-2007-09-13 Eric Blake <ebb9@byu.net>
-
- * AUTHORS: Fix typo.
-
-2007-09-12 Gary V. Vaughan <gary@gnu.org>
-
- Be consistent about using 'module' for m4_module types and
- 'handle' for lt_dlhandle types:
-
- * m4/m4private.h (m4_symbol_value): Rename handle element to
- method. Changed all references.
- (VALUE_MODULE, SYMBOL_MODULE): Renamed from VALUE_HANDLE and
- SYMBOL_HANDLE respectively. Changed all references.
- * m4/m4module.h (M4INIT_HANDLER, M4FINISH_HANDLER): Ditto.
- * m4/builtin.c (m4_builtin_find_by_name)
- (m4_builtin_find_by_func): Use module as the parameter name for
- pointers of type 'm4_module'.
- * m4/module.c (module_remove, m4_get_module_name)
- (install_builtin_table, install_macro_table)
- (m4_module_make_resident, m4__module_next, m4_module_refcount):
- Ditto.
- * src/freeze.c (produce_module_dump): Ditto.
- * m4/input.c (m4_input_block): Rename handle element to method.
- Changed all references.
- * m4/symtab.c (m4__symtab_remove_module_references): Ditto.
- * modules/load.c: Use module as the variable name for pointers
- of type 'm4_module'.
- * modules/m4.c: Ditto.
- * modules/perl.c: Ditto.
- * modules/shadow.c: Ditto.
-
-2007-09-07 Eric Blake <ebb9@byu.net>
-
- Add refcount builtin.
- * modules/load.c (refcount): New builtin.
- (m4modules): Use correct type.
- * doc/m4.texinfo (Refcount): New section.
- * m4/m4private.h (struct m4_module): Add refcount member.
- (m4_module_refcount) [NDEBUG]: Add faster accessor macro.
- * m4/module.c (m4_module_load): Add symbols to table on first
- load by m4, regardless of other libltdl loads of same module.
- (m4_module_refcount): Use new struct member, rather than relying
- on libltdl count which might be inflated by unrelated loads.
- (m4__module_interface): Optimize.
- (m4__module_next, m4__module_find): Avoid assertions that could
- trigger with unrelated libltdl loads.
- (m4__module_open): Track m4 load count.
- (m4__module_exit): Only unload what m4 loaded.
- (module_remove): Track m4 unloads.
- * NEWS: Document new builtin.
-
- More conversion to m4_module*.
- * src/freeze.c (produce_module_dump, dump_symbol_CB)
- (reload_frozen_state): Use correct type.
- * m4/input.c (struct m4_input_block): Likewise.
- * m4/symtab.c (dump_symbol_CB): Likewise.
-
- * AUTHORS: Simplify, to match libtool and autoconf layout.
- * THANKS: Sync with branch.
-
-2007-09-06 Eric Blake <ebb9@byu.net>
-
- Wrap lt_dlhandle in struct m4_module.
- * m4/m4module.h (includes): No longer require clients to know
- about lt_dlhandle.
- (m4_module): New opaque declaration.
- (m4_export): Delete unused type.
- (M4INIT_HANDLER, M4FINISH_HANDLER, m4_module_init_func)
- (m4_module_finish_func, m4_module_load, m4_get_module_name)
- (m4_builtin_find_by_name, m4_builtin_find_by_func): Use new
- wrapper.
- (m4_module_makeresident, m4_module_refcount): New declarations.
- * m4/m4private.h (includes): Move <ltdl.h> here.
- (m4_module): New declaration. Simple for now, but intended for
- growth.
- (m4__module_open, m4__module_next, m4__module_find)
- (m4__symtab_remove_module_references): Use new wrapper.
- * m4/builtin.c (m4_builtin_find_by_name, m4_builtin_find_by_func):
- Likewise.
- * m4/module.c (m4_get_module_name, m4_module_import)
- (m4_module_load): Likewise.
- (install_builtin_table, install_macro_table): Likewise. Also,
- change return type since these always returned NULL and no one
- used the result.
- (m4_module_makeresident, m4_module_refcount): New functions.
- (m4_module_unload, m4__module_next, m4__module_find): Use new
- wrapper.
- (m4__module_open): Populate new wrapper, and associate it with the
- lt_dlhandle.
- (m4__module_exit): Use new wrapper.
- (module_remove): Likewise. Reclaim storage on last use.
- (module_close): Delete, and inline into module_remove.
- * m4/symtab.c (m4__symtab_remove_module_references): Use new
- wrapper.
- * modules/load.c (load_init): Use new API.
- * modules/m4.c (m4_export_table): Kill unused declaration.
- (m4_init): Use new API.
- * modules/shadow.c (shadow_init): Use new API.
- * src/main.c (main): Adjust callers.
- * src/freeze.c (reload_frozen_state): Likewise.
- * tests/modules.at (unload load module): New test.
-
-2007-09-03 Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap (ltdl/m4/.cvsignore): Add xstrtol module macros.
- * src/m4/.cvsignore: Add xstrtol module sources.
-
-2007-09-03 Gary V. Vaughan <gary@gnu.org>
-
- Work around a bug in darwin's awk:
-
- * bootstrap (func_get_translations): Use $AWK instead of raw
- `awk' so that the user can use an alternative implementation
- if the first awk in PATH doesn't behave as expected.
- (func_get_translations): The first awk script mangles the last
- entry passed to it for at least the awk implementation shipped
- with Darwin 8.10.1. Capture $3 into a variable too to work-
- around that problem.
-
-2007-08-29 Gary V. Vaughan <gary@gnu.org>
-
- As gnulib xstrtol is only used by main, and unconditionally pulls
- in a copy of getopt, undo bootstrap change from 2007-08-11 below,
- and copy the xstrtol code into src/ so that main() can use it
- without pushing the extra code into libm4:
-
- * bootstrap (src_modules): Add getopt and xstrtol modules.
- * Makefile.am (src_m4_SOURCES): Add xstrtol sources.
- * po/POTFILES.in: Move gnu/xstrtol-error.c to src/xstrtol-error.c.
-
-2007-08-11 Eric Blake <ebb9@byu.net>
-
- Another upstream xstrtol change.
- * po/POTFILES.in: Track changes in files containing messages.
- * bootstrap (src_modules): getopt is now pulled into libgnu.a, no
- need to grab it separately.
- * src/main.c (OPT_STR, LONG_OPT_STR, short_opt_str, OPT_STR_INIT):
- No longer needed.
- (size_opt): Adjust to latest xstrtol interface.
-
-2007-08-10 Eric Blake <ebb9@byu.net>
-
- Documentation improvements.
- * doc/m4.texinfo (Defn): Resync with branch.
- (Compatibility, Extensions): Sync with branch.
-
-2007-08-07 Eric Blake <ebb9@byu.net>
-
- Adjust to gnulib xstrtol changes.
- * src/main.c (size_opt): Adjust signature, so that error strings
- are easier to translate.
- (OPT_STR, LONG_OPT_STR, short_opt_str, OPT_STR_INIT): New macros
- for tracking long options.
- (main): Track which long option was used.
- * tests/options.at (--debuglen, --nesting-limit): Adjust to change
- in error message.
- (deprecated options): Test that --arglength spelling shows up in
- error message.
-
-2007-08-06 Eric Blake <ebb9@byu.net>
-
- Normalize all GPL license notices.
- * m4/COPYING.LIB: Delete - libm4 is not distributed under LGPLv2
- at this time.
- * Makefile.am: Update license wording.
- * bootstrap: Likewise.
- * commit: Likewise.
- * configure.ac: Likewise.
- * ltdl/config/mailnotify: Likewise.
- * ltdl/config/mkstamp: Likewise.
- * ltdl/m4/debug.m4: Likewise.
- * ltdl/m4/gmp.m4: Likewise.
- * ltdl/m4/m4-error.m4: Likewise.
- * ltdl/m4/m4-getopt.m4: Likewise.
- * ltdl/m4/m4-gettext.m4: Likewise.
- * ltdl/m4/m4-obstack.m4: Likewise.
- * ltdl/m4/m4-regex.m4: Likewise.
- * ltdl/m4/stackovf.m4: Likewise.
- * m4/builtin.c: Likewise.
- * m4/debug.c: Likewise.
- * m4/hash.c: Likewise.
- * m4/hash.h: Likewise.
- * m4/input.c: Likewise.
- * m4/m4.c: Likewise.
- * m4/m4module.h: Likewise.
- * m4/m4private.h: Likewise.
- * m4/macro.c: Likewise.
- * m4/module.c: Likewise.
- * m4/output.c: Likewise.
- * m4/path.c: Likewise.
- * m4/resyntax.c: Likewise.
- * m4/symtab.c: Likewise.
- * m4/syntax.c: Likewise.
- * m4/system_.h: Likewise.
- * m4/utility.c: Likewise.
- * modules/evalparse.c: Likewise.
- * modules/format.c: Likewise.
- * modules/gnu.c: Likewise.
- * modules/import.c: Likewise.
- * modules/load.c: Likewise.
- * modules/m4.c: Likewise.
- * modules/m4.h: Likewise.
- * modules/modtest.c: Likewise.
- * modules/mpeval.c: Likewise.
- * modules/perl.c: Likewise.
- * modules/shadow.c: Likewise.
- * modules/stdlib.c: Likewise.
- * modules/time.c: Likewise.
- * modules/traditional.c: Likewise.
- * po/Makevars: Likewise.
- * src/freeze.c: Likewise.
- * src/m4.h: Likewise.
- * src/main.c: Likewise.
- * src/stackovf.c: Likewise.
- * tests/builtins.at: Likewise.
- * tests/freeze.at: Likewise.
- * tests/generate.awk: Likewise.
- * tests/m4.in: Likewise.
- * tests/macros.at: Likewise.
- * tests/modules.at: Likewise.
- * tests/options.at: Likewise.
- * tests/others.at: Likewise.
- * tests/stackovf.test: Likewise.
- * tests/testsuite.at: Likewise.
-
-2007-07-22 Eric Blake <ebb9@byu.net>
-
- Fix diversions on NetBSD, when fopen(name,"a+") seeks to end.
- * m4/output.c (m4_tmpopen): Explicitly seek to beginning.
- * tests/builtins.at (divert): Enhance test to cover this.
- * THANKS: Update.
- Reported by Thomas Klausner.
-
-2007-07-20 Eric Blake <ebb9@byu.net>
-
- Fix 'make distcheck' issues.
- * bootstrap: Add more files that might be more up-to-date in
- gnulib.
- * Makefile.am (EXTRA_DIST): No longer distribute removed diff.
- * config/m4/gnulib-cache.m4: Update to latest gnulib.
-
-2007-07-16 Eric Blake <ebb9@byu.net>
-
- * po/POTFILES.in: Track recent translation additions from gnulib
- updates.
-
-2007-07-14 Eric Blake <ebb9@byu.net>
-
- Reflect upstream license .texi changes.
- * doc/m4.texinfo (Copying): Rename node...
- (GNU General Public License): ...to this.
- (GNU Free Documentation License): Adjust node location.
- * local/doc/gpl-3.0.texi.diff: Remove file.
-
-2007-07-10 Eric Blake <ebb9@byu.net>
-
- Upgrade to GPLv3, and document 1.4.10.
- * bootstrap: Adjust to GPLv3.
- (func_update): Port from branch.
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool
- --local-dir=local --import gpl-3.0'.
- * doc/m4.texinfo (History): Mention 1.4.11.
- (Copying This Package): New appendix.
- * NEWS: Document 1.4.10.
- * local/doc/gpl-3.0.texi.diff: New file.
- * Makefile.am: Update license.
- (doc_m4_TEXINFOS, EXTRA_DIST): Distribute additions.
- * commit: Update license.
- * configure.ac: Likewise.
- * ltdl/config/mailnotify: Likewise.
- * ltdl/config/mkstamp: Likewise.
- * ltdl/m4/debug.m4: Likewise.
- * ltdl/m4/gmp.m4: Likewise.
- * ltdl/m4/m4-error.m4: Likewise.
- * ltdl/m4/m4-getopt.m4: Likewise.
- * ltdl/m4/m4-gettext.m4: Likewise.
- * ltdl/m4/m4-obstack.m4: Likewise.
- * ltdl/m4/m4-regex.m4: Likewise.
- * ltdl/m4/stackovf.m4: Likewise.
- * m4/builtin.c: Likewise.
- * m4/debug.c: Likewise.
- * m4/hash.c: Likewise.
- * m4/hash.h: Likewise.
- * m4/input.c: Likewise.
- * m4/m4.c: Likewise.
- * m4/m4module.h: Likewise.
- * m4/m4private.h: Likewise.
- * m4/macro.c: Likewise.
- * m4/module.c: Likewise.
- * m4/output.c: Likewise.
- * m4/path.c: Likewise.
- * m4/resyntax.c: Likewise.
- * m4/symtab.c: Likewise.
- * m4/syntax.c: Likewise.
- * m4/system_.h: Likewise.
- * m4/utility.c: Likewise.
- * modules/evalparse.c: Likewise.
- * modules/format.c: Likewise.
- * modules/gnu.c: Likewise.
- * modules/import.c: Likewise.
- * modules/load.c: Likewise.
- * modules/m4.c: Likewise.
- * modules/m4.h: Likewise.
- * modules/modtest.c: Likewise.
- * modules/mpeval.c: Likewise.
- * modules/perl.c: Likewise.
- * modules/shadow.c: Likewise.
- * modules/stdlib.c: Likewise.
- * modules/time.c: Likewise.
- * modules/traditional.c: Likewise.
- * po/Makevars: Likewise.
- * src/freeze.c: Likewise.
- * src/m4.h: Likewise.
- * src/main.c: Likewise.
- * src/stackovf.c: Likewise.
- * tests/builtins.at: Likewise.
- * tests/freeze.at: Likewise.
- * tests/generate.awk: Likewise.
- * tests/m4.in: Likewise.
- * tests/macros.at: Likewise.
- * tests/modules.at: Likewise.
- * tests/options.at: Likewise.
- * tests/others.at: Likewise.
- * tests/stackovf.test: Likewise.
- * tests/testsuite.at: Likewise.
-
-2007-07-09 Eric Blake <ebb9@byu.net>
-
- * modules/format.c (format): Avoid undefined behavior with %c.
-
-2007-07-01 Gary V. Vaughan <gary@gnu.org>
-
- The translation project has moved.
- * bootstrap (func_get_translations): Use the new translation
- project url.
- (TP_URL): Removed.
-
-2007-06-26 Karl Berry <karl@freefriends.org> (tiny change)
-
- Match Free Software Directory categories.
- * doc/m4.texinfo (dircategory): Update.
-
-2007-05-31 Eric Blake <ebb9@byu.net>
-
- Add extension to divert builtin.
- * modules/m4.c (builtin_divert): Immediately divert second
- argument.
- * m4/output.c (m4_output_text): Allow 0 length. Fixes regression
- from two days ago.
- (m4_shipout_text): Short-circuit on zero length.
- * tests/freeze.at (loading format 2): Expand test to catch
- regression. Also check out-of-range version.
- * tests/builtins.at (divert): Expand test to check corner cases
- of extension.
- * doc/m4.texinfo (Divert): Document the extension.
- * NEWS: Likewise.
- Reported by Daniel Richard G.
-
-2007-05-30 Eric Blake <ebb9@byu.net>
-
- Port format improvements from branch.
- * doc/m4.texinfo (History): Mention upcoming 1.4.10 release.
- (Format): Enhance section.
- * modules/format.c (format): Accept %'hhd, and issue warnings on
- unrecognized specifiers.
- * modules/gnu.c (builtin_format): Adjust how format is called.
-
-2007-05-28 Eric Blake <ebb9@byu.net>
-
- * tests/options.at (--syncoutput): Add xfailed test.
-
- Fix sync line interaction with multiline comments.
- * doc/m4.texinfo (Preprocessor features): Improve documentation.
- (Syncoutput): Improve testsuite.
- (Incompatibilities): Add testcase, and document bug.
- * src/freeze.c (reload_frozen_state): Don't interfere with
- synclines when reloading state.
- * m4/input.c (m4__next_token): Report line where multiline tokens
- start.
- * m4/m4private.h (m4__token_type): Add parameter.
- * m4/m4module.h (m4_output_text): Export.
- (m4_shipout_text): Add parameter.
- * src/macro.c (m4_macro_expand_input, expand_token)
- (expand_argument): Adjust callers so that line is passed from
- input to output.
- * m4/output.c (output_text): Rename...
- (m4_output_text): ...to this, and export.
- (m4_insert_file, insert_diversion_helper): Update callers.
- (m4_shipout_text): Take new parameter for start line of token.
- Output at most one syncline per token.
- Reported by Sergey Poznyakoff.
-
- Fix large diversion corner cases.
- * tests/freeze.at (large diversion): New test.
- * m4/output.c (m4_tmpfile, m4_tmpopen): Simplify use of errno.
- (make_room_for): Use NULL, not 0, for pointers.
- (m4_freeze_diversions): Allow freezing large diversions.
- (insert_diversion_helper): Avoid using rewind.
-
- Also run gnulib unit tests during make check.
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool
- --tests-base=tests/gnu --with-tests'.
- * configure.ac (AC_CONFIG_FILES): Build tests/gnu testdir.
- * Makefile.am (SUBDIRS): Run gnulib tests before ours.
-
-2007-05-25 Eric Blake <ebb9@byu.net>
-
- * m4/system_.h: Include <stdint.h>, for intmax_t.
- * THANKS: Update.
- Reported by Daniel Richard G.
-
-2007-05-24 Eric Blake <ebb9@byu.net>
-
- Provide consistent shift semantics regardless of hardware.
- * modules/m4.c (numb_lshift, numb_rshift, numb_urshift): Mask
- before shifting.
- (number, unumber): Always use [u]intmax_t.
- Reported by Gary V. Vaughan.
-
- Support POSIX flush semantics on all platforms.
- * modules/m4.c (m4_sysval_flush): Rely on gnulib.
- * ltdl/m4/gnulib-cache.m4: Fix typo in previous commit.
-
- Work around cygwin and mingw fseeko bugs.
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- fseeko'.
- * modules/m4.c (m4_sysval_flush): Prefer fseeko over fseek.
-
-2007-04-25 Eric Blake <ebb9@byu.net>
-
- Test that regression in 1.4.9's eval doesn't recur.
- * doc/m4.texinfo (Eval): Check negative division.
- * THANKS: Update.
-
-2007-04-12 Eric Blake <ebb9@byu.net>
-
- Allow for running test in sticky or setgid directory.
- * tests/builtins.at (mkdtemp): Adjust test.
-
- Don't test for broken sed too soon.
- * tests/others.at (stdin seekable): Rearrange subtests.
-
- Work around 'stdin seekable' shortcoming on glibc.
- * ltdl/m4/gnulib-cache.m4: Use closein instead of closeout.
- * tests/others.at (stdin closed): Adjust to new output.
- * src/main.c (process_file): No need to return anything.
- (main): Use close_stdin instead of close_stdout.
- Reported by Ralf Wildenhues.
-
- Enable autobuild usage.
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- autobuild'.
- * configure.ac (AB_INIT): Output autobuild information.
-
-2007-04-11 Eric Blake <ebb9@byu.net>
-
- Address testsuite shortcoming in 'stdout full' on glibc.
- * tests/others.at (stdout full): Adjust expected output when more
- than 1k text is printed to /dev/full.
- Reported by Ralf Wildenhues.
-
-2007-04-10 Eric Blake <ebb9@byu.net>
-
- * tests/macros.at (Arity and defn): Fix quoting.
-
-2007-04-09 Eric Blake <ebb9@byu.net>
-
- Address failure of 'seekable stdin' on Mac OS X.
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- fflush'.
-
-2007-04-07 Eric Blake <ebb9@byu.net>
-
- Include <config.h> first in all C files, and not in headers.
- Fixes regression for --disable-assert builds from 2007-04-02.
- * src/m4.h (includes): Don't include config.h here.
- * m4/m4private.h (includes): Likewise.
- * m4/builtin.c: Include config.h before anything else.
- * m4/debug.c: Likewise.
- * m4/hash.c: Likewise.
- * m4/input.c: Likewise.
- * m4/m4.c: Likewise.
- * m4/macro.c: Likewise.
- * m4/module.c: Likewise.
- * m4/symtab.c: Likewise.
- * m4/syntax.c: Likewise.
- * m4/utility.c: Likewise.
- * src/freeze.c: Likewise.
- * src/stackovf.c: Likewise.
-
-2007-04-03 Eric Blake <ebb9@byu.net>
-
- * modules/m4.c (numb_ratio, numb_divide, numb_modulo): Avoid
- SIGFPE on x86 architectures.
- Reported by Ralf Wildenhues.
-
-2007-04-02 Eric Blake <ebb9@byu.net>
-
- Fix warnings from last commit.
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- fprintf-posix sprintf-posix'.
- * m4/macro.c (expand_macro, trace_format): Use correct specifier
- for size_t.
- (process_macro): Avoid negative array index.
- * src/freeze.c (produce_resyntax_dump, produce_module_dump)
- (dump_symbol_CB, produce_frozen_state): Use correct specifier for
- size_t.
-
-2007-04-02 Gary V. Vaughan <gary@gnu.org>
-
- Get rid of the last 'differs in signedness' compiler warnings:
-
- * m4/macro.c (process_macro): m4_get_symbol_value_text() returns
- a regular 'char *', so variables to store the return address,
- and iterate through it should be regular 'char *' too.
- * m4/input.c (m4_input_block): The start and current members of
- the string part of this union store regular 'char *' types, so
- they should be regular 'char *' types too.
-
-2007-04-02 Gary V. Vaughan <gary@gnu.org>
-
- M4 was designed to have a small number of header files defining
- the interfaces to several source files each. Keeping this in
- mind allows us to tidy things up considerably. Having done this,
- it becomes clear that some of the installed headers reference
- other headers which are not installed (but that's another patch):
-
- * m4/m4private.h (stdio--.h, stdlib--.h, unistd--.h): Moved from
- here...
- * m4/system_.h (gnu/stdio--.h, gnu/stdlib--.h, gnu/unistd--.h):
- ...to here, so client modules can benefit too.
- (assert.h, errno.h, limits.h, sys/stat.h): Include one here at the
- lowest level to save doing it multiple times elsewhere.
- * m4/debug.c (stdio.h): Removed. The portable <gnu/stdio--.h>
- is already included via m4private.h.
- * modules/time.c (stdio.h): Ditto.
- * modules/gnu.c (stdlib.h): Ditto resp <gnu/stdlib--.h>.
- * modules/stdlib.c (stdlib.h, unistd.h): Ditto resp <gnu/stdlib--.h>
- and <gnu/unistd--.h>,
- * m4/m4private.h (m4module.h): Use angle brackets for an installed
- file.
- * m4/hash.h (system.h): Ditto.
- * modules/gnu.c (progname.h): Removed.
- * src/freeze.c (m4/system.h, m4private.h): Already included vi m4.h.
- * m4/m4private.h (assert.h, errno.h): Already included via
- m4/m4module.h.
- * m4/input.c (ctype.h): Ditto.
- * m4/module.c (ltdl.h): Ditto.
- * m4/output.c (errno.h, limits.h, stdio.h, sys/types.h, sys/stat.h)
- (unistd.h): Ditto.
- * m4/path.c (config.h, stdlib.h): Ditto.
- * m4/utility.c (config.h): Ditto.
- * modules/evalparse.c (assert.h, ctype.h): Ditto.
- * modules/gnu.c (assert.h, ctype.h, errno.h): Ditto.
- * modules/import.c (assert.h): Ditto.
- * modules/m4.c (assert.h, errno.h): Ditto.
- * modules/modtest.c (assert.h): Ditto.
- * modules/stdlib.c (sys/types.h): DittAo.
- * src/m4.h (ctype.h, errno.h, string.h, sys/types.h, ltdl.h):
- Ditto.
- * src/stackovf.c (assert.h): Ditto.
- * modules/gnu.c (m4/m4module.h, m4private.h): Build using the faster
- private interfaces when NDEBUG is defined.
- * modules/import.c (m4/m4module.h, m4private.h): Ditto.
- * modules/load.c (m4/m4module.h, m4private.h): Ditto.
- * modules/m4.c (m4/m4module.h, m4private.h): Ditto.
- * modules/modtest.c (m4/m4module.h, m4private.h): Ditto.
- * modules/mpeval.c (m4/m4module.h, m4private.h): Ditto.
- * modules/perl.c (m4/m4module.h, m4private.h): Ditto.
- * modules/shadow.c (m4/m4module.h, m4private.h): Ditto.
- * modules/time.c (m4/m4module.h, m4private.h): Ditto.
- * modules/traditional.c (m4/m4module.h, m4private.h): Ditto.
- * src/m4.h (locale.h): Moved from here...
- * src/main.h: ...to here.
- (m4private.h): Already included via m4.h.
- * src/stackovf.c (m4private.h): Ditto.
-
-2007-03-28 Gary V. Vaughan <gary@gnu.org>
-
- * Makefile.am (stamp-vcl): Removed.
- (CONFIG_STATUS_DEPENDENCIES): Depend directly on ChangeLog.
-
-2007-03-28 Eric Blake <ebb9@byu.net>
-
- * src/main.c (usage): Improve note to TRANSLATORS.
- * m4/system_.h (EXIT_FAILURE): Reflect gnulib changes.
-
- * tests/builtins.at (__m4_version__): Fix bug when TIMESTAMP is
- empty.
-
-2007-03-24 Eric Blake <ebb9@byu.net>
-
- * m4/output.c (m4_output_init): Update to latest gnulib.
- * bootstrap (ltdl/m4/.cvsignore): No longer track generated
- .cvsignore in CVS.
- * NEWS: Reflect release of 1.4.9.
- * THANKS: Update.
-
-2007-03-07 Eric Blake <ebb9@byu.net>
-
- * AUTHORS: Update
-
- Exercise gnulib's new POSIX *printf modules.
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- vasprintf-posix'.
- * modules/format.c (format): Support %a and %A.
- * doc/m4.texinfo (Format): Test this addition.
- * NEWS: Document this addition.
-
-2007-03-03 Eric Blake <ebb9@byu.net>
-
- * m4/input.c (m4__next_token): Fix synclines when in batch mode.
- * doc/m4.texinfo (M4exit): Synch another section.
- (Syncoutput): Make similar to other sections.
-
-2007-03-01 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo: Improve the indices.
- (Concept index): Rearrange to be last.
- (Sysval): Merge from branch.
-
- * doc/m4.texinfo (Syscmd, Esyscmd): Merge more doc sections.
-
-2007-02-28 Eric Blake <ebb9@byu.net>
-
- POSIX XCU ERN 137 was approved.
- * modules/mpeval.c (numb_extension): Delete.
- * modules/m4.c (numb_extension): Likewise.
- * modules/evalparse.c (comma_term, condition_term): Always
- implement ?: and , operators.
- * m4/symtab.c: Update comment to match reality.
- * src/freeze.c (produce_frozen_state, reload_frozen_state): Avoid
- dereferencing context directly when accessor exists.
- * src/main.c (usage): Prefer GNU_M4 over EMACS.
- (struct macro_definition): Rename...
- (struct deferred): ...to match usage. All uses changed.
- * doc/m4.texinfo (Eval): Document this change.
- (Operation modes, Changeresyntax): Fix wording to prefer GNU_M4
- over emacs.
- (Preprocessor features, Changesyntax): Fix inaccuracies.
- * NEWS: Import branch NEWS items for 1.4.x series. Document
- change in eval.
-
- POSIX XCU ERN 118 was approved.
- * modules/m4.c (define): Kill posixly_correct distinction in
- define behavior, since POSIX says GNU behavior complies.
- * tests/builtins.at (define): Restore original semantics.
- * doc/m4.texinfo (Pushdef): Document portability issues with
- define.
- (Incompatibilities): Clean up wording of what POSIX requires.
- * NEWS: Document this.
-
-2007-02-26 Eric Blake <ebb9@byu.net>
-
- Re-enable clean bootstrap on cygwin.
- * Makefile.am (AM_LDFLAGS): For now, export all symbols from
- modules, since otherwise we run afoul of current libtool
- limitations on cygwin and mingw.
-
-2007-02-25 M. Levinson <levinsm@users.sourceforge.net> (tiny change)
-
- * src/freeze.c (reload_frozen_state): Avoid dereferencing freed
- memory. Fixes regression introduced 2007-01-20.
-
-2007-02-25 Eric Blake <ebb9@byu.net>
-
- * tests/freeze.at (loading format 2): Augment test to catch
- regression introduced on 2007-01-20.
- * THANKS: Update.
- Reported by M. Levinson.
-
- * m4/system_.h (includes, EXIT_SUCCESS, EXIT_FAILURE): Adjust to
- latest gnulib.
-
-2007-02-05 Eric Blake <ebb9@byu.net>
-
- * tests/options.at (--fatal-warnings): New test.
- * tests/others.at (stdin seekable): Exit on error.
- * m4/m4private.h (M4_OPT_WARN_EXIT_BIT): New bit.
- (m4_get_warnings_exit_opt): Access it.
- * m4/m4module.h (m4_context_opt_bit_table): Access it.
- * m4/utility.c (m4_error, m4_error_at_line): Only force an exit
- on -EE.
- (m4_warn, m4_warn_at_line): Change exit status on -E, and force
- exit on -EE.
- * src/m4.c (usage): Document new -E behavior.
- (main): Make -E an additive option.
- * doc/m4.texinfo (Operation modes): Document the change.
- Reported by Ralf Wildenhues.
-
- * tests/others.at (stdin seekable): Fix bug in test.
- * ltdl/m4/gnulib-cache.m4: Gnulib module strstr no longer exists.
-
- * m4/input.c (struct m4_input_block): Remove unused field traced.
-
-2007-02-03 Eric Blake <ebb9@byu.net>
- and Bruno Haible <bruno@clisp.org> (tiny change)
-
- * doc/m4.texinfo (Input processing, Quoting Arguments): Beef up
- the examples.
- Reported by Bruno Haible.
-
-2007-01-31 Eric Blake <ebb9@byu.net>
-
- * m4/resyntax.c (m4_regexp_syntax_encode): Detect allocation
- failure.
-
-2007-01-26 Eric Blake <ebb9@byu.net>
-
- * m4/symtab.c (includes): Adjust to latest gnulib.
- * modules/m4.c (includes): Likewise.
-
-2007-01-23 Eric Blake <ebb9@byu.net>
-
- * m4/m4module.h (M4_SYNTAX_ASSIGN): Delete this unused
- extension to make enough room.
- (M4_SYNTAX_IGNORE): Change value to zero, since the (commented)
- code in input.c special cases this category.
- (M4_SYNTAX_LBRACE, M4_SYNTAX_RBRACE): New values in preparation
- for define(eleventh,${11}) extension.
- * m4/syntax.c: Update comments accordingly.
- (m4_syntax_create, m4_syntax_code): Handle { and }.
- * m4/input.c (m4__next_token): Likewise.
- * src/freeze.c (produce_frozen_state): Support new categories.
- (reload_frozen_state): When loading version 1, disable syntax
- features not present in 1.4.x.
- * tests/freeze.at: Sort and rename existing tests.
- (loading format 1): Ensure we don't break v1 frozen files that
- used raw ${.
- (loading format 2, reloading changecom, reloading changesyntax):
- New tests.
- * doc/m4.texinfo (Changesyntax, Frozen file format 1): Document
- the new syntax categories.
- (Arguments): Update the FIXME comment.
- (M4wrap): Merge examples from branch, before worrying about fixing
- m4wrap to obey POSIX.
- (Using frozen files): Start merging from branch.
- * NEWS: Update.
-
-2007-01-20 Eric Blake <ebb9@byu.net>
-
- * src/freeze.c (produce_char_dump): Delete. Replace with...
- (produce_mem_dump): ...this new function, to encode more strings.
- Also make the coding easier to read and slightly more compact.
- (produce_syntax_dump): Only dump non-default syntax codes.
- (produce_module_dump, dump_symbol_CB, produce_frozen_state):
- Encode non-ASCII characters in user-supplied strings.
- (GET_STRING): Accept escape sequences in version 2.
- * NEWS: Document this change.
- * TODO: Update.
-
-2007-01-16 Eric Blake <ebb9@byu.net>
-
- Port patch from branch for stack overflow detection on BSD/OS.
- * ltdl/m4/stackovf.m4 (M4_SYS_STACKOVF): Check for stack_t.ss_sp.
- * src/stackovf.c (setup_stackovf_trap) [HAVE_SIGALTSTACK &&
- ! HAVE_STACK_T_SS_SP]: Use this check.
- Reported by Chris McGuire.
-
-2007-01-15 Eric Blake <ebb9@byu.net>
-
- * tests/builtins.at (__m4_version__): New test.
- * modules/traditional.c (m4_macro_table): Provide windows and os2
- macros, as appropriate. Add __traditional__ macro.
- * modules/mpeval.c (m4_macro_table): Name the macro __mpeval__,
- not __gmp__, to match module name.
- * modules/load.c (m4_macro_table): Name the macro __load__, not
- __modules__, to match module name.
- * doc/m4.texinfo (History, Shell commands, Platform macros): Merge
- from the branch.
- (Standard Modules): Improve wording.
- (Incompatibilities): Move platform macros into their own node.
- (Load, Unload): Use actual examples.
- * NEWS: Document this change.
- * THANKS: Update.
-
-2007-01-13 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Mpeval): Add tests.
- * tests/testsuite.at (AT_CHECK_GMP): New filter, factored from...
- * tests/builtins.at (gmp): ...here. Rename test to...
- (mpeval): ...this.
- * tests/generate.awk (new_test): Filter out mpeval tests when gmp
- is not available.
- * m4/m4module.h (m4_get_no_gnu_extensions_opt): Merge
- no_gnu_extensions with posixly_correct_opt, since they were set in
- sync.
- * m4/m4private.h (struct m4): Remove no_gnu_extensions.
- * src/main.c (main): Update caller.
- * src/freeze.c (reload_frozen_state): Likewise.
- * modules/m4.c (m4wrap): Likewise.
-
-2007-01-12 Eric Blake <ebb9@byu.net>
-
- * m4/syntax.c (m4_set_comment): XCU ERN 131 was approved by
- POSIX, so update the comment.
- * doc/m4.texinfo (Inhibiting Invocation): XCU ERN 130 was
- approved by POSIX, so we can always have blind macros, even when
- POSIXLY_CORRECT.
- (Ifelse): Mention the term `blind builtin'.
-
-2007-01-08 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * doc/m4.texinfo: Fix a couple of typos.
-
-2007-01-08 Eric Blake <ebb9@byu.net>
-
- * ltdl/m4/gnulib-cache.m4: Update for new year.
- * ltdl/m4/gmp.m4 (_M4_LIB_GMP): Cover all error cases.
- Reported by Ralf Wildenhues.
-
-2007-01-06 Eric Blake <ebb9@byu.net>
-
- * m4/m4private.h (to_uchar): Move...
- * m4/m4module.h: here, so modules can use it.
- * src/main.c (usage, long_options): Support --posix as a synonym
- for --traditional.
- * modules/m4.c (numb_invert): Detect unsupported x**-y.
- (numb_incr, numb_urshift, numb_extension): New macros.
- (numb_obstack): Port patch from branch to support radix 1 output.
- * modules/mpeval.c (numb_obstack): Use \ for ratios.
- (numb_incr, numb_urshift, numb_extension): New macros.
- (mpq2mpz): Warn rather than error.
- * modules/evalparse.c (URSHIFT, NEGATIVE_EXPONENT): New
- enumerators.
- (eval_error): Rearrange, so that all ignorable errors are less
- than SYNTAX_ERROR.
- (eval_text, last_text): Obey C++ type safety rules.
- (numb_pow): Change return type.
- (exp_term): Adjust caller.
- (m4_evaluate): Fail on bad exponent.
- (logical_or_term, logical_and_term): Ignore failed ** in short
- circuit.
- (eval_lex): Fix typos when detecting <<= and >>=. Use \ instead
- of : for ratio. Support >>>, ,, and ?:. Port patch from branch
- to parse radix 1 numbers.
- (condition_term, comma_term): New parse functions.
- (shift_term): Support >>>.
- (m4_evaluate): Port patch from branch to output radix 1 numbers.
- Warn instead of error for most parse problems.
- * doc/m4.texinfo (Limits control, Eval): Document these changes.
- * NEWS: Document new operators and new command line option.
-
-2007-01-04 Eric Blake <ebb9@byu.net>
-
- * configure.ac (AC_SYS_LARGEFILE): Guarantee large file support.
-
-2007-01-03 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Format, Incr): More merges.
- (Eval): Ensure C precedence rules are met.
- * modules/evalparse.c (BADOP, INVALID_OPERATOR): New enumerators.
- (not_term, logical_not_term): Delete; these are same precedence
- as other unary operators.
- (equality_term): New; these are lower precedence than relational
- operators.
- (eval_lex, simple_term, m4_evaluate): Recognize forbidden C
- operators for better error messages.
- (logical_or_term, logical_and_term): Short-circuit out the error
- of division by zero.
- (unary_term): Allow consecutive unary operators.
- * modules/m4.c (int2numb, numb2int): Delete; these potentially
- truncate bits.
- (numb_not, numb_eor, numb_ior, numb_and): Update callers.
- * modules/mpeval.c (reduce1, reduce2): Protect macros better.
- * NEWS: Document this change.
-
-2006-12-27 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Substr, Patsubst): Merge more sections from the
- branch.
- * modules/m4.c (substr): Merge from branch.
-
-2006-12-26 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Changesyntax): Check for regressions with
- changesyntax(W=...).
-
-2006-12-22 Eric Blake <ebb9@byu.net>
-
- * m4/m4module.h (m4_set_syntax): Change signature.
- * modules/gnu.c (m4_resyntax_encode_safe): Reduce error to
- warning.
- (changesyntax): Likewise, and update caller.
- * m4/m4private.h (m4_syntax_table): Add orig member.
- * m4/syntax.c (m4_set_quotes, m4_set_comment): Merge from branch.
- Don't set is_single_quotes and is_single_comments when the begin
- character is shadowed by another syntax type.
- (m4_syntax_create): Populate default syntax table.
- (add_syntax_attribute): Don't lose quote assignment.
- (remove_syntax_attribute): Only allow removing rquote or ecomm.
- (add_syntax_set, subtract_syntax_set, set_syntax_set)
- (reset_syntax_set): New helper routines.
- (m4_set_syntax): Alter semantics - NUL key reverts entire syntax
- to default, and empty chars reverts that key to default.
- (check_is_single_quotes, check_is_single_comments): New helper
- routines.
- * modules/m4.c (changecom): Merge from branch.
- * m4/input.c (m4__next_token): Rearrange token recognition order
- to macro, quote, comment, in order to match traditional
- implementations.
- * src/freeze.c (reload_frozen_state): Update caller.
- * doc/m4.texinfo (Changequote, Changecom): Merge from branch, with
- modifications.
- (Changeresyntax): Revise to match style of surrounding sections
- and add more examples.
- (Changesyntax): Likewise, and update to new semantics.
- * NEWS: Document this change.
-
- * doc/m4.texinfo (Operation modes): Avoid underfull hbox.
- (M4wrap, Eval, Errprint): Fix typos.
- (Divnum): Not necessary to redivert in example.
-
-2006-12-21 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Len, Index macro, Regexp): More section merging
- from branch.
-
-2006-12-19 Eric Blake <ebb9@byu.net>
-
- * modules/m4.h (m4_sysval_flush_func): Adjust prototype.
- * modules/m4.c (m4_sysval_flush): Add parameter, so that m4exit
- can track write errors without all other callers warning multiple
- times.
- (sysval_flush_helper): New function.
- (dumpdef, syscmd, errprint, m4exit): Adjust callers.
- * modules/gnu.c (esyscmd): Likewise.
- * tests/others.at (stdout closed, stdout full): Error message
- update.
-
-2006-12-16 Eric Blake <ebb9@byu.net>
-
- * src/main.c: Fix missing include.
-
- * src/main.c (main): Check for errors when closing stdin.
- * modules/m4.c (m4exit): Missed part of previous patch: flush
- stdin before a successful exit.
- Reported by Ralf Wildenhues.
-
-2006-12-14 Eric Blake <ebb9@byu.net>
-
- * modules/m4.c (m4_sysval_flush): Flush stdin before exiting, as
- required by POSIX.
- * tests/others.at (stdin seekable): New test.
-
-2006-12-09 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * doc/m4.texinfo: Fix some typos.
-
-2006-12-04 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Undivert, Divnum, Cleardivert): Merge more doc
- sections.
- (Modules): Make style consistent.
-
-2006-11-16 Eric Blake <ebb9@byu.net>
-
- * bootstrap: Relax m4 requirement, thanks to...
- * configure.ac (Gettext support): ...this workaround to the 1.4.4
- bug. Undoes restriction added on 2006-11-09.
-
- * tests/builtins.at (esyscmd, syscmd): Redo, since spilled
- diversions are now closed when not active.
- (divert): Remove check now in the manual.
- * tests/others.at (stderr closed): Likewise.
- (stdout closed): Add a check.
- * doc/m4.texinfo (Include, Search Path, Diversions, Divert): Sync
- more docs with branch.
-
-2006-11-14 Eric Blake <ebb9@byu.net>
-
- Remerge sparse diversion handling from branch.
- * ltdl/m4/gnulib-cache.m4: Replace avltree-list with
- avltree-oset.
- * m4/output.c (diversion_table): Change type to gl_oset_t.
- (m4_output_init, m4_output_exit, cleanup_tmpfile, make_room_for)
- (m4_make_diversion, insert_diversion_helper, m4_insert_diversion)
- (m4_undivert_all, m4_freeze_diversions): Adjust all callers.
- (div0, diversion_storage): New variables.
- (diversions, equal_diversion_CB): Deleted.
- (threshold_diversion_CB): New callback.
- (m4_tmpname, m4_tmpopen, m4_tmpclose, m4_tmpremove): New
- functions.
- (m4_tmpfile): Move cloexec action here.
-
- * m4/resyntax.c (m4_regexp_syntax_encode): Avoid bug with signed
- char.
-
-2006-11-13 Eric Blake <ebb9@byu.net>
-
- Add several new command line options.
- * src/main.c (usage): Update.
- (OPTSTRING, long_options): Add --pushdef, --popdef, --gnu,
- --traceon, --traceoff, --syncoutput, --warnings, --unload-module.
- Make --regexp-syntax argument optional.
- (main): Support new options. Fix regression in interactive
- behavior from Nov 8.
- * m4/m4private.h (M4_OPT_SYNCOUTPUT_BIT): Rename from
- M4_OPT_SYNC_OUTPUT_BIT.
- * m4/m4module.h (m4_context_opt_bit_table): Rename sync_output to
- syncoutput, to match option.
- (m4_parse_truth_arg): New prototype.
- * m4/utility.c (m4_parse_truth_arg): Implement it.
- * m4/output.c (m4_shipout_text): Adjust sync_output caller.
- * modules/gnu.c (syncoutput): Adjust sync_output caller, and use
- m4_parse_truth_arg.
- * doc/m4.texinfo (Operation modes, Dynamic loading features)
- (Preprocessor features, Limits control, Debugging options)
- (Command line files): Update documentation.
- * tests/builtins.at (mkstemp): Simplify.
- * tests/macros.at (Command line pushdef): New test.
- (Command line define): Improve.
- * tests/options.at (--traceon and --traceoff, --syncoutput): New
- tests.
- (POSIXLY_CORRECT): Likewise.
- (deprecated options): Augment.
- (--regexp-syntax): Update, now that -r takes optional arg.
- * NEWS: Reformat. Document new options.
-
-2006-11-11 Eric Blake <ebb9@byu.net>
-
- One step closer to allowing C++ compilation - don't blindly
- convert between char* and unsigned char*.
- * m4/m4module.h (m4_set_syntax): Change signature.
- * m4/m4private.h (m4_string): Use signed char.
- (m4_get_syntax_lquote, m4_get_syntax_rquote, m4_get_syntax_bcomm)
- (m4_get_syntax_ecomm): No longer a need to cast.
- * m4/syntax.c (m4_set_syntax, m4_syntax_create, m4_set_quotes):
- Reflect this change.
- * m4/macro.c (expand_argument): Simplify.
- (expand_token): Use proper type.
- * src/freeze.c (reload_frozen_state): Likewise.
- * m4/input.c (MATCH, match_input): Likewise.
- * modules/m4.c (translit): Likewise.
- * modules/gnu.c (substitute): Simplify.
-
- * m4/macro.c (trace_format): Use canonical type name.
- * m4/output.c (m4_freeze_diversions): Likewise.
- * src/freeze.c (produce_module_dump, dump_symbol_CB)
- (produce_frozen_state): Likewise.
- * m4/m4private.h (to_uchar): Grab from branch.
- * m4/input.c (string_peek, string_read): Use it.
- * m4/utility.c (skip_space): Likewise.
- * src/main.c (main): Likewise.
- * doc/m4.texinfo (Translit): Remerge from branch.
- * tests/builtins.at (translit): Test 8-bit range.
- * modules/m4.c (m4_expand_ranges): Merge from branch.
-
-2006-11-09 Eric Blake <ebb9@byu.net>
-
- * bootstrap: Validate that installed M4 is powerful enough.
- Reported by Gary V. Vaughan, analyzed by Stepan Kasal.
-
-2006-11-08 Eric Blake <ebb9@byu.net>
-
- Merge deferred handling of -D option from branch.
- * doc/m4.texinfo (Debugging options, Preprocessor features)
- (Dynamic loading features, Operation modes, Invoking m4):
- Document this change.
- * src/main.c (OPTSTRING): Specify in-order processing.
- (process_file): New function.
- (main): Use it to interleave files and deferred options.
- * tests/macros.at (Command line define): New test.
- * tests/generate.awk: Allow '@comment file' as first example
- within a node.
- * tests/options.at (option grouping): Update to reflect actual
- POSIX semantics.
- (file names): New test.
-
-2006-11-07 Eric Blake <ebb9@byu.net>
-
- * m4/output.c (cleanup_tmpfile, m4_insert_diversion_helper): Check
- for failure.
-
- * tests/builtins.at (m4exit): New test; failed on cygwin before
- this patch.
- * m4/output.c (cleanup_tmpfile): Close files before removing
- directory.
- (make_room_for, m4_output_exit): Ensure that atexit handler
- invoked from m4_error sees consistent state.
-
- * doc/m4.texinfo (Errprint): Merge another doc node.
- * tests/builtins.at (dumpdef, errprint): New tests.
- * modules/m4.c (errprint): Merge from branch: flush before
- printing to stderr.
-
-2006-11-02 Eric Blake <ebb9@byu.net>
-
- * bootstrap: Update bootstrap requirement wording.
- Reported by Bruno Haible.
-
-2006-10-31 Eric Blake <ebb9@byu.net>
-
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- strstr'.
- * doc/m4.texinfo (Translit): Merge from branch.
- * modules/m4.c (divert, substr): Ignore excess arguments.
- (index, translit): Merge from branch.
- * tests/builtins.at (translit): Add a test.
-
-2006-10-30 Eric Blake <ebb9@byu.net>
-
- * m4/m4private.h (m4_get_symbol_value_module): Delete accidental
- checkin.
- * m4/symtab.c (m4_get_symbol_value_module): Likewise.
-
- * modules/m4.c (m4_make_temp): Make safe across libtool.
- * m4/symtab.c (dump_symbol_CB) [DEBUG_SYM]: Avoid warnings.
- * configure.ac (--with-modules): Accomodate changed module
- location when doing './configure --enable-debug'.
-
-2006-10-28 Eric Blake <ebb9@byu.net>
-
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- config-h.'
-
-2006-10-27 Eric Blake <ebb9@byu.net>
-
- * bootstrap (gnulib): No longer a need to patch after gnulib-tool
- --update.
- * configure.ac (AM_GNU_GETTEXT_VERSION): Bump requirement to
- 0.16, since 0.15 is incompatible with our automake requirement.
-
- * m4/macro.c (expand_argument): Fix missing initialization.
- * m4/m4private.h (struct m4_symbol_value): Store entire
- m4_builtin, not just the func.
- (m4_get_symbol_value_func): Update.
- (m4_get_symbol_value_builtin, m4_set_symbol_value_builtin): New
- fast accessors.
- * m4/m4module.h (m4_get_symbol_value_builtin)
- (m4_get_symbol_builtin): New prototypes.
- (m4_set_symbol_value_func): Delete, replace with...
- (m4_set_symbol_value_builtin): New function.
- (m4_builtin_find_by_name): Change signature.
- * m4/symtab.c (m4_symbol_value_print): Simplify.
- (m4_get_symbol_value_func): Update.
- (m4_get_symbol_value_builtin): New function.
- (m4_set_symbol_value_func): Delete, replace with...
- (m4_set_symbol_value_builtin): New function.
- (dump_symbol_CB) [DEBUG_SYM]: Simplify.
- * m4/builtin.c (m4_builtin_find_by_name): Change signature.
- * m4/input.c (struct m4_input_block): Remove unused trace member.
- (m4_push_builtin, builtin_print, init_builtin_token): Update
- callers.
- * m4/module.c (install_builtin_table): Likewise.
- * src/freeze.c (reload_frozen_state): Likewise.
- * modules/gnu.c (builtin): Make it possible to retrieve a builtin
- token, even after the builtin has been undefined.
- * doc/m4.texinfo (Builtin): Document new capability.
- * NEWS: Likewise.
-
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- tempname'.
- * modules/m4.c (m4_make_temp): Use it.
- * tests/builtins.at (mkstemp, mkdtemp): Update message wording.
-
-2006-10-27 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * Makefile.am (dist_pkgdata_DATA): Distribute recently-added
- files.
-
-2006-10-26 Eric Blake <ebb9@byu.net>
-
- Silence -O2 -Wall -Wwrite-strings warnings.
- * m4/m4private.h (m4_symbol_value): Const-ify text.
- * m4/m4module.h (m4_get_symbol_value_text)
- (m4_get_symbol_value_placeholder, m4_set_symbol_value_text)
- (m4_set_symbol_value_placeholder): Likewise.
- * m4/macro.c (expand_token, expand_argument, expand_macro): Fix
- fallout.
- * m4/symtab.c (m4_symbol_value_delete, m4_symbol_value_copy)
- (m4_get_symbol_value_text, m4_get_symbol_value_placeholder)
- (m4_set_symbol_value_text, m4_set_symbol_value_placeholder):
- Likewise.
- * modules/format.c (format): Likewise.
- * src/main.c (main): Likewise.
- * src/freeze.c (produce_symbol_dump, dump_symbol_CB): Likewise.
- * modules/shadow.c (shadow, test): Likewise.
- * m4/output.c (m4_make_diversion): Don't hold on to empty
- diversions.
- (m4_output_init, make_room_for, m4_undivert_all): Don't type-pun.
- (m4_freeze_diversions): Likewise. Don't use uninitialized
- variable.
-
- Convert diversions to list instead of sparse array, part 2.
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- avltree-list'.
- * m4/output.c (m4_diversion): Add next pointer and divnum members.
- (diversion_table): Convert to a list instead of a sparse array.
- (free_list): Maintain free list of reclaimed diversions.
- (equal_diversion_CB, cmp_diversion_CB): New functions.
- (m4_output_init): Set up list.
- (m4_output_exit): Tear down list.
- (make_room_for, m4_undivert_all, m4_freeze_diversions): Change
- list iteration.
- (m4_make_diversion): Change creation of new diversions.
- (m4_insert_diversion_helper): New function, to avoid list
- searches.
- * tests/builtins.at (divert): The test now passes.
- * NEWS: Document this improvement.
-
- Convert diversions to list instead of sparse array, part 1.
- * m4/m4module.h (m4_shipout_text, m4_shipout_string): Use size_t
- for length.
- * m4/output.c (diversion, total_buffer_size, output_unused):
- Track size in size_t. All users changed.
- (struct diversion): Reduce size now, to compensate for part 2.
- (m4_make_diversion, make_room_for): Avoid malloc overflow.
- (m4_output_exit): Fix typo in assert.
- (m4_output_init, make_room_for, m4_make_diversion)
- (m4_insert_diversion, m4_freeze_diversions): Adjust users of
- struct m4_diversion to disambiguate the new union.
- * tests/builtins.at (divert): Detect this failure.
-
-2006-10-25 Eric Blake <ebb9@byu.net>
-
- * m4/m4module.h (m4_push_builtin): Add parameter.
- * modules/m4.c (defn): Update caller.
- * m4/input.c (file_read_init, string_read_init): No longer
- needed.
- (input_funcs): Change signature of read_func, all callers
- updated.
- (composite_peek, composite_read, composite_unget),
- (composite_print, composite_funcs): New input type. Not yet
- fully utilized, but one step closer to fixing defn.
- (m4_input_block): Make every input block track current file and
- line. Rename some members. Remove unused out_line. Add support
- for composite input block.
- (input_change): New flag.
- (file_peek, file_read, file_clean, file_unget, file_print):
- Update callers.
- (m4_push_file, m4_push_builtin, m4_push_string_init)
- (m4_push_string_finish, m4_push_wrapup, m4_pop_wrapup)
- (m4_skip_line, pop_input): Track input block changes.
- (m4_pop_wrapup): Avoid overflow.
- (init_builtin_token): Handle composite input.
- (next_char): Handle input block changes.
- * doc/m4.texinfo (Location): Remerge from branch.
-
- * src/m4.h (includes): Need <locale.h> after all; fixes
- regression from yesterday.
-
- * m4/system_.h (obstack_regrow): New macro. Hopefully glibc will
- accept it someday.
- * m4/macro.c (expand_macro): Avoid referencing invalid memory.
- Handle nesting the argc obstack.
- (expand_token): Avoid unnecessary malloc.
- (collect_arguments): Copy name before invalidating it.
- (argc_stack, argv_stack): New variables.
- (m4_macro_expand_input): Initialize argc and argv stacks once per
- file, instead of once per macro.
-
-2006-10-24 Eric Blake <ebb9@byu.net>
-
- * src/m4.h (includes): Add gettext.h, for N_. Assume setlocale.
-
-2006-10-23 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Macro Arguments, Incompatibilities): Remerge
- from branch regarding stripped leading whitespace.
-
- * modules/m4.c (includes): Use safe headers even when configured
- with --enable-assert.
- (m4_builtin_table, m4_make_temp): Work around fact that mkstemp is
- #defined as mkstemp_safer.
-
-2006-10-21 Eric Blake <ebb9@byu.net>
-
- * modules/m4.c (m4_make_temp): Change signature.
- (maketemp, mkstemp): Update callers.
- * modules/m4.h (m4_make_temp_func): New export.
- * modules/gnu.c (mkdtemp): New macro.
- * doc/m4.texinfo (Operation modes): Document interaction with
- --safer.
- (Mkdtemp): New node.
- * tests/builtins.at (mkdtemp): New test.
- (mkstemp): Check for umask effect.
- * NEWS: Document new builtin.
-
- * tests/generate.awk (normalize): Update recognition of trailing
- spaces in tests.
- * doc/m4.texinfo: Minor formatting fixes from branch.
- (Foreach, Improved foreach): Merge from branch.
- * examples/foreach.m4: Merge from branch.
- * examples/foreachq.m4: New file from branch.
- * examples/foreach2.m4: Likewise.
- * examples/foreachq2.m4: Likewise.
-
- * doc/m4.texinfo (titlepage): Add myself as author.
- * src/main.c (AUTHORS): Likewise.
-
-2006-10-19 Eric Blake <ebb9@byu.net>
-
- * modules/m4.c (m4_make_temp, mkstemp): New functions.
- (maketemp): Add POSIX behavior and a warning.
- * tests/others.at (maketemp): Move this test...
- * tests/builtins.at (mkstemp): ...to here, and beef up.
- * tests/options.at (--safer): Update to new warning message.
- * doc/m4.texinfo (Mkstemp): Sync from branch.
- (Extensions): Update maketemp behavior.
- * NEWS: Document that maketemp now always warns.
-
- * tests/generate.awk: For ease of doc-writing, simplify selection
- of '-Ipath/to/examples' to '@comment examples'.
- * examples/forloop.m4: Simplify.
- * examples/forloop2.m4: New file.
- * examples/quote.m4: New file.
- * doc/m4.texinfo (Improved forloop): New node.
- (Manual): Clarify use of examples directory.
- (Shift, Forloop): Resync from branch.
- (Include, Location): Update to new usage of examples directory.
-
- * m4/system_.h (includes): Pick up <unistd.h> before checking for
- _POSIX_VERSION.
- (gettext_noop): Don't define here, let gettext.h do it instead.
- * po/POTFILES.in: Update entries to reflect gnulib imports.
-
-2006-10-16 Eric Blake <ebb9@byu.net>
-
- * ltdl/m4/gnulib-cache.m4: Augment with 'gnulib-tool --import
- configmake'.
- * configure.ac (AM_INIT_AUTOMAKE): Bump requirement to 1.10a, for
- pkglibexecdir support.
- * Makefile.am (m4_libm4_la_SOURCES, m4/pathconf.h): No longer
- worry about pathconf.h, now that gnulib does it for us.
- (pkgmodincludedir): Simplify.
- (pkglibexecdir): Delete, now that automake does this.
- * m4/module.c (m4__module_init): Use PKGLIBEXECDIR.
- * src/main.c (usage): Likewise.
- * m4/symtab.c (m4_symbol_value_groks_macro): Fix typo.
-
- * doc/m4.texinfo: Port some changes from the branch.
- (Invoking m4): Promote to a chapter, instead of a section of
- Preliminaries.
- (Operation modes, Dynamic loading features, Preprocessor features)
- (Limits control Frozen state, Debugging options)
- (Command line files): Subdivide into new sections.
- (Cleardivert): Rename from cleardiv.
-
-2006-10-14 Eric Blake <ebb9@byu.net>
-
- * tests/others.at (stdin closed): Update to match previous patch.
-
- * m4/input.c (file_clean): Don't close stdin twice, POSIX says it
- is not portable.
- Reported by Ralf Wildenhues.
-
- * modules/m4.c (undivert): Merge from branch.
- * doc/m4.texinfo (Improved fatal_error): Fix typo.
- (Improved exch): New node, copied from branch.
- (Improved cleardivert): Update from branch.
- * THANKS: Update.
-
-2006-10-13 Eric Blake <ebb9@byu.net>
-
- * configure.ac (AC_CONFIG_HEADERS): Name the template config.hin,
- not config-h.in.
- * modules/gnu.c (builtin, indir): Transparently handle builtin
- tokens from defn.
- * doc/m4.texinfo (Indir, Builtin): Remerge from branch.
- * m4/input.c (m4_pop_wrapup): Display debug message when switching
- to wrapped text.
- (m4_input_init): No need to use empty file any more.
- (file_print): Display correct file name.
- * m4/utility.c (m4_error, m4_warn): Ensure we don't try to
- dereference a NULL file name.
- * m4/m4module.h (m4_pop_wrapup): New parameter.
- (m4_symbol_value_groks_macro, m4_symbol_groks_macro): New
- prototypes.
- * m4/m4private.h (m4_symbol_value_groks_macro): Faster version.
- * m4/symtab.c (m4_symbol_value_groks_macro): New method.
- * src/main.c (main): Adjust caller.
- * tests/options.at (--debugmode): Test more output from -dV.
-
-2006-10-12 Eric Blake <ebb9@byu.net>
-
- * m4/input.c (m4_print_token) [DEBUG_INPUT]: Modernize.
-
- * m4/m4private.h (m4__next_token_is_open): New prototype.
- * m4/m4module.h (m4_push_single): Delete; push_string is an
- adequate interface, and removing support for this simplifies the
- input engine.
- (m4_push_wrapup): New parameter.
- (m4_is_syntax): Delete; m4_has_syntax is sufficient.
- (M4_SYNTAX_LQUOTE, M4_SYNTAX_BCOMM, M4_SYNTAX_MASKS): Make
- start-quote and start-comment exclusive from other syntax
- categories.
- * m4/syntax.c: Likewise.
- * m4/input.c (input_funcs): Make polymorphic without requiring
- clients to know whether they are located at isp. All users
- changed.
- (file_names): New variable.
- (m4_input_init): Initialize it.
- (m4_push_file): Use it.
- (m4_input_exit): Free it after use.
- (m4__next_token): Simplify slightly.
- (m4__peek_token): Rename and simplify...
- (m4__next_token_is_open): ... to this. In particular, this
- allows us to avoid a double ungetc, which POSIX doesn't
- guarantee.
- (struct m4_input_block, m4_push_single, single_peek, single_read):
- Remove support for single characters, as the input engine now
- guarantees we don't need it.
- (file_unget, string_unget, m4_input_print, unget_input):
- Strengthen assertions.
- (file_init_funcs, file_read_init): New for file reading.
- (string_init_funcs, string_read_init): New for wrapped text.
- (m4_push_string_init, m4_push_string_finish, m4_push_wrapup):
- Support wrapped text with locations.
- (m4_skip_line): Support dnl across include file boundary.
- (peek_char): Don't pop input when peeking.
- (file_peek): Peek can be called at the end of the file.
- (string_read): Don't read beyond string bounds.
- * m4/macro.c (expand_token, collect_arguments): Update callers.
- (expand_macro): Report errors at location of open parenthesis.
- (expand_token, expand_argument, process_macro): Avoid negative
- array dereferences with m4_has_syntax.
- * m4/utility.c (skip_space): Likewise.
- * modules/m4.c (m4wrap): Update caller.
- * tests/builtins.at (__file__, __line__, dnl): New tests.
- * tests/options.at (--debugmode): Normalize the output.
- * doc/m4.texinfo (Macro Arguments, Dnl, History, Location):
- Remerge recent changes from branch.
- (Improved fatal_error): New node from branch.
-
-2006-10-11 Eric Blake <ebb9@byu.net>
-
- * src/main.c (usage, long_options): Add --debugmode as an alias
- for --debug, to match macro name.
- * tests/options.at (--debugmode): Rename from --debug, and test
- for new alias.
- (--discard-comments): Augment test.
- * doc/m4.texinfo (Invoking m4, Debugmode): Document this.
- * NEWS: Likewise.
-
-2006-10-10 Eric Blake <ebb9@byu.net>
-
- Trace improvements: debugmode(c) was always printing the last two
- lines paired, combine them; and show non-text expansions.
- * m4/macro.c (trace_prepre): Update to show what the macro will
- expand to.
- (trace_pre): No need to special-case on debugmode(c).
- (trace_post): Likewise. Also, show non-text expansions.
- (expand_macro): Update caller. Collecting arguments can change
- debug mode, so cache values beforehand.
- (trace_format): Remove support for unused %l%S%r, and fix support
- for %z to match gcc's attribute((printf)).
- (trace_header): Update caller.
- * m4/input.c (struct m4_input_block): Rename from input_block.
- (struct input_funcs): Add print_func member.
- (file_print, builtin_unget, builtin_print, string_print)
- (m4_input_print): New functions.
- (m4_push_string_finish): Change return type.
- (m4_push_file): Fix missing use of close parameter.
- * m4/debug.c (m4_debug_decode): Don't clear pending traces.
- * m4/m4module.h (m4_input_print): New prototype.
- * tests/builtins.at (debug, esyscmd, multiquotes, syscmd): Update
- to match behavior change.
- * tests/options.at (--debug): Likewise.
- * tests/macros.at (Propagation of traceon)
- (Propagation of --trace): Likewise.
- * tests/others.at (stderr closed, stdout closed, stdin closed):
- Likewise.
- * doc/m4.texinfo (Forloop): Simplify.
- (Trace): Update to changed behavior.
- (Debugmode): Document this change.
- * src/main.c (usage): Likewise.
- * NEWS: Likewise.
-
-2006-10-09 Eric Blake <ebb9@byu.net>
-
- * m4/path.c (m4_include_env_init): Don't alter result of getenv.
- Reported by Ralf Wildenhues.
-
- * modules/gnu.c (gnu_buf): Rename from buf to silence -Wshadow.
-
-2006-10-07 Eric Blake <ebb9@byu.net>
-
- * m4/m4module.h (m4_set_exit_failure): New prototype.
- * m4/utility.c (m4_set_exit_failure): New function.
- * modules/m4.c (m4exit): Use it to avoid yet another global
- variable export in libm4.
-
-2006-10-06 Eric Blake <ebb9@byu.net>
-
- * m4/output.c (cleanup_tmpfile): Exit nonzero on failure to clean
- up.
- * tests/others.at (stdout closed): Fix final check.
-
- Replace uses of tmpfile with clean-temp, since tmpfile is
- incompatible with closeout.
- * tests/builtins.at (esyscmd, syscmd): Don't use pipe; it loses
- exit status of m4.
- * tests/others.at (stderr closed): Likewise.
- * tests/testsuite.at (M4_ONE_MEG_DEFN): Actually hit one meg.
- * ltdl/m4/gnulib-cache.m4: Augment with gnulib-tool --import
- clean-temp.
- * m4/output.c [!HAVE_TMPFILE]: Delete dead code.
- (m4_tmpfile, cleanup_tmpfile): New functions.
- (make_room_for, m4_insert_diversion): Use clean-temp module.
- * configure.ac (AC_CHECK_FUNCS_ONCE): No longer check for
- tmpfile.
- * doc/m4.texinfo (Diversions): Document new use of $TMPDIR.
-
- * m4/utility.c (m4_numeric_arg): Merge from branch.
- * modules/gnu.c (debuglen): New builtin.
- * src/main.c (usage, ARGLENGTH_OPTION, long_options, main):
- Rename --arglength to --debuglen.
- * tests/options.at (--arglength): Rename to --debuglen.
- (deprecated options): Augment test.
- * doc/m4.texinfo (Invoking m4): Document the name change.
- (Debugmode): Rename from Debug Levels.
- (Debugfile): Rename from Debug Output.
- (Debuglen): New node.
- * NEWS: Document these changes.
-
- * modules/m4.c (m4exit): Fix typo. Ensure desired exit status in
- case closing a module exits.
-
- * modules/m4.c (m4exit): Merge from branch.
- * m4/m4.c (m4_delete): Avoid assertion triggered by last patch.
-
-2006-10-05 Eric Blake <ebb9@byu.net>
-
- * ltdl/m4/gnulib-cache.m4: Augment with gnulib-tool --import
- closeout.
- * Makefile.am (m4_libm4_la_DEPENDENCIES): Add missing dependency.
- * src/main.c (main): Close stdout on exit.
- * m4/debug.c (set_debug_file): Check for write failure.
- * m4/m4.c (m4_delete): Don't mask write failure.
- * tests/testsuite.at (AT_CHECK_M4): Allow tracing by expanding
- macros before calling AT_CHECK.
- (M4_ONE_MEG_DEFN): New helper macro.
- * tests/others.at (stdout full): New test.
- (stderr closed, stdin closed, stdout closed): Augment.
- * tests/builtins.at (syscmd): New test.
- (esyscmd): Augment.
-
-2006-10-04 Eric Blake <ebb9@byu.net>
-
- * tests/builtins.at: Alphabetize tests.
- * tests/testsuite.at (AT_CHECK_M4): Allow choosing stdin.
- * tests/generate.awk (new_test): Fix underquoting.
- * tests/others.at (maketemp): Rename from misc.
- (stdin closed, stdout closed, stderr closed): New tests.
-
-2006-10-03 Eric Blake <ebb9@byu.net>
-
- Avoid all global variables in modules, so that --disable-static
- can work on cygwin.
- * examples/incl.m4: New file, from branch.
- * Makefile.am (dist_pkgdata_DATA): Distribute it.
- * doc/m4.texinfo (Location): Merge this section from branch.
- (Include): Update the test.
- * tests/generate.awk (new_test): Allow for VPATH build
- pre-processing of expected __program__ output.
- * m4/m4module.h (m4_current_diversion, m4_output_current_line):
- Avoid global variables.
- (m4_context_field_table): Add current_diversion, output_line.
- (m4_output_init, m4_make_diversion): Add parameter.
- (m4_get_program_name, m4_set_program_name): New accessors.
- * m4/m4private.h (m4_get_current_diversion),
- (m4_set_current_diversion, m4_get_output_line)
- (m4_set_output_line): New accessors.
- * m4/utility.c (m4_get_program_name, m4_set_program_name): New
- methods.
- * modules/m4.c (divnum, divert): Adjust callers.
- * modules/gnu.c (__program__): Likewise.
- * m4/output.c (m4_output_init, m4_make_diversion)
- (m4_freeze_diversions, m4_shipout_text, m4_make_diversion)
- (m4_insert_diversion): Likewise.
- * m4/input.c (file_clean, m4_push_file): Likewise.
- * src/freeze.c (reload_frozen_state): Likewise.
- * src/main.c (main, usage): Likewise.
-
- Partially plug memory leak when unloading gnu module.
- * tests/modules.at (unload gnu module): New test.
- * modules/gnu.c (gnu_LTX_m4_finish_module): New function.
- (m4_regexp_compile): Move static storage to module visibility.
- * tests/options.at (--debug): Adjust to new output.
-
-2006-09-29 Eric Blake <ebb9@byu.net>
-
- Even when not the first option, --help can't have side effects.
- * tests/options.at (--debugfile): Detect bugs in this area.
- * tests/testsuite.at (AT_CHECK_M4): Avoid a process when ignoring
- stderr.
- * src/main.c (main): Fix it by deferring debugfile change. Also,
- defer closing streams until after module tracing is done.
- * modules/gnu.c (debugfile): Make message consistent with command
- line.
- * doc/m4.texinfo (Invoking m4): Touch up the documentation.
- * NEWS: Document this fix.
-
- * modules/m4.c (dnl): Include macro name in warning message.
- * m4/input.c (m4_skip_line): Add parameter.
- * m4/m4module.h (m4_skip_line): Likewise.
- * src/main.c (usage): Update wording.
- * doc/m4.texinfo (Inhibiting Invocation): Add xfailed test until
- issue of blind macros vs. POSIX is resolved.
- (Dnl): Merge another node from branch.
-
- * ltdl/m4/gnulib-cache.m4: Augment with gnulib-tool --import
- xstrtol.
- * m4/system_.h (N_): Define.
- * src/main.c (main): Validate numeric arguments.
- (size_opt): New function, idea borrowed from coreutils.
- * m4/macro.c (expand_macro): -L0 implies no limit.
- * doc/m4.texinfo (Invoking m4): Document this change.
- * NEWS: Likewise.
- * tests/options.at: (--arglength, --nesting-limit)
- (--regexp-syntax): New tests of argument validation.
-
-2006-09-28 Eric Blake <ebb9@byu.net>
-
- * tests/options.at: Alphabetize the tests.
-
-2006-09-27 Eric Blake <ebb9@byu.net>
-
- * m4/m4module.h (m4_symbol_value_print, m4_symbol_print): Add
- another parameter to print module info.
- * m4/macro.c (trace_pre): Adjust caller.
- * modules/m4.c (M4BUILTIN_HANDLER): Likewise.
- * doc/m4.texinfo (Dumpdef, Debug Levels): Document this.
- * NEWS: Document this.
-
- * ltdl/m4/gnulib-cache.m4: Augment with gnulib-tool --import
- strnlen.
- * m4/symtab.c (symbol_value_print): Rename to...
- (m4_symbol_value_print): ...this, and...
- (m4_symbol_print): Update to allow -L length truncation. Now
- truncation also affects dumpdef output and builtin names.
- * m4/m4private.h (nesting_limit, max_debug_argument_length):
- Switch to size_t.
- * m4/m4module.h (m4_symbol_print): Add parameter.
- (m4_symbol_value_print): New function.
- * modules/m4.c (dumpdef): Allow length truncation.
- * m4/macro.c (trace_pre): Use m4_symbol_print, rather than
- repeating code.
- * doc/m4.texinfo (Invoking m4): Document -l better.
- (Dumpdef, Debug Levels): Document the effect of -l.
- * NEWS: Document this change.
-
- * modules/m4.c (m4_dump_symbols, errprint, m4wrap)
- (m4_expand_ranges): Ensure we aren't picking up partial object on
- obstack.
- * modules/stdlib.c (setenv): Allow extra arguments.
- * modules/time.c (ctime): Avoid side effect in call to
- obstack_grow.
- * modules/gnu.c (m4_regexp_substitute): Likewise.
- (renamesyms): Avoid extra obstack_init.
- * src/freeze.c (reload_frozen_state): Remove debug comment.
- (produce_frozen_state): Simplify fprintf to puts where possible.
- * modules/modtest.c (modtest_init, modtest_finish): Likewise.
- * modules/import.c (import, symbol_fail, modules_fail): Likewise.
- * m4/macro.c (trace_flush): Likewise.
- * m4/debug.c (m4_debug_message_prefix): Likewise.
- * m4/path.c (include_dump): Likewise.
- * m4/module.c (module_remove): Likewise.
- (install_builtin_table): Simplify malloc and string
- concatenation.
-
-2006-09-26 Eric Blake <ebb9@byu.net>
-
- * m4/m4module.h (m4_symbol_print): New prototype.
- (M4_DEBUG_TRACE_STACK): New enumerator.
- (m4_is_debug_bit): Allow use without requiring m4private.h.
- * m4/symtab.c (symbol_value_print, m4_symbol_print): New
- functions.
- * modules/m4.c (dump_symbol_CB, m4_dump_symbols): Speed up
- callback.
- (dumpdef): Allow printing pushdef'd stacks.
- * m4/debug.c (m4_debug_decode): Add new 's' debug mode.
- * src/main.c (usage): Document it.
- * doc/m4.texinfo (Dumpdef, Debug Levels): Likewise.
- * NEWS: Likewise.
-
- * configure.ac (AC_CONFIG_HEADERS): Place <config.h> with other
- gnulib headers.
- * Makefile.am (AUTOMAKE_OPTIONS): Add nostdinc, to reduce length
- of lines during make.
- (AM_CPPFLAGS): Remove unneeded include path.
- (src_m4_CPPFLAGS): Remove redundant include path.
- * m4/system_.h Make preprocessor indentation consistent.
- (M4_DIRSEP_CHAR, M4_PATHSEP_CHAR, M4_GNUC_FORMAT): Remove unused
- macros.
- (UNIX, W32_NATIVE, OS2): Update platform recognition macros from
- branch.
- (M4_GNUC_PRINTF, M4_GNUC_SCANF, M4_GNUC_NORETURN)
- (M4_GNUC_CONST, M4_GNUC_UNUSED): Mangle names properly for header.
- (bool, true, false): Don't undefine here; stdbool takes care of
- that.
- * src/m4.h (includes): Assume config.h, and several standard
- headers.
- (__CYGWIN__, WIN32): Don't define here; let system.h do it.
- * m4/m4private.h: Assume config.h.
- * m4/output.c: Likewise.
- * m4/path.c: Likewise.
- * m4/resyntax.c: Likewise.
- * m4/utility.c: Likewise.
- * modules/gnu.c: Likewise.
- * modules/import.c: Likewise.
- * modules/load.c: Likewise.
- * modules/m4.c: Likewise.
- * modules/modtest.c: Likewise.
- * modules/mpeval.c: Likewise.
- * modules/perl.c: Likewise.
- * modules/shadow.c: Likewise.
- * modules/stdlib.c: Likewise.
- * modules/time.c: Likewise.
- * modules/traditional.c: Likewise.
-
-2006-09-21 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Invoking m4): Add clarification on option
- processing behavior.
- * tests/options.at (option grouping): Test this.
- * THANKS: Update.
- Reported by Mikhail Teterin.
-
- * bootstrap: Add --force option, based on idea from coreutils.
- * README: Document that ./bootstrap and autoreconf are for
- developers, and not lightly done in tarballs.
-
-2006-09-20 Eric Blake <ebb9@byu.net>
-
- * src/main.c (usage, OPTSTRING, main): Rename -e to -i. Make
- warnings consistent.
- (long_options, HASHSIZE_OPTION): Warn on -H.
- * doc/m4.texinfo (Invoking m4): Document this.
- * tests/options.at (deprecated options): Update.
-
- Change the default of interactive sessions to match sh.
- * src/main.c (usage): Document this.
- (enum interactive_choice): New enum.
- (main): Use it to defer decision of interactive until after
- argument processing.
- * doc/m4.texinfo (Invoking m4): Document this.
- * NEWS: Likewise, plus add missing mention of -b.
- Reported by Stepan Kasal.
-
-2006-09-19 Eric Blake <ebb9@byu.net>
-
- * src/main.c (usage, main, DEBUGFILE_OPTION): Deprecate -o as
- well as --error-output; the goal is to add -o/--output in some
- future version with semantics like gcc or autom4te.
- * doc/m4.texinfo (Invoking m4, Dumpdef, Debug Output, Errprint):
- (Extensions): Reflect this update.
- (Renamesyms): Add another test.
- (Defn): Xfail for now, so that `make check' is happy.
- * NEWS: Document this change.
- * tests/generate.awk: Mark dynamic loading tests as such. Allow
- xfailing tests.
- * tests/macros.at (Renamesyms collisions): New test, exposing
- renamesyms' coredump.
- * tests/options.at (--debugfile, --safer): Update to match
- change.
-
- * m4/debug.c (set_debug_file): Fix regression in -o when stdout
- and stderr are same file, introduced 2003-07-23.
- * tests/options.at (--debugfile): New test, to catch the bug.
- (deprecated options): Test --error-output.
- * src/main.c (usage, main, long_options, ERROR_OUTPUT_OPTION):
- Deprecate --error-output, and replace it with --debugfile.
- * doc/m4.texinfo (Invoking m4, Debug Output, Dumpdef, Errprint):
- Document this change.
- * NEWS: Likewise.
-
-2006-09-18 Eric Blake <ebb9@byu.net>
-
- * modules/load.c (modules): Rename to...
- (m4modules): ...this, since it is an English word with 0
- arguments.
- * modules/gnu.c (symbols, m4symbols): Likewise.
- * doc/m4.texinfo (Listing Modules): Rename to...
- (M4modules): ...this.
- (Symbols): Rename to...
- (M4symbols): ...this.
- (Load, Foreach, Trace, Answers): Update to new spellings.
- * NEWS: Document this.
-
- * modules/m4.c (traceon, traceoff): Change to Solaris semantics,
- such that without arguments, the global trace flag is changed
- rather than walking the table of all currently-defined macros.
- (set_trace_CB): No longer needed.
- * m4/m4module.h (m4_set_symbol_name_traced): Add a parameter.
- (m4_set_symbol_traced): Delete.
- (m4_symtab_create): Nuke the nuke parameter.
- * m4/m4private.h (m4_get_symbol_value): Delete.
- * m4/symtab.c (m4_symbol_popdef): No more need for nuke_trace.
- (m4_set_symbol_name_traced): Free undefined entries that are no
- longer traced.
- (symbol_destroy_CB): Update caller.
- * m4/m4.c (m4_create): Update caller.
- * src/main.c (main): Likewise.
- (usage): Fix typo in last commit.
- * doc/m4.texinfo: Minor cleanups throughout.
- (Debugging, Dumpdef, Trace, Debug Levels, Debug Output): Merge
- more nodes from branch.
- (Trace): Document new semantics, and how to simulate the old.
- * tests/builtins.at (multiquotes): Adjust to new semantics.
- * NEWS: Update somewhat.
-
-2006-09-14 Eric Blake <ebb9@byu.net>
-
- Add --safer option, per debian bug 5898.
- * src/main.c (usage): Document new option.
- (SAFER_OPTION): New enumerator.
- (main): Set the option bit.
- * m4/m4module.h (m4_context_opt_bit_table): Declare new bit
- accessors.
- * m4/m4private.h (M4_OPT_SAFER_BIT): New macro.
- (m4_get_safer_opt): New accessor.
- * modules/gnu.c (esyscmd, debugfile): Disable when --safer.
- * modules/m4.c (syscmd, maketemp): Likewise.
- * doc/m4.texinfo (Invoking m4, Debug Output, Syscmd, Esyscmd)
- (Sysval, Maketemp): Add tests of this.
- * tests/options.at (--safer): Likewise.
-
-2006-09-13 Eric Blake <ebb9@byu.net>
-
- * tests/modules.at (AT_CHECK_M4_MODTEST): Use AT_CHECK_M4, for
- stderr filtering.
- Reported by Ralf Wildenhues.
-
- Fix installcheck.
- * Makefile.am (check_LTLIBRARIES): Build test libraries in the
- tests directory, so we can be sure an installed build is not
- picking up uninstalled non-test libraries.
- (check-local, installcheck-local): Depend on test libraries.
- * tests/modules.at (AT_CHECK_M4_MODTEST): Don't use options
- after file name. Fix quoting. Remove skipping the test, now
- that makefile guarantees test modules will exist.
- (Freezing modules, modules: shadow, modules: unload)
- (modules: trace): Always put test modules in module path.
- (modules: importing): Likewise, and rely on AT_CHECK_M4 for
- stderr munging.
- * src/main.c (usage): Document default module search path.
- (import_environment, frozen_file_to_read, frozen_file_to_write):
- Move...
- (main): ...here.
- * tests/testsuite.at (AT_CHECK_M4): Filter stderr here...
- * tests/m4.in: ...not here.
- Reported by Ralf Wildenhues.
-
-2006-09-08 Eric Blake <ebb9@byu.net>
-
- * bootstrap: Kill unrelated copy-n-paste code from argument
- parsing. Let Makefile generate testsuite.
- * Makefile.am (EXTRA_DIST): Remove examples/WWW/man/Makefile.
-
-2006-09-07 Eric Blake <ebb9@byu.net>
-
- * m4/m4module.h (m4_peek_input): No longer export.
- (m4_error_at_line, m4_warn_at_line): New prototypes.
- (m4_is_symbol_void): New macro.
- (m4_push_file): Update prototype.
- * m4/m4private.h (m4__peek_token): New prototype.
- (M4_TOKEN_OPEN, M4_TOKEN_COMMA, M4_TOKEN_CLOSE): New enumerators.
- * m4/utility.c (m4_error_at_line, m4_warn_at_line): New functions.
- * src/main.c (main): Allow reading from stdin twice.
- * modules/m4.c (include): Adjust to new prototype.
- * m4/input.c: General comment cleanup.
- (file_peek, file_read, file_unget, push_file): Set end flag on
- EOF, so that we don't call getc twice.
- (push_file, file_clean): Port fix from branch to avoid closing
- stdin prematurely.
- (pop_input): Port fix from branch to avoid reading free'd memory
- when input ends mid-string.
- (m4_pop_wrapup): Port fix from branch to allow multiple m4wraps.
- (string_peek, string_read): Always use unsigned char.
- (m4_skip_line): Warn when dnl cut short by EOF.
- (peek_input): Rename from m4_peek_input.
- (match_input): Update signature, to distinguish between `(' token
- and multi-char quote or comment beginning with `('.
- (m4_input_exit): Cleanup now done in m4_pop_wrapup.
- (m4__peek_token): New function, ported from branch.
- (m4__next_token): Update to new token types.
- * m4/macro.c (expand_token, expand_argument): Use peek_token.
- * doc/m4.texinfo (Pseudo Arguments, Defn, Answers): Fix typos.
- (Invoking m4): Remerge from branch.
-
- * Makefile.am ($(TESTSUITE)): Revert patch from 2006-09-05...
- (check-local): and put dependency here.
- Reported by Ralf Wildenhues.
-
-2006-09-05 Eric Blake <ebb9@byu.net>
-
- * m4/m4module.h (m4_debug_message): New prototype.
- (M4_DEBUG_TRACE_MODULE): New debug bit.
- * m4/m4private.h (M4_DEBUG_MESSAGE, M4_DEBUG_MESSAGE1)
- (M4_DEBUG_MESSAGE2): Delete these macros.
- * m4/debug.c (m4_debug_message): New method.
- (m4_debug_decode): Add module tracing as flag `m'.
- * m4/input.c (m4_push_file, file_clean): Use new method.
- * m4/path.c (m4_path_search): Likewise.
- * po/Makevars (XGETTEXT_OPTIONS): Likewise.
- * m4/module.c (install_builtin_table, install_macro_table)
- (m4__module_open, module_close, module_remove): Promote several
- module debug messages outside of DEBUG_MODULES.
- (m4__module_init, module_remove) [DEBUG_MODULES]: Don't mix
- DEBUG_MODULES with normal trace output.
- * src/main.c (usage): Document new flag.
- * doc/m4.texinfo (Debug Levels): Likewise.
- * Makefile.am ($(TESTSUITE)): Add missing dependency.
- * tests/m4.in: Neutralize platform-dependent module filenames.
- * tests/options.at (--debug): Update expected output.
-
-2006-09-05 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * doc/m4.texinfo: Fix some typos.
- * tests/others.at: Likewise.
-
-2006-09-05 Eric Blake <ebb9@byu.net>
-
- * m4/input.c (lex_debug): Remove dead code that broke compilation
- with --enable-debug.
- * m4/module.c (install_builtin_table, install_macro_table)
- (m4__module_init, m4__module_open, module_close)
- (module_remove): Fix compilation when --enable-debug.
- * m4/output.c (m4_shipout_text): Likewise.
- * ltdl/m4/debug.m4 (M4_CHECK_DEBUGGING): Preload all static
- libraries when --enable-debug.
- * configure.ac (DYNAMIC_MODULES): New variable, to pass
- information to testsuite.
- (modules to preload): Determine modules after we know whether
- shared libraries are supported.
- * tests/atlocal.in (DYNAMIC_MODULES): Substitute this into
- testsuite.
- * tests/testsuite.at (AT_CHECK_DYNAMIC_MODULE): New macro.
- * tests/modules.at (Freezing modules, AT_CHECK_M4_MODTEST)
- (modules: shadow, modules: unload, modules: importing)
- (modules: trace): Use new macro.
- * tests/builtins.at (gmp): Likewise.
-
- * m4/macro.c (expansion_level, macro_call_id): Change to size_t.
- All users updated.
- (expand_token): Avoid assertion just added to docs.
- (expand_macro): Track pending expansions, for when a symbol's
- definition changes during argument collection.
- (m4_macro_call, process_macro): Operate on symbol value, not
- symbol, since symbol may have changed during argument collection.
- * m4/m4private.h (m4_symbol_value): Add pending_expansions member.
- (VALUE_PENDING, SYMBOL_PENDING, VALUE_DELETED_BIT): New defines.
- (m4_get_symbol_value): Add fast macro version.
- * m4/m4module.h (M4_BUILTIN_FLAGS_MASK): New enumerator.
- (m4_macro_call): Adjust prototype.
- * m4/module.c (install_builtin_table): Check that flags are valid
- when creating builtin.
- * m4/symtab.c (m4__symtab_remove_module_references): Use
- m4_symbol_value_delete, rather than inlining it.
- (m4_symbol_value_copy): Copy placeholder text.
- (symbol_popval): Use m4_symbol_value_delete.
- (m4_symbol_value_delete): Implementation was missing when NDEBUG.
- Handle pending expansions.
- * modules/gnu.c (indir): Update to new prototype.
- * doc/m4.texinfo: Fix menus to be consistent with section names.
- (Defn): Add test that macro tokens flatten to empty string;
- triggered an assert before this patch.
- (Ifelse): Merge another node.
- (Loops): Split into...
- (Forloop, Foreach): New nodes; work is still underway on them.
- (Answers): Add more info on foreach macro; work is still underway.
- (Indir): Add test that indir collects arguments before looking up
- macro.
- * TODO: Update based on this patch.
-
-2006-09-01 Eric Blake <ebb9@byu.net>
-
- * m4/m4.c (m4_create): Fix latent bug since 2003-10-08.
- * m4/hash.h (m4_free_hash_iterator): New prototype.
- * m4/hash.c (struct m4_hash) [!NDEBUG]: Add iter member, to
- ensure we don't do unsafe things while iterating.
- (HASH_ITER, ITER_CHAIN): New accessor macros.
- (m4_hash_new, m4_hash_resize, maybe_grow): Fix malloc typing bug.
- (m4_hash_delete, m4_hash_insert): Unsafe while iterating.
- (m4_hash_remove) [!NDEBUG]: Enforce safety while iterating.
- (m4_get_hash_iterator_next) [!NDEBUG]: Track current iterators,
- to catch unsafe actions.
- (m4_free_hash_iterator): New function, to avoid memory leaks, and
- when debugging, to track safe actions.
- (m4_hash_apply): Avoid memory leak.
- * m4/symtab.c (m4_symtab_apply): Likewise.
- * ltdl/m4/gnulib-cache.m4: Remove getopt from here; it is pulled
- in manually to src/ for now.
- * tests/builtins.at (gmp): Add keyword module.
- * tests/modules.at (Freezing modules, modules: shadow)
- (modules: unload, modules: importing, modules: trace): Likewise.
-
-2006-08-30 Eric Blake <ebb9@byu.net>
-
- * m4/utility.c (m4_warn): Factor "Warning" out of messages into
- here.
- (m4_bad_argc, m4_numeric_arg): Update all callers.
- * m4/macro.c (m4_macro_call): Likewise.
- * doc/m4.texinfo (Defn, Pushdef): Fix typos in last commit.
- (Indir, Builtin, Ifdef): More doc merges.
- (Loops): Mention that documenting foreach would be nice.
- (Macro Arguments, Defn, Builtin, Ifdef, Ifelse, Changesyntax)
- (Include, Eval, Location, M4exit): s/input.m4/stdin/.
- * modules/gnu.c (indir, builtin): Warn, not error, on undefined.
- (substitute, syncoutput): Update all m4_warn callers.
- * modules/m4.c (undefine, popdef, m4_dump_symbols, defn)
- (traceon, traceoff): Make warning message consistent.
- (define, pushdef): Update all m4_warn callers.
- * tests/generate.awk: Choose file name so that documentation can
- show command-line behavior.
- * tests/builtins.at (define): Update to new wording.
- * tests/macros.at (pushdef/popdef): Likewise.
- * tests/freeze.at (loading format 1): Likewise.
- * tests/modules.at (AT_CHECK_M4_MODTEST): Likewise.
-
- * doc/m4.texinfo (Undefine, Defn, Pushdef): More doc merges from
- the branch.
- (Defn): Add failing test case for mixing text and builtin.
- (Renamesyms): Improve wording, and identify core dump that needs
- fixing.
-
-2006-08-29 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Quoting Arguments, Definitions, Define)
- (Arguments, Pseudo Arguments): More doc merges from the branch.
- (Macro expansion): Turn example into test.
- (Pseudo Arguments): Add example of avoiding argument.
- * modules/m4.c (undefine, popdef): Accept multiple arguments.
- (define, pushdef): Warn on non-text macro name.
- (ifelse, m4_dump_symbols, defn, traceon, traceoff): Tweak
- warning/error messages.
- (ifdef): Ignore extra arguments.
- * m4/symtab.c (m4_symbol_value_copy): Avoid memory leak.
- (m4__symtab_remove_module_references): Check that there is no leak.
- * tests/macros.at (pushdef/popdef): Update to new message.
- * tests/builtins.at (define): Likewise.
- * tests/freeze.at (loading format 1): Likewise.
- * tests/modules.at (AT_CHECK_M4_MODTEST): Likewise.
-
- * m4/m4private.h (m4_get_syntax_lquote, m4_get_syntax_rquote)
- (m4_get_syntax_bcomm, m4_get_syntax_ecomm) [NDEBUG]: Use same type
- as accessor function, to avoid compiler warning.
- * m4/module.c (m4__module_open): Move declaration of variable to
- avoid compiler warning.
- * src/main.c (main): Avoid shadowing a global variable.
- * src/freeze.c (produce_symbol_dump): Avoid unused variable
- warning when NDEBUG.
- * tests/options.at (--discard-comments, --import-environment)
- (--debug, --prepend-include, --help and --version): Rename tests
- to name option tested.
-
-2006-08-28 Eric Blake <ebb9@byu.net>
-
- * m4/utility.c (m4_bad_argc): Move assertion out of hot path...
- * m4/module.c (install_builtin_table): ...to here, and add
- assertion that blind macros require arguments.
- * m4/m4module.h (struct m4_builtin): Document restrictions that
- must be met during module loading.
- * modules/gnu.c (changeresyntax, changesyntax): These are blind,
- so require an argument to avoid triggering assertion.
- (debugfile): Tweak error message.
-
-2006-08-25 Eric Blake <ebb9@byu.net>
-
- * m4/m4module.h (M4_BUILTIN_GROKS_MACRO, M4_BUILTIN_BLIND)
- (M4_BUILTIN_SIDE_EFFECT): New enumerators.
- (struct m4_builtin): New member flags replaces groks_macro_args,
- blind_if_no_args. min_args and max_args are now 0-based.
- Rearrange members to reduce size on platforms where function
- pointers are 64 bits but regular pointers are 32.
- (m4_bad_argc): Add argument.
- * m4/m4private.h (VALUE_SIDE_EFFECT_ARGS_BIT): New define.
- * m4/utility.c (m4_bad_argc): Simplify calculation, and take side
- effect into account.
- * m4/module.c (install_builtin_table): Adjust all users affected
- by this API change.
- * m4/macro.c (m4_macro_call): Likewise.
- * src/freeze.c (reload_frozen_state): Likewise.
- * modules/m4.c (builtin_functions, ifelse, syscmd): Likewise.
- * modules/gnu.c (builtin_functions, builtin, esyscmd): Likewise.
- * modules/import.c (builtin_functions): Likewise.
- * modules/load.c (builtin_functions): Likewise.
- * modules/modtest.c (builtin_functions): Likewise.
- * modules/mpeval.c (builtin_functions): Likewise.
- * modules/perl.c (builtin_functions): Likewise.
- * modules/shadow.c (builtin_functions): Likewise.
- * modules/stdlib.c (builtin_functions): Likewise.
- * modules/time.c (builtin_functions, mktime_functions)
- (strftime_functions): Likewise.
- * doc/m4.texinfo (Loops): Update test now that shift is blind.
- (Macro Arguments): Fix typo in test.
- (Patsubst): Fix typo in test.
- * modules/gnu.c (m4_regexp_substitute): Don't skip empty match at
- end of string. Fix return value when ignore_duplicates.
- * tests/builtins.at (patsubst): Fix typo in test.
-
- * tests/options.at (debug-flags): Update to reflect new message.
- (deprecated options, prepend-include, help and version): New
- tests.
- * tests/testsuite.at (AT_CHECK_M4): Avoid hanging testsuite if
- test omits an input file name.
- * src/main.c (long_options, main): Add -B/--prepend-include.
- (usage): Document it.
- (main): `m4 --help --version' now displays help, not version.
- * ltdl/m4/gnulib-cache.m4: Augment with gnulib-tool --import
- dirname filenamecat.
- * m4/m4module.h (m4_add_include_directory): Add parameter.
- * m4/m4private.h (m4__include_init): New prototype.
- * m4/m4.c (m4_create): Put `.' on path before options are
- collected.
- * m4/path.c (includes): Assume C89. Use gnulib for file name
- management.
- (m4__include_init): New function.
- (search_path_add): Allow prepending.
- (m4_add_include_directory, search_path_env_init): Adjust callers.
- (m4_path_search): Relative names now invoke path search, since
- `.' might not be first.
- * doc/m4.texinfo (Invoking m4, Search Path): Document new option.
-
-2006-08-25 Bruno Haible <bruno@clisp.org> (tiny change)
- and Eric Blake <ebb9@byu.net>
-
- * bootstrap: Run autopoint before gnulib-tool, since autopoint
- 0.15 installs macros obsoleted by current gnulib.
-
-2006-08-25 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Macro Arguments): Another section merged;
- testsuite failures now exposed.
-
-2006-08-23 Eric Blake <ebb9@byu.net>
-
- * doc/m4.texinfo (Quoted strings, Other tokens, Comments)
- (Input processing): More doc merges from the branch.
- (Regular expression syntax): Add introductory text.
- (Inhibiting Invocation): More doc merges from the branch.
- (Other tokens): Reorder after comments.
- * tests/generate.awk: Allow passing options to doc examples.
-
-2006-08-22 Eric Blake <ebb9@byu.net>
-
- * tests/options.at (debug-flags): New test.
- * m4/m4module.h (M4_DEBUG_TRACE_VERBOSE): Make sure this value is
- not negative, to distinguish failure in m4_debug_decode.
- (m4_debug_decode): Add new parameter.
- * modules/gnu.c (regexp): Slight cleanup.
- (renamesyms): Ignore excess arguments.
- (syncoutput): Make case-insensitive, warn on bad argument.
- (debugmode): Factor -+ handling out to...
- * m4/debug.c (m4_debug_decode): ...here.
- (m4_debug_message_prefix): Fix spacing.
- * src/main.c (main): Let -d option adjust flags.
- * m4/input.c (file_clean): Avoid printing empty file name.
- * doc/m4.texinfo (Syncoutput): Document new range of input.
- (Invoking m4): Document use of multiple -d flags.
-
- Start porting various fixes from the branch that use gnulib.
- * ltdl/m4/gnulib-cache.m4: Augment with gnulib-tool --import
- binary-io cloexec close-stream fopen-safer getopt gnupload mkstemp
- regexprops-generic stdlib-safer unlocked-io.
- * m4/debug.c (m4_debug_set_output): Close debug file on exec.
- * m4/path.c (m4_path_search): Close input file on exec, reject
- empty file name, fix parameter naming.
- * m4/output.c (make_room_for): Close diversion file on exec.
- (includes): Assume C89 headers.
- (tmpfile): For now, we don't want tmpfile-safer, because we want
- clean-temp later.
- * m4/m4private.h (includes): Use various gnulib headers.
- * doc/regexprops-generic.texi: Use gnulib's copy.
-
- * configure.ac (AM_INIT_AUTOMAKE): Bump automake requirement.
- * AUTHORS: Add copyright.
- * ChangeLog: Likewise.
- * README: Likewise. Require automake 1.9b or later.
- * HACKING: New file.
- * README-alpha: Add copyright.
- * THANKS: Likewise. Update.
- * doc/STYLE: Add copyright, and tweak for changed directories.
- * modules/README: Add copyright, and tweak for libtool version.
- * examples/COPYING: New file.
- * examples/WWW/COPYING: Likewise.
- * examples/WWW/m4lib/COPYING: Likewise.
- * modules/shadow.m4: Add copyright.
- * modules/perl.m4: Likewise.
- * modules/modtest.m4: Likewise.
- * modules/stdlib.m4: Likewise.
- * modules/time.m4: Likewise.
- * modules/time2.m4: Likewise.
- * po/Makevars: Likewise.
- * tests/iso8859.m4: Likewise.
- * tests/m4.in: Likewise.
- * NEWS: Add (C) to copyright.
- * TODO: Likewise.
- * m4/system_.h: Likewise.
- * tests/atlocal.in: Likewise.
- * tests/builtins.at: Likewise.
- * tests/freeze.at: Likewise.
- * tests/generate.awk: Likewise.
- * tests/macros.at: Likewise.
- * tests/modules.at: Likewise.
- * tests/options.at: Likewise.
- * tests/others.at: Likewise.
- * tests/testsuite.at: Likewise.
- * m4/utility.c: Spell out copyright years.
- * src/main.c: Likewise.
-
- * doc/m4.texinfo (Bugs, Manual, Syntax): Sync from branch.
-
-2006-08-21 Eric Blake <ebb9@byu.net>
-
- * configure.ac (AC_CHECK_HEADERS_ONCE): Check for <sys/wait.h>.
- * modules/gnu.c (esyscmd): Use -1 for failure. Set sysval to 0
- when no arguments are given, but without losing warning about 0
- arguments.
- * modules/m4.c (syscmd): Likewise.
- (includes): Assume C89.
- (m4_sysval): Make static.
- (M4_SYSVAL_EXITBITS, M4_SYSVAL_TERMSIGBITS): New macros.
- (sysval): Port calculation from branch.
-
-2006-08-20 Eric Blake <ebb9@byu.net>
-
- * m4/macro.c (expand_macro): Move argument check...
- (m4_macro_call): ...to here, so indir will warn.
- * modules/gnu.c (__program__): New macro, ported from branch.
- (builtin): Perform argument check.
- (changesyntax): Avoid out-of-bounds read.
-
- * modules/gnu.c (includes): Assume stdlib.h, errno.
- (m4_regexp_compile): Add no_sub parameter, avoid memory leaks.
- (substitute): Add caller parameter, avoid out-of-bounds memory
- references.
- (m4_regexp_substitute, patsubst, regexp, renamesyms): Adjust
- callers.
-
-2006-08-16 Eric Blake <ebb9@byu.net>
-
- * po/POTFILES.in: Add more files that contain translatable
- strings.
- * po/Makevars (XGETTEXT_OPTIONS): Add options to pass more
- information to translators.
- (USE_MSGCTXT): New var for gettext 0.15.
- * m4/input.c (file_clean, m4_push_file, m4__next_token): Start
- debug/trace messages in lower case.
- * m4/macro.c (expand_argument): Likewise.
- * m4/path.c (m4_path_search): Likewise.
- * src/main.c (main): Likewise.
-
-2006-08-14 Eric Blake <ebb9@byu.net>
-
- * src/main.c (usage): Document --import-environment.
- * doc/m4.texinfo (History, Invoking m4): Synchronize from branch.
-
-2006-08-11 Eric Blake <ebb9@byu.net>
-
- * bootstrap (func_get_translations): Only remove files when doing
- full update.
- (func_update_po): Avoid CDPATH problems.
-
-2006-08-10 Eric Blake <ebb9@byu.net>
-
- * bootstrap (func_get_translations): New function.
- (func_update_po): Borrow ideas from tar to correctly pull in
- translations from newer location.
-
-2006-08-09 Eric Blake <ebb9@byu.net>
-
- * bootstrap: Recent gnulib no longer has jm_* macros to worry
- about.
- * ltdl/m4/gnulib-cache.m4: Augment with gnulib-tool --import
- verror.
- * m4/m4module.h (M4ERROR, M4WARN): Delete, replaced by...
- (m4_error, m4_warn): ... these new prototypes.
- (m4_current_file, m4_current_line): Move into context, rather
- than leaving as globals.
- (m4_insert_file, m4_insert_diversion, m4_freeze_diversions)
- (m4_undivert_all, m4_input_init): Now takes context.
- * m4/utility.c (m4_error, m4_warn): New functions.
- * m4/m4private.h: Assume errno exists.
- (struct m4): Move warning_status to a bit flag,
- and add exit_status. Adjust accessors accordingly.
- * src/main.c (print_program_name_CB): No longer needed.
- (main): Use new m4_get_fatal_warnings_opt.
- * m4/debug.c: Adjust all callers of M4WARN and M4ERROR, and abort
- instead of issuing "INTERNAL ERROR". Pass context when needed,
- and use new accessors.
- * m4/input.c: Likewise.
- * m4/macro.c: Likewise.
- * m4/output.c: Likewise.
- * m4/utility.c: Likewise.
- * modules/evalparse.c: Likewise.
- * modules/gnu.c: Likewise.
- * modules/load.c: Likewise.
- * modules/m4.c: Likewise.
- * modules/mpeval.c: Likewise.
- * src/freeze.c: Likewise.
- * src/main.c: Likewise.
- * tests/macros.at: Adjust to new message format.
- * tests/builtins.at: Likewise.
- * tests/freeze.at: Likewise.
- * tests/modules.at: Likewise.
- * doc/m4.texinfo: Likewise.
-
- * configure.ac (AM_GNU_GETTEXT, AM_GNU_GETTEXT_VERSION): Require
- newer gettext 0.15.
-
-2006-08-03 Eric Blake <ebb9@byu.net>
-
- * src/stackovf.c (setup_stackovf_trap): Port patch from branch to
- gracefully handle ENOSYS.
- * TODO: Update.
- * THANKS: Update.
-
-2006-07-28 Eric Blake <ebb9@byu.net>
-
- * src/freeze.c (reload_frozen_state): Copy string when creating
- placeholder, to avoid memory corruption.
- * m4/symtab.c (symbol_popval): Avoid memory leak.
- (m4_symbol_rename): Avoid shadowing rename function.
- (dump_symbol_CB, symtab_dump) [DEBUG_SYM]: Fix compilation.
- * tests/freeze.at (reloading unknown builtin): Add test.
- * tests/generate.awk: Capture m4.texinfo line number in
- testsuite.log, not just generated.at.
-
- Port idea from branch that a frozen file can request an unknown
- builtin without producing a warning unless the builtin is
- actually used.
- * m4/m4private.h (m4__symbol_type): Add M4_SYMBOL_PLACEHOLDER.
- (m4_is_symbol_value_placeholder, m4_get_symbol_value_placeholder)
- (m4_set_symbol_value_placeholder): New accessors.
- * m4/m4module.h (m4_is_symbol_placeholder),
- (m4_get_symbol_value_placeholder),
- (m4_set_symbol_value_placeholder),
- (m4_get_symbol_placeholder): Likewise.
- * m4/symtab.c (m4_is_symbol_value_placeholder),
- (m4_get_symbol_value_placeholder),
- (m4_set_symbol_value_placeholder): Likewise.
- (dump_symbol_CB): Handle new symbol type.
- * m4/macro.c (trace_pre): Likewise.
- (m4_macro_call): Warn when invoking a placeholder.
- * modules/m4.c (dumpdef): Handle dumping a placeholder.
- (defn): Warn when referencing a placeholder.
- * src/freeze.c (dump_symbol_CB): Ignore placeholder when
- freezing.
- (reload_frozen_state): When reloading unknown builtin, install a
- placeholder instead of warning.
- * tests/freeze.at (loading format 1): Allow warning when
- popdef'ing undefined function.
-
-2006-07-27 Paul Eggert <eggert@cs.ucla.edu> (tiny change)
-
- * m4/hash.c (m4_hash_string_hash): Don't case-fold in the hash
- function. Shift by 7, not 3, for consistency with
- gnulib/lib/hash.c. Don't assume hash word is 32 bits.
-
-2006-07-27 Eric Blake <ebb9@byu.net>
-
- * src/main.c (usage): Update to match branch.
- (main): Update --version info to distinguish between program name
- `m4' and package name `GNU M4'.
- (AUTHORS): Translate René Seindal's name.
- * configure.ac (TIMESTAMP): Remove now-redundant parentheses.
- * Makefile.am (doc/m4.1): Update to match branch.
- * m4/m4.c (DEFAULT_NESTING_LIMIT): Raise to 1024, to match
- branch.
-
- * m4/system_.h (EXIT_MISMATCH): Define.
- * src/main.c (main): Don't clear syntax table for version 1.
- (usage): Document exit status.
- * src/freeze.c (reload_frozen_state): Port GET_DIRECTIVE from the
- branch, and require V directive to appear first in file. Fix
- broken logic for detecting F and T in version 1 files.
-
-2006-07-22 Eric Blake <ebb9@byu.net>
-
- * src/main.c (stackovf_handler): Document the problems in our
- overflow handler.
- * src/stackovf.c: Forward port changes in branch to use POSIX
- sa_sigaction when available.
- (process_sigsegv): Avoid buffer overrun when error string is
- translated, although the fact that we translate in a signal
- handler is still a bug.
- * ltdl/m4/stackovf.m4 (M4_SYS_STACKOVF): Forward port changes
- from branch to modernize checks.
-
- * modules/format.c (format): Avoid compiler warning that str may
- be used uninitialized.
-
- * m4/m4private.h (DEBUG_MODULES, DEBUG_STKOVF) [DEBUG]: Fix
- spelling.
- (DEBUG_SYNTAX) [DEBUG]: Turn on more debug.
- (DEBUG_MACRO): Remove unused macro.
- * src/stackovf.c: Avoid compiler warnings.
- * m4/input.c: Likewise.
- * m4/module.c: Likewise.
- * m4/output.c: Likewise.
- * m4/path.c: Likewise.
- * m4/symtab.c: Likewise.
- * m4/syntax.c: Likewise.
-
-2006-07-20 Eric Blake <ebb9@byu.net>
-
- * ltdl/m4/gnulib-cache.m4: gnulib-tool has changed again.
- Regenerate to explicitly ask for --assume-autoconf=2.60.
-
-2006-07-19 Eric Blake <ebb9@byu.net>
-
- * po/ChangeLog: Merge into main ChangeLog, then delete file.
- * THANKS: Update.
-
- * doc/m4.texinfo (copying): Relax restriction on front-cover and
- back-cover texts.
-
-2006-07-17 Eric Blake <ebb9@byu.net>
-
- * configure.ac (AM_GNU_GETTEXT_VERSION): Bump requirement to
- 0.14.5.
-
- * ltdl/m4/gnulib-cache.m4: Augment with `gnulib-tool --import
- xvasprintf'.
- * modules/format.c (includes): Use xvasprintf.h.
- (format): Make static. Avoid buffer overflow, that can lead to
- arbitrary code execution exploit. Only pass unsigned char to
- is*(). Support F, g, and G specifiers.
- * doc/m4.texinfo (Format): Expose buffer overrun bug. Document
- new specifiers.
-
-2006-07-17 Gary V. Vaughan <gary@gnu.org>
-
- Ensure M4 compiles correctly with -DDEBUG, and use a single
- consistent definition of various /DEBUG_[A-Z]+/ symbols:
-
- * m4/input.c: Have commented out out DEBUG_INPUT only by default.
- (m4_print_token): Use m4_get_symbol_value_text and
- m4_get_symbol_value_func calls instead of obsolescent VALUE_TEXT
- and VALUE_FUNC respectively.
- (m4__next_token): Use m4_print_token call instead of obsolescent
- print_token symbol.
- * m4/module.c: Have commented out out DEBUG_MODULE only by default.
- * m4/output.c: Similarly for DEBUG_OUTPUT.
- * m4/path.c: Similarly for DEBUG_INCL.
- * m4/symtax.c: Similarly for DEBUG_SYM.
- * m4/syntax.c: Similarly for DEBUG_SYNTAX.
- * src/stackovf.c: Similarly for DEBUG_STACKOVF.
- * m4/m4private.h (DEBUG): Add DEBUG_OUTPUT and DEBUG_STACKOVF to
- preprocessor macros defined with -DDEBUG compiles.
-
-2006-07-17 Gary V. Vaughan <gary@gnu.org> (tiny change)
-
- * bootstrap: Correct typo in --download-po argument parsing.
-
-2006-07-15 Eric Blake <ebb9@byu.net>
-
- * ltdl/m4/gnulib-cache.m4: Augment with `gnulib-tool --import
- gendocs fdl'.
- * tests/generate.awk (normalize): Recognize @tabchar.
- * doc/m4.texinfo (Top): Start merging from branch. Remove tabs.
- Fix menus. Upgrade FDL license from 1.1 to 1.2. Fix overfull
- hboxes.
- (Index macro, Shell commands, Incompatiblities): Rename nodes
- from Index, UNIX commands, Other incompat.
- (Platform macros, Using frozen files, Frozen file format 1)
- (Frozen file format 2, Copying This Manual, Indices): New nodes.
- * Makefile.am (EXTRA_DIST): Distribute gendocs.
- (MAINTAINERCLEANFILES): Clean up files from gnulib.
- (doc_m4_TEXINFOS): Depend on fdl.texi.
- (web-manual): New maintainer target.
-
-2006-07-14 Gary V. Vaughan <gary@gnu.org>
-
- * doc/m4.texinfo (Modules): RMS asked me for an explanation of
- the modular architecture of M4. The result is paraphrased here
- for the benefit of future readers of the manual.
-
-2006-07-14 Gary V. Vaughan <gary@gnu.org> (tiny change)
-
- * Makefile.am (TESTSUITE_AT): Add missing tests/freeze.at.
-
-2006-07-14 Eric Blake <ebb9@byu.net>
-
- * src/main.c (main): Avoid compiler warning.
- * modules/gnu.c (renamesyms): Remove unused variable.
-
-2006-07-14 Gary V. Vaughan <gary@gnu.org>
-
- * m4/m4module.h (m4_regexp_syntax_decode, m4_regexp_syntax_encode)
- (m4_get_regexp_syntax_opt, m4_set_regexp_syntax_opt): Declare
- new functions for managing regexp syntax options.
- * m4/m4private.h (m4): Add regexp_syntax field.
- * m4/resyntax.c: New file implements the above.
- * Makefile.am (m4_libm4_la_SOURCES): Add m4/resyntax.c.
- * modules/gnu.c (RE_SYNTAX_BRE, RE_SYNTAX_ERE, builtin_eregexp)
- (builtin_epatsubst, builtin_erenamsyms, m4_regexp_do)
- (m4_patsubst_do, m4_renamesyms_do): Removed.
- (builtin_changeresyntax): New builtin to change regular expression
- syntax.
- (m4_resyntax_encode_safe): Factor out diagnostics code.
- * src/freeze.c (produce_resyntax_dump): New function to dump
- default regexp syntax specifier to frozen file.
- (reload_frozen_state): Updated to action 'R' directive.
- * src/main.c (usage): Describe new -r option.
- (long_options, OPTSTRING): Declare it.
- (main): Encode and store cli regexp syntax option argument.
- * tests/freeze.at (regexp syntax): New test that regexp syntax
- survives freezing.
- * tests/generate.awk (m4_pattern_allow): Updated for renamesyms.
- * doc/m4.texinfo (Erenamesyms and Renamesyms, Eregexp and Regexp)
- (Epatsubst and Patsubst): Renamed to...
- (Renamesyms, Regexp, Patsubst): ...these respectively. Updated
- documentation and added new examples.
- (Changeresyntax): New section describing changeresyntax builtin,
- and regexp syntax names.
- (Regular expression syntax): New section describing differences
- between various regular expression syntaxes.
- (Frozen files): Document 'R' directive.
- * NEWS: Updated.
-
-2006-07-13 Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap: Enhanced to work more like our other scripts:
- Add a copyright statement; support --version and --help; accept a
- --download-po option with argument as a substitute for DOWNLOAD_PO
- in the environment.
-
-2006-07-11 Eric Blake <ebb9@byu.net>
-
- * Makefile.am (doc/m4.1): Port patch from branch that avoids
- intermediate file.
- * ltdl/m4/gnulib-cache.m4: Regenerate since upstream gnulib-tool
- changed.
-
-2006-07-10 Gary V. Vaughan <gary@gnu.org> (tiny change)
-
- * tests/builtin.at (patsubst, regexp): Adjust these tests, now
- that `\0' is no longer accepted.
-
- * src/main.c (usage): Alphabetize options within their sections.
-
- * modules/gnu.c (m4_regexp_search, regsub, substitute)
- (esyscmd): Improve comments.
-
- * modules/gnu.c (substitute): Remove old warning for \0.
- (substitute_warned): No longer required. Removed.
-
- * modules/gnu.c: Put macro definitions into alphabetical order.
-
-2006-07-07 Eric Blake <ebb9@byu.net>
-
- * tests/freeze.at (loading format 1): New file, with new test.
- * tests/testsuite.at: Include it.
- * tests/macros.at (Arity, defn, and freeze): Add frozen keyword.
- * tests/modules.at (Freezing modules): Likewise.
-
- * configure.ac (AC_PREREQ): Autoconf 2.60 is now out.
- (AC_CHECK_HEADERS): Assume signal.h.
- (AC_CHECK_HEADERS_ONCE): Use new feature to shrink configure.
- (AC_CHECK_FUNCS_ONCE): Likewise.
- * src/m4.h (includes): Assume signal.h.
-
-2006-07-05 Eric Blake <ebb9@byu.net>
-
- Fix all testsuite failures on cygwin.
- * doc/m4.texinfo (Syscmd, Esyscmd): Forward-port updates from
- branch-1_4. Solves testsuite failure when uninstalled m4 is
- shadowed by redefinition of PATH in libtool wrapper.
- * Makefile.am (module_ldflags): Don't forget AM_LDFLAGS, which
- contains the -no-undefined required by cygwin.
- (TESTS_ENVIRONMENT): Export abs_top_builddir.
- * tests/others.at (misc): Port to platforms where /etc/passwd
- does not exist or does not contain user named root.
- * tests/modules.at (AT_CHECK_M4_MODTEST): Look in correct
- directory.
- * tests/builtins.at (define, divert): Avoid overquoting.
- * tests/generate.awk (new_group): Likewise.
-
-2006-07-05 Gary V. Vaughan <gary@gnu.org>
-
- The regs_allocated field in a struct re_pattern_buffer refers
- to the state of a particular re_registers struct when used in
- successive matches using the same compiled pattern. Avoid a
- SEGV in `renamesyms' resulting from using a new re_registers
- with an existing re_pattern_buffer:
-
- * modules/gnu.c (m4_pattern_buffer): Wrapper struct for associated
- pattern buffer and registers.
- (m4_regexp_search): New function to call re_regexp_search with
- correctly matched pattern buffer and register instantiations.
- (m4_regexp_compile): Return an m4_pattern_buffer. Adust all
- callers.
-
-2006-07-04 Gary V. Vaughan <gary@gnu.org>
-
- * ltdl/m4/m4-getopt.m4 (M4_GETOPT): Update to take into account
- changes to gnulib getopt.m4 since last build.
- * Makefile.am (src_m4_SOURCES): Only compile shipped getopt module
- if the system getopt fails M4_GETOPT tests.
-
-2006-06-22 Eric Blake <ebb9@byu.net>
-
- * Makefile.am (EXTRA_DIST): Distribute gnulib-cache.m4.
- Reported by Bruno Haible.
-
-2006-06-22 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * m4/module.c (m4__module_exit): Avoid ltdl memory leak.
-
-2006-06-19 Eric Blake <ebb9@byu.net>
-
- * THANKS: Update.
-
-2006-06-19 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * Makefile.am (src_m4_DEPENDENCIES): Make dependency explicit.
- (clean-local): Split into and depend upon...
- (clean-local-tests, clean-local-src): ...these two. The latter
- removes the libtool object directory below `src', to work around
- a buglet in Automake, failing to list it.
- (EXTRA_DIST): Distribute modules/perl.c.
-
-2006-06-19 Eric Blake <ebb9@byu.net>
-
- * Makefile.am ($(srcdir)/doc/m4.1): No need to list $(srcdir) in
- right side of dependency; VPATH does that.
- (stamp-vcl): Update to use libtool's algorithm.
- (EXTRA_DIST): Distribute stamp-vcl.
- Reported by Ralf Wildenhues.
- (TESTSUITE): Revert earlier change that used absolute path, as
- that broke 'make dist' in VPATH. Stick with $(srcdir) instead.
- (EXTRA_DIST): Revert earlier change of $(TESTSUITE).
- (TESTS_ENVIRONMENT) [USE_GMP]: Revert earlier addition, since
- atlocal takes care of it instead.
- (check-local, installcheck-local, clean-local): Inline absolute
- path to testsuite here, rather than relative path to testsuite
- elsewhere.
-
-2006-06-19 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * m4/m4private.h (DELETE): Cast away const here...
- * src/stackovf.c (stackovf_exit): ...to avoid cast-as-lvalue here.
- * src/freeze.c (reload_frozen_state): Avoid uninitialized
- variable warning.
-
-2006-06-19 Eric Blake <ebb9@byu.net>
-
- * Makefile.am (doc/m4.1): Build in $(srcdir), to match where
- .info pages are built.
- Reported by Ralf Wildenhues.
- (EXTRA_DIST): Inline definition of testsuite, so that make dist
- works again.
-
-2006-06-16 Eric Blake <ebb9@byu.net>
-
- Follow recommendations from autoconf manual for autotest.
- * Makefile.am (TESTSUITE): Factor the $(srcdir) out of uses, and
- turn it into an absolute path until autotest provides an option
- that allows us to avoid changing directories. Properly quote
- throughout.
- (TESTS_ENVIRONMENT) [USE_GMP]: Inform testsuite about GMP.
- (check-recursive): Delete unused target.
- ($(TESTSUITE)): Atomically update testsuite.
- (CD_TESTDIR): Simplify.
- (m4__cd): Delete unused macro.
- (check-local): Let TESTSUITEFLAGS influence the run.
- (installcheck-local): Let TESTSUITEFLAGS override
- AUTOTEST_PATH. Add dependencies.
- (clean-local): Clean up.
- (DISTCLEANFILES, MAINTAINERCLEANFILES): Add directory location.
- * README: Document how to use the testsuite.
-
-2006-06-15 Eric Blake <ebb9@byu.net>
-
- * configure.ac (M4_DEFAULT_PRELOAD): Fix typo in last commit.
-
- * ltdl/m4/m4-error.m4 (M4_ERROR): Use M4_ instead of m4_ to avoid
- clashes with m4sugar.
- * ltdl/m4/m4-getopt.m4 (M4_GETOPT): Likewise.
- * ltdl/m4/m4-gettext.m4 (M4_GNU_GETTEXT): Likewise.
- * ltdl/m4/m4-obstack.m4 (M4_OBSTACK): Likewise.
- * ltdl/m4/m4-regex.m4 (M4_REGEX): Likewise.
- * ltdl/m4/gmp.m4 (_M4_LIB_GMP): Likewise.
- * ltdl/m4/stackovf.m4 (M4_SYS_STACKOVF): Likewise.
- * ltdl/m4/debug.m4 (M4_CHECK_DEBUGGING): Likewise.
- * configure.ac: Likewise.
- (M4_DEFAULT_PRELOAD): Use as a macro, not shell variable.
- * Makefile.am (src_m4_CPPFLAGS): Use STACKOVF as a makefile
- conditional.
- * ltdl/m4/m4-gnulib.m4: Delete, no longer needed.
-
- Reduce compiler warnings. Inside GMP, mpq_t is an array type, so
- const mpq_t is not assignable from plain mpq_t. Avoid
- type-punning warnings caused trying to mix these types.
- * modules/mpeval.c (numb_ior, numb_eor, numb_and, numb_lshift),
- (numb_rshift, numb_divide, numb_modulo): Remove const qualifier.
- * modules/evalparse.c (or_term, xor_term, and_term, shift_term),
- (mult_term, exp_term): Remove type-punning casts.
- (numb_pow): Remove const qualifier.
- * src/freeze.c (reload_frozen_state): Fix typo in messages.
- Fix variables that can be used uninitialized, which fixes
- security hole where malicious frozen file can execute arbitrary
- code.
-
-2006-06-14 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * Makefile.am (modules_mpeval_la_LIBADD): Readd $(LIBADD_GMP).
-
-2006-06-13 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
- and Eric Blake <ebb9@byu.net>
-
- Allow `make dist' to work again.
- * Makefile.am (EXTRA_DIST): doc/helptoman.pl is gone.
- (MAINTAINERCLEANFILES): Avoid redundant mention of dist_man_MANS.
- (cvs-dist): Fix typo.
- * NEWS: Match current version number.
-
-2006-06-13 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * Makefile.am (AM_CPPFLAGS): Add $(LTDLINCL), so the right
- ltdl.h is used.
-
- * bootstrap: Do not run libtoolize manually, this is done
- correctly by autoreconf. Invoke autoreconf with --no-recursive
- to avoid unnecessary rerunning of autotools for libltdl.
-
-2006-06-13 Eric Blake <ebb9@byu.net>
-
- * THANKS: Update.
-
-2006-06-12 Eric Blake <ebb9@byu.net>
-
- * m4/output.c [HAVE_MKTEMP]: Gnulib provides mkstemp, so don't
- bother with mktemp.
- * src/m4.h: Don't declare mktemp.
- * m4/input.c (m4__next_token): Avoid bzero.
- * configure.ac (AC_CHECK_FUNCS): Remove obsolete checks.
- * Makefile.am (doc/m4.1): Depend on installed help2man, rather
- than distributing outdated helptoman.pl.
- * doc/helptoman.pl: Delete.
-
-2006-06-10 Eric Blake <ebb9@byu.net>
-
- * README (Patches): Document the current dependence on CVS
- builds of autotools.
- * ltdl/m4/gnulib-cache.m4: Update, and use --macro-prefix=M4.
- * configure.ac: Use consistent quoting throughout.
- (AC_PREREQ): Bump to 2.59d.
- (AC_INIT): Package name begins with uppercase.
- (AC_ARG_WITH): Use AS_HELP_STRING.
- (AM_INIT_AUTOMAKE): Enable gnits mode.
- (AC_ISC_POSIX, AM_PROG_CC_STDC, AC_PROG_INSTALL, AC_PROG_MAKE_SET),
- (AC_PROG_AWK, AM_C_PROTOTYPES, AC_C_CONST, AC_HEADER_STDC),
- (AC_CHECK_HEADERS, AC_FUNC_ALLOCA, AC_FUNC_VPRINTF): Remove checks
- done by gnulib or automake, or which autoconf has declared
- obsolete.
- * m4/m4private.h (Includes): Assume C89 or better, and use errno
- unconditionally.
- * m4/output.c (Includes): Likewise.
- * modules/gnu.c (Includes): Likewise.
- * modules/m4.c (Includes): Likewise.
- * src/m4.h (Includes): Likewise.
-
- * README-alpha: Update web address.
- * README: Likewise. Change encoding to ASCII. Remove old advice
- about cygwin. Document bootstrapping dependency.
- * AUTHORS: Update from branch-1_4.
- * THANKS: Likewise. Change encoding to UTF-8.
- * BACKLOG: Delete. This file is too old and unmaintained to be
- worthwhile.
- * ChangeLog: Change encoding to UTF-8.
-
- Avoid compiler warnings.
- * m4/macro.c (trace_format): Don't mark this as a printf format,
- since we don't accept the same set of modifiers as printf. It
- would be nice if gcc let us specify a custom format archetype.
- * src/main.c (main): Cast away const.
-
-2006-06-10 Andreas Schwab <schwab@suse.de> (tiny change)
- Eric Blake <ebb9@byu.net>
-
- * modules/time.c (ctime): Pass correctly typed variable to
- m4_numeric_arg.
- (gmtime): Likewise.
- (localtime): Likewise.
- (strftime): Likewise.
- * m4/utility.c (m4_numeric_arg): For now, document arbitrary
- limit inherent in this interface.
-
-2006-05-08 Bruno Haible <bruno@clisp.org> (tiny change)
-
- * modules/m4.c (WEXITSTATUS): Provide fallback definition.
- (sysval): Use WEXITSTATUS.
- * modules/gnu.c (esyscmd): Set sysval to 0xffff, to accomodate both
- big-endian and little-endian wait status definitions.
-
-2006-05-06 Eric Blake <ebb9@byu.net>
-
- * po/Makevars (MSGID_BUGS_ADDRESS): Add.
- * po/POTFILES.in (src/getopt.c, src/version-etc.c): These files live
- in src, not gnu.
-
-2006-05-06 Eric Blake <ebb9@byu.net>
-
- * configure.ac (LT_CONFIG_LTDL_DIR): Inform libtool which
- subdirectory to use.
- (support for -pipe): Move after LT_INIT, since it relies on
- libtool internals.
-
-2006-05-05 Eric Blake <ebb9@byu.net>
-
- * Makefile.am (doc/m4.1): Use $@, not $(srcdir)/doc/$@.
-
- * THANKS: Update.
-
-2006-05-05 Bruno Haible <bruno@clisp.org>
- and Eric Blake <ebb9@byu.net>
-
- * configure.ac (gl_SOURCE_BASE, gl_M4_BASE, gl_MODULES): Move to...
- * ltdl/m4/gnulib-cache.m4: ...this new file, per new gnulib-tool
- usage pattern.
- * bootstrap: Update usage of gnulib-tool.
-
-2006-05-04 Eric Blake <ebb9@byu.net>
-
- * Makefile.am (doc/m4.1): Use EXEEXT on built binary.
- Cleanup whitespace.
-
-2005-12-05 Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap (func_update_po): Synch with CVS GNU tar. wget 1.9.x
- and 1.10.x support --cache=off, so $WGETFLAGS are not necessary.
- Reported by Eric Blake <ebb9@byu.net>
-
-2005-12-04 Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap (func_update_po): Test and set $WGETFLAGS to disable
- http caching as -C is no longer supported by wget 1.10.x.
- Reported by Eric Blake <ebb9@byu.net>
-
-2005-10-20 Gary V. Vaughan <gary@gnu.org>
-
- * m4/module.c (caller_id): To match libtool-2.0 interface, changed
- to ...
- (iface_id): ...an lt_dlinterface_id type.
- (m4__module_find): New abstraction for lt_dlhandle_fetch. Use
- throughout, instead of calling obsolete lt_dlhandle_find directly.
- (m4__module_next): Use multiloader-safe lt_dlhandle_iterate. Use
- throughout, instead of calling obsolete lt_dlhandle_next.
- * m4/m4private.h (m4__module_find): Declare it.
- * m4/builtin.c (m4_builtin_find_by_name, m4_builtin_find_by_func):
- Use m4__module_next instead of obsolete lt_dlhandle_next.
-
-2005-10-20 Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap (func_update_po): Update pofiles directly from the
- translation project.
- * po/LINGUAS, po/cs.po, po/de.po, po/el.po, po/fr.po, po/it.po,
- po/ja.po, po/nl.po, po/pl.po, po/ru.po, po/sv.po: No need to store
- these files under source control anymore.
- Suggested by Eric Blake <ebb9@byu.net>
-
-2005-07-07 Paul Eggert <eggert@cs.ucla.edu>
-
- * ltdl/m4/m4-gnulib.m4: Update FSF contact address. Somehow this
- file escaped the address updates on 2005-05-01.
-
-2005-07-07 Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap: Allow user overriding of gnulib-tool location, and
- correctly determine module source directories whether gnulib-tool
- is given as a relative or absolute path, or is found by searching
- PATH.
- Reported by Eric Blake <ebb9@byu.net>
-
-2005-07-07 Ralf Wildenhues <Ralf.Wildenhues@gmx.de>
-
- * ltdl/m4/debug.m4 (m4_CHECK_DEBUGGING): Make sure that both $rm
- and $RM are defined for various versions of
- AC_LIBTOOL_COMPILER_OPTION.
-
- * bootstrap (AUTORECONF): New variable to allow user overriding of
- autoreconf path.
-
-2005-07-07 Gary V. Vaughan <gary@gnu.org>
-
- * doc/m4.texinfo (History): Add better notes on the ancestory of
- GNU m4, and other historical interest.
-
-2005-05-08 Gary V. Vaughan <gary@gnu.org>
-
- * m4/symtab.c (m4_symbol_rename): New function that performs a low
- level symbol rename.
- * m4/m4module.h (m4_symbol_rename): Declare it as part of the API.
- * modules/gnu.c (regsub): Factored out of m4_epatsubst_do...
- (m4_patsubst_do, m4_renamesyms_do): ...wrappers that use
- regsub...
- (erenamesyms, renamesyms): ...builtins that use these to implement
- macro renaming by regular expression.
- * doc/m4.texinfo (Erenamesyms and Renamesyms): Document them.
- * tests/generate.awk: Allow some forbidden `m4_' prefixed symbols
- to stop the new generated tests from choking.
-
-2005-05-07 Gary V. Vaughan <gary@gnu.org>
-
- Since most of the build is handled from a single Makefile.am now,
- we can teach make about the dependencies between the m4 binary and
- the preopened modules it is built against:
-
- * configure.ac (PREOPEN_DEPENDENCIES): Substitute for a list of
- preopened modules.
- * Makefile.am (src_m4_DEPENDENCIES): Rebuild the m4 program if any
- of the preopened modules have changed.
-
-2005-05-07 Gary V. Vaughan <gary@gnu.org>
-
- * configure.ac (gl_MODULES): Add mkstemp for machines that don't
- have a native implementation.
-
-2005-05-06 Gary V. Vaughan <gary@gnu.org>
-
- * src/m4.h (EXIT_SUCCESS, EXIT_FAILURE): Removed. These are
- handled already by gnu/exit.h.
-
- * configure.ac (gl_MODULES): Add assert to support a
- --disable-assert configure time option for NDEBUG setting.
-
- * Makefile.am (src_m4_SOURCES): Add version-etc-fsf.c.
- * bootstrap (src_modules): Add version-etc-fsf.
- * src/main.c (version_etc_copyright): Removed.
-
- * ltdl/m4/m4-getopt.m4 (m4_GETOPT): Synch with gnulib/getopt.m4.
-
-2005-05-04 Gary V. Vaughan <gary@gnu.org>
-
- * src/m4.h (__CYGWIN__, WIN32): Canonicalise Windows and Cygwin
- recognition macros.
- * src/freeze.c (produce_frozen_state): Use \n line-endings even
- on Windows, so that the frozen file reader will work.
- Reported by Josef T. Burger <bolo@bolo.com>
-
-2005-05-04 Vincent Lonngren <Vincent.lonngren.759@student.lu.se>
-
- Forward port of a patch that allowed m4-1.4.2 to compile on
- QNX 6.3:
-
- * configure.ac (AC_CHECK_HEADERS): Add signal.h,
- sys/signal.h.
- * src/m4.h: And include them as appropriate.
- * src/main.c, src/stackovf.h: Don't include signal.h literally;
- m4.h will include the correct file.
-
-2005-05-04 Gary V. Vaughan <gary@gnu.org>
-
- * m4/m4private.h: Make errno visible for the sources patched
- below.
-
-2005-05-04 Paul Eggert <eggert@twinsun.com>
-
- * src/main.c (print_program_name_CB): Preserve errno, since
- M4ERROR relies on this.
- * modules/gnu.c (m4_esyscmd): Clear errno before calling popen.
- * modules/m4.c (m4_maketemp): Clear errno before calling mkstemp.
- * m4/path.c (m4_path_search): Don't let "free" trash errno when
- returning NULL.
-
- * m4/output.c (m4_insert_file): Don't assume errno has a valid
- value simply because fread returns zero. This fixes a
- portability bug reported by Marion Hakanson in
- <http://lists.gnu.org/archive/html/bug-m4/2004-07/msg00029.html>.
-
-2005-05-04 Santiago Vila <sanvila@debian.org>
-
- * tests/stackovf.test: Use tempfile if available.
-
-2005-05-04 Robert Bihlmeyer <robbe@orcus.priv.at> (tiny change)
-
- http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=92629
- * m4/output.c (m4_insert_file): Do not mix buffered and
- unbuffered I/O, as this breaks on the Hurd.
-
-2005-05-04 Gary V. Vaughan <gary@gnu.org>
-
- Gnulib has changed again. Reimport. Adjust. Rinse. Repeat.
- Automake and Libtool now agree on subdir-objects and LTLIBOBJS,
- and libtoolize does a better job of ltdl importing now too, so
- take advantage of that while updating the tree:
-
- * acm4, config: Moved from here...
- * ltdl/m4, ltdl/config: ...to here.
- * doc/Makefile.am, m4/Makefile.am, modules/Makefile.am,
- src/Makefile.am, tests/Makefile.am: Removed...
- * Makefile.am: ...and migrated to here, with adjustments to
- compensate for relative path differences.
- * commit: Adjust relative paths.
- * configure.ac: Adjust relative paths.
- (AC_PREREQ): 2.59 isn't strictly new enough, we also need a
- patch.
- (LT_PREREQ): 2.0 isn't released yet, but will work when it is! In
- the meanwhile, CVS HEAD libtool is needed.
- (AM_INIT_AUTOMAKE): Added subdir-objects declaration. 1.9.5 isn't
- stricly new enough, we also need a patch.
- (AM_PROG_CC_C_O): Required for subdir-objects in Automake.
- (AC_WITH_LTDL): Replaced with LT_WITH_LTDL.
- (gl_MODULES): Don't list getopt and version-etc, as they don't
- belong in libm4.
- * bootstrap: After running gnulib-tool to import the listed
- modules, fetch getopt and version-etc into src manually.
- (ltdldir): Change to ltdl.
- * src/main.c: Adjust for changes in version-etc API.
- * ltdl/m4/m4-getopt.m4: New macro to mirror gnulib's getopt.m4,
- but works when the getopt module isn't to be included in the lib.
- * README: Add note about patching autoconf and automake to
- bootstrap CVS m4.
-
-2005-05-02 Matt Kraai <kraai@debian.org> (tiny change)
-
- http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=84416
- * doc/m4.texinfo (Maketemp): Change maketemp to refer to a new,
- empty file rather than to a nonexistent file. This closes a
- common security hole.
- * modules/m4.c (m4_maketemp): Implement the above, by using
- mkstemp rather than mktemp.
-
-2005-05-01 Gary V. Vaughan <gary@gnu.org>
-
- The FSF are moving offices today. Changed their contact address
- in all files from `59 Temple Place, Suite 330, MA 02111-1307' to
- `51 Franklin Street, Fifth Floor, MA 02110-1301'.
-
-2005-03-11 Ralf Wildenhues <Ralf.Wildenhues@gmx.de> (tiny change)
-
- * tests/Makefile (clean-local): Ignore testsuite cleanup
- failures.
-
-2005-03-11 Per Bothner <per@bothner.com> (tiny change)
-
- * tests/Makefile (clean-local): Only run the testsuite cleanup
- if the testsuite has been generated.
-
-2005-02-11 Stepan Kasal <kasal@ucw.cz>
-
- * TODO: slight clarification of the example of qindir usage.
-
-2005-02-08 Gary V. Vaughan <gary@gnu.org>
-
- * TODO: Add qindir requirement, and defn bug.
- From Stepan Kasal <kasal@ucw.cz>
-
-2005-02-08 Stepan Kasal <kasal@ucw.cz>
-
- * TODO: Add ``execution stack'', fix a typo.
- * doc/m4.texinfo: Typos.
-
-2004-12-24 Eric Blake <ebb9@byu.net>
-
- * configure.ac (INCLUDE_STDBOOL_H): Account for gnulib's move
- to the gnu subdirectory.
- * acm4/m4-error.m4 (INCLUDE_ERROR_H): Likewise.
- * acm4/m4-obstack.m4 (INCLUDE_OBSTACK_H): Likewise.
- * acm4/m4-regex.m4 (INCLUDE_REGEX_H): Likewise.
- * m4/system_.h: Likewise, in non-configured includes.
-
-2004-10-14 Noah Misch <noah@cs.caltech.edu>,
- Gary V. Vaughan <gary@gnu.org>
-
- * m4/m4.c (m4_context_field_table, m4_context_opt_bit_table):
- Protect definitions from macro expansion under -DNDEBUG by
- parenthesising the expanded function names.
- * m4/syntax.c (m4_get_syntax_lquote, m4_get_syntax_rquote)
- (m4_get_syntax_bcomm, m4_get_syntax_ecomm)
- (m4_is_syntax_single_quotes, m4_is_syntax_single_comments)
- (m4_is_syntax_macro_escaped): Similarly protect function
- definitions from macro expansion under -DNDEBUG by #undefing the
- matching macro names before each definition. Also, move all the
- function definitions to the end of the file so that any
- invocations in the rest of the file pick up the fast macro
- versions.
- * m4/m4private.h (m4_set_symbol_table, m4_set_syntax_table)
- (m4_set_debug_file, m4_set_trace_messages)
- (m4_set_warning_status_opt, m4_set_no_gnu_extensions_opt)
- (m4_set_nesting_limit_opt, m4_set_debug_level_opt)
- (m4_set_max_debug_arg_length_opt): New fast macro versions of the
- option setter functions.
-
-2004-09-23 Gary V. Vaughan <gary@gnu.org>
-
- * po/POTFILES.in: Reflect move of gnulib files from gnulib/m4
- to gnu.
-
-2004-09-23 Gary V. Vaughan <gary@gnu.org>
-
- * src/main.c: Include gnulib files from the correct directory.
-
- * gnulib/*: Don't store any of the gnulib files in arch, as they
- generate spurious changes.
- * Makefile.am (ACLOCAL_AMFLAGS): Remove gnulib/acm4 since the
- gnulib macros now share our macro directory.
- (SUBDIRS): Descend into `gnu' rather than `gnulib'.
- * bootstrap: Call gnulib-tool to import from the gnulib tree.
- (gl_AC_HEADER_INT_TYPES_H, gl_AC_HEADER_STDINT_H,
- gl_AC_TYPE_UINTMAX_T): Patch gnulib.m4 to define these in terms of
- the gettext macros from autopoint that overwrite the gnulib-tool
- imported versions. Import sources and Makefile.am into the `gnu'
- directory. Changed all callers.
- * configure.ac (gl_EARLY, gl_SOURCE_BASE, gl_M4_BASE, gl_MODULES,
- gl_INIT): Call these gnulib-tool macros instead of the hardcoded
- for imported modules.
- * acm4/m4-error.m4, acm4/m4-gettext.m4, acm4/m4-obstack.m4,
- acm4/m4-regex.m4: Use AC_BEFORE to enforce ordering rather than
- hardcoding the gnulib macros they wrap.
-
-2004-07-15 Gary V. Vaughan <gary@gnu.org>
-
- Latest CVS libtool can preload modules in libraries, including
- its own module loaders! Tweak m4 so that it doesn't try to treat
- libltdl's module loaders as m4 modules when freezing and on exit:
-
- * gnulib/acm4/*.m4: Don't store these files in arch since they
- generate spurious changes.
- * bootstrap: Simplify initial libtoolize call, since CVS
- libtoolize is smarter these days.
- * doc/Makefile.am (%.1): Make the helptoman call work with a VPATH
- build.
- * m4/module.h (m4__module_exit): Missing declaration.
- * m4/m4private.h (m4__module_next): New function declaration.
- * m4/module.c (m4__module_next): lt_dlhandle_{firs,nex}t
- encapsulation. Changed all callers.
- (m4__module_interface): New function to verify m4 loadable module
- interfaces.
- (m4__module_init): Register the interface validator.
- (m4__module_exit): Only close my own modules.
- * modules/m4.c (unistd.h): Provide missing declaration.
- (m4_set_sysval, m4_sysval_flush, m4_dump_symbols)
- (m4_expand_ranges): More missing declarations.
- * modules/modtest.c (export_test): Ditto.
- * src/Makefile.am (AM_CPPFLAGS): Add libltdl directory.
- * src/main.c (main): Bump copyright year.
- * tests/modules.at: Fix sed syntax error.
-
-
-2004-06-17 Gary V. Vaughan <gary@gnu.org>
-
- Tweaking to enable compilation with latest CVS libtool and
- libltdl. We can't just dump the library files directly into the
- m4 directory anymore now that libltdl is built from pieces itself:
-
- * bootstrap: Rewritten to use latest libtoolize sanely, and to
- set up libltdl subdirectory.
- * configure.ac (AC_CONFIG_AUX_DIR): Point to our own, not the
- gnulib subdirectory's config.
- (TIMESTAMP): Use $ac_aux_dir for VPATH builds.
- (m4_pattern_forbid): Remove the cruft to deal with renamed jm_
- macros from gnulib.
- (AC_LIB_LTDL): Latest libltdl is a sub-project with its own
- configure.ac, so use AC_WITH_LTDL instead.
- * Makefile.am (SUBDIRS): Add libltdl.
- * acm4/m4-regex.m4 (jm_INCLUDED_REGEX): Updated. gnulib now uses
- gl_INCLUDED_REGEX.
- * m4/Makefile.am (AM_CPPFLAGS): Add INCLTDL.
- (libm4_la_SOURCES): Remove ltdl.c and ltdl.h.
- (libm4_la_LIBADD): Add LIBLTDL.
- * m4/ltdl.c, m4/ltdl.h: Removed.
- * m4/m4module.h: Include canonical ltdl.h.
- * po/*.po: Updated.
-
-2004-06-14 Gary V. Vaughan <gary@gnu.org>
-
- * gnulib/import: Now updates makefile fragments, and configure.ac.
- * gnulib/m4/gnulib.am: New file. Generated makefile fragments.
- * gnulib/m4/Makefile.am: include it.
- * gnulib/acm4/intmax.m4, gnulib/acm4/longdouble.m4,
- gnulib/acm4/longlong.m4, gnulib/acm4/printf-posix.m4,
- gnulib/acm4/signed.m4, gnulib/acm4/size_max.m4,
- gnulib/acm4/wchar_t.m4, gnulib/acm4/wint_t.m4,
- gnulib/acm4/xsize.m4: New macro files from latest gnulib import.
- * gnulib/acm4/alloca.m4, gnulib/acm4/inttypes_h.m4,
- gnulib/acm4/lib-ld.m4, gnulib/acm4/lib-prefix.m4,
- gnulib/acm4/error.m4, gnulib/acm4/po.m4, gnulib/acm4/regex.m4,
- gnulib/acm4/stdbool.m4, gnulib/acm4/stdint_h.m4,
- gnulib/acm4/uintmax_t.m4, gnulib/acm4/ulonglong.m4,
- gnulib/acm4/unlocked-io.m4, gnulib/acm4/xalloc.m4,
- gnulib/acm4/free.m4, gnulib/acm4/gettext.m4,
- gnulib/acm4/glibc21.m4: Updated macro files from latest gnulib
- import.
- * gnulib/m4/getopt_int.h: New source file from latest gnulib
- import.
- * gnulib/m4/alloca.c, gnulib/m4/alloca_.h, gnulib/m4/getopt1.c,
- gnulib/m4/obstack.c, gnulib/m4/obstack.h, gnulib/m4/regex.c,
- gnulib/m4/unlocked-io.h, gnulib/m4/version-etc.c,
- gnulib/m4/xmalloc.c, gnulib/m4/getopt.c, gnulib/m4/getopt.h:
- Updated source files from latest gnulib.
-
-2004-02-29 Gary V. Vaughan <gary@gnu.org>
-
- * config/mailnotify: New file for mailing commit notifications,
- imported from cvs-utils.
- * commit: Updated from cvs-utils and tweaked for m4.
-
-2003-12-01 Gary V. Vaughan <gary@gnu.org>
-
- * config/mkstamp: Updated from CVS libtool.
- * configure.ac: Generate a gnu coding standards compliant version
- number, and use it for the banner.
- * Makefile.am (stamp-vcl): New rules to force m4 to be regenerated
- mhen the TIMESTAMP changes in ChangeLog, but the file modification
- time doesn't (e.g. in cvs commit). Otherwise dist tarballs will
- contain the previous version number.
- * src/main.c: Make --version output conform to the GNU standard.
-
- * configure.ac (AM_INIT_AUTOMAKE): Require 1.7g...
- * modules/Makefile.am (gnu_la_SOURCES, load_la_SOURCES,
- m4_la_SOURCES, traditional_la_SOURCES, modtest_la_SOURCES,
- shadow_la_SOURCES, import_la_SOURCES, stdlib_la_SOURCES,
- time_la_SOURCES): ...so that these are defaulted correctly, and
- can be removed from this file.
- (AM_LDFLAGS): Add -module...
- (gnu_la_LDFLAGS, load_la_LDFLAGS, m4_la_LDFLAGS,
- traditional_la_LDFLAGS, modtest_la_LDFLAGS, shadow_la_LDFLAGS,
- import_la_LDFLAGS, stdlib_la_LDFLAGS, time_la_LDFLAGS): ...so that
- the individual settings can be removed.
- * m4/Makefile.am (libm4_la_LIBADD): Add $(LTLIBINTL) here once...
- * module/Makefile.am (gnu_la_LIBADD, load_la_LIBADD,
- m4_la_LIBADD, traditional_la_LIBADD, modtest_la_LIBADD,
- shadow_la_LIBADD, import_la_LIBADD, stdlib_la_LIBADD,
- time_la_LIBADD): ...so that these are picked up as a deplib of
- libm4 and don't need to be set explicitly.
-
-2003-11-18 Gary V. Vaughan <gary@gnu.org>
-
- * modules/Makefile.am (pkglibexec_LTLIBRARIES): Remove perl.la
- from the standard build. It is too fragile.
-
- * gnulib/acm4/libtool.m4, m4/ltdl.c, m4/ltdl.h: Reimported from
- CVS libtool after merging m4 changes across to libtool.
-
- * m4/symtab.c (m4_symtab_create): Fix a careless use of sizeof.
- * m4/path.c (search_path_add): Ditto.
-
-2003-11-13 Gary V. Vaughan <gary@gnu.org>
-
- * configure.ac (AC_LIBTOOL_TAGS): Don't include shell code for
- libtool tags we don't use in configure. This reduces the size
- of the script from over 1Mb to under 700Kb.
-
-2003-11-13 Gary V. Vaughan <gary@gnu.org>
-
- The import script was not written properly, and the last gnulib
- import was incomplete. Fixed that problem, and reimport our
- gnulib dependencies, which picks up the address calculation
- overflow checks described by Paul below. Also tweak the clients
- of the gnulib xalloc module not to use deprecated macros:
-
- * gnulib/import: Recurse through module dependencies rather than
- naively descending only one level.
- * configure.ac: Add calls to gnulib's strnlen and extension module
- macros.
- * gnulib/m4/Makefile.am: Add snippets from gnulib's strnlen and
- extension modules.
- * gnulib/acm4/extensions.m4, gnulib/acm4/xalloc.m4,
- gnulib/m4/alloca.c, gnulib/m4/obstack.c, gnulib/m4/obstack.h,
- gnulib/m4/stdbool_.h, gnulib/m4/unlocked-io.h, gnulib/m4/xalloc.h,
- gnulib/m4/xmalloc.c, gnulib/m4/xstrdup.c: Updated from CVS
- gnulib.
- * gnulib/acm4/libtool.m4: Updated from CVS libtool.
- * m4/hash.c (m4_get_hash_iterator_next): Use `xzalloc (S)' in
- place of `xcalloc (1, S)'.
- * m4/m4.c (m4_create): Likewise.
- * m4/m4private.h (m4_symbol_value_create): Likewise.
- * m4/symtab.c (symtab_fetch): Likewise.
- * m4/syntax.c (m4_syntax_create): Likewise.
- * src/freeze.c (reload_frozen_state): Likewise.
- * m4/path.c (search_path_add): Eliminate use of deprecated NEW
- macro.
- * m4/symtab.c (m4_symtab_create): Likewise.
-
-2003-11-13 Gary V. Vaughan <gary@gnu.org>
-
- * tests/module.at: Comment typo.
-
-2003-10-10 Gary V. Vaughan <gary@gnu.org>
-
- * tests/modules.at (modules: importing): Apply some lateral
- thinking, and use AT_CHECK to compare the output of a sed pass
- over stderr against the canonical strerror string.
-
- * tests/modules.at (modules: importing): Edit the generated stderr
- output to canonicalize strerror output, before a comparison.
-
-2003-10-10 Gary V. Vaughan <gary@gnu.org>
-
- Tru64UNIX perl is sloppy with namespace pollution. This patch is
- careful not to trip over the mess:
-
- * modules/perl.c: Some builds of perl install headers that contain
- `#define try __builtin_try'. Be sure to undefine that macro
- before `m4/hash.h' gets included, which uses the `try' symbol.
- * m4/system_.h: Similarly for `bool'. Undefine `bool', `true' and
- `false' before including `stdbool.h'.
- (DELETE): This symbol is not in m4's namespace, and is in any
- case only used internally...
- * m4/m4private.h (DELETE): ...so move it to here.
- Reported by Martin MOKREJS <mmokrejs@natur.cuni.cz>
-
-2003-10-08 Paul Eggert <eggert@twinsun.com>
-
- Don't use XMALLOC and XCALLOC. Once we install the
- corresponding patch into gnulib, this will fix some
- address-calculation overflow bugs on hosts where calloc (A, B)
- returns garbage when A*B overflows.
-
- * m4/hash.c (m4_hash_new, node_new, m4_hash_resize,
- maybe_grow, m4_get_hash_iterator_next): Replace XMALLOC with
- xmalloc, XCALLOC with xcalloc.
- * m4/m4.c (m4_create): Likewise.
- * m4/m4private.h (m4_symbol_value_create): Likewise.
- * m4/output.c (m4_output_init): Likewise.
- * m4/symtab.c (symtab_fetch, m4_set_symbol_traced): Likewise.
- * m4/syntax.c (remove_syntax_attribute): Likewise.
- * src/freeze.c (reload_frozen_state): Likewise.
- * src/main.c (main): Likewise.
-
-2003-10-07 Gary V. Vaughan <gary@gnu.org>
-
- * Makefile.am (ACLOCAL_AMFLAGS): Search in the new acm4 and
- gnulib/acm4 directories for aclocal m4 macros.
- * gnulib/Makefile.am (EXTRA_DIST): Removed.
- (MAINTAINERCLEANFILES): Add Makefile.in.
- * configure.ac (m4_GNULIB_MODULES): Use it to declare which gnulib
- modules we use.
- * acm4/m4-gnulib.m4 (m4_GNULIB_MODULES): New macro.
- * gnulib/import: New file. Temporary script for updating gnulib
- imported files, until gnulib-tool is working.
- * gnulib/config/codeset.m4, gnulib/config/error.m4,
- gnulib/config/exitfail.m4, gnulib/config/extensions.m4,
- gnulib/config/getopt.m4, gnulib/config/gettext.m4,
- gnulib/config/glibc21.m4, gnulib/config/iconv.m4,
- gnulib/config/intdiv0.m4, gnulib/config/inttypes-pri.m4,
- gnulib/config/inttypes.m4, gnulib/config/inttypes_h.m4,
- gnulib/config/isc-posix.m4, gnulib/config/lcmessage.m4,
- gnulib/config/lib-ld.m4, gnulib/config/lib-link.m4,
- gnulib/config/lib-prefix.m4, gnulib/config/malloc.m4,
- gnulib/config/nls.m4, gnulib/config/obstack.m4,
- gnulib/config/onceonly_2_57.m4, gnulib/config/po.m4,
- gnulib/config/progtest.m4, gnulib/config/realloc.m4,
- gnulib/config/regex.m4, gnulib/config/restrict.m4.
- gnulib/config/stdbool.m4, gnulib/config/stdint_h.m4,
- gnulib/config/strerror_r.m4, gnulib/config/strndup.m4,
- gnulib/config/strnlen.m4, gnulib/config/strtol.m4,
- gnulib/config/uintmax_t.m4, gnulib/config/ulonglong.m4,
- gnulib/config/unlocked-io.m4, gnulib/config/xalloc.m4,
- gnulib/config/xstrndup.m4: Removed.
- * gnulib/acm4/alloca.m4, gnulib/acm4/codeset.m4,
- gnulib/acm4/error.m4, gnulib/acm4/exitfail.m4,
- gnulib/acm4/extensions.m4, gnulib/acm4/free.m4,
- gnulib/acm4/getopt.m4, gnulib/acm4/gettext.m4,
- gnulib/acm4/glibc21.m4, gnulib/acm4/iconv.m4,
- gnulib/acm4/intdiv0.m4, gnulib/acm4/inttypes-pri.m4,
- gnulib/acm4/inttypes.m4, gnulib/acm4/inttypes_h.m4,
- gnulib/acm4/isc-posix.m4, gnulib/acm4/lcmessage.m4,
- gnulib/acm4/lib-ld.m4, gnulib/acm4/lib-link.m4,
- gnulib/acm4/lib-prefix.m4, gnulib/acm4/malloc.m4,
- gnulib/acm4/nls.m4, gnulib/acm4/obstack.m4,
- gnulib/acm4/onceonly_2_57.m4, gnulib/acm4/po.m4,
- gnulib/acm4/progtest.m4, gnulib/acm4/realloc.m4,
- gnulib/acm4/regex.m4, gnulib/acm4/restrict.m4.
- gnulib/acm4/stdbool.m4, gnulib/acm4/stdint_h.m4,
- gnulib/acm4/strerror_r.m4, gnulib/acm4/strndup.m4,
- gnulib/acm4/strnlen.m4, gnulib/acm4/strtol.m4,
- gnulib/acm4/uintmax_t.m4, gnulib/acm4/ulonglong.m4,
- gnulib/acm4/unlocked-io.m4, gnulib/acm4/xalloc.m4,
- gnulib/acm4/xstrndup.m4: Reimported from CVS gnulib with
- gnulib/import script.
- * gnulib/m4/alloca.c, gnulib/m4/alloca_.h, gnulib/m4/error.c,
- gnulib/m4/error.h, gnulib/m4/exitfail.c, gnulib/m4/free.c,
- gnulib/m4/malloc.c, gnulib/m4/obstack.c, gnulib/m4/obstack.h,
- gnulib/m4/realloc.c, gnulib/m4/regex.c, gnulib/m4/strtol.c,
- gnulib/m4/version-etc.c, gnulib/m4/version-etc.h,
- gnulib/m4/xalloc.h, gnulib/m4/xmalloc.c: Updated from CVS
- gnulib with gnulib/import script.
- * configure.ac, gnulib/m4/Makefile.am: Manually insert anticipated
- guards ready for gnulib-tool to autoupdate on import.
- * config/debug.m4, config/gmp.m4, config/m4-error.m4,
- config/m4-gettext.m4, config/m4-obstack.m4, config/m4-regex.m4,
- config/stackovf.m4: Moved from here...
- * acm4/debug.m4, acm4/gmp.m4, acm4/m4-error.m4,
- acm4/m4-gettext.m4, acm4/m4-obstack.m4, acm4/m4-regex.m4,
- acm4/stackovf.m4: ...to here, to separate aclocal macros from
- configure time helper scripts.
- * config/error.m4: Removed; superceded by gnulib/acm4/error.m4.
- * m4/hash.c, m4/m4.c, m4/macro.c, m4/module.c, m4/output.c,
- m4/path.c, m4/symtab.c, m4/syntax, m4/system_.h, modules/m4.c,
- src/main.c, src/stackovf.c: s/xfree/free/g to comply with new
- gnulib xalloc.h.
- * src/main.c (version_etc_copyright): Only output the current
- year.
- (version_etc): Call with new variadic API.
-
-2003-09-16 Gary V. Vaughan <gary@gnu.org>
-
- * gnulib/m4/version-etc.c, gnulib/m4/version-etc.h: Import
- version-etc module from CVS gnulib.
- * po/POTFILES.in: Add gnulib/m4/version-etc.c.
- * src/Makefile.am: Build it.
- * src/main.c: Use it.
-
- * gnulib/m4/exit.h: Import exit module from CVS gnulib.
- * gnulib/m4/Makefile.am (pkginclude_HEADERS): Add exit.h.
- * m4/system_.h: Don't define EXIT_SUCCESS and FAILURE, include
- exit.h instead.
-
-2003-09-15 Charles Wilson <cygwin@cwilson.fastmail.fm>,
- Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap: Separate options.
- * configure.ac (AM_GNU_GETTEXT_VERSION): Bump to 0.12.1.
- * gnulib/m4/Makefile.am (stdbool.h): Use srcdir, gnulib_srcdir is
- not set.
- * modules/Makefile.am (gnu_la_LIBADD, load_la_LIBADD)
- (m4_la_LIBADD, mpeval_la_LIBADD, traditianal_la_LIBADD)
- (modtest_la_LIBADD, import_la_LIBADD, perl_la_LIBADD)
- (shadow_la_LIBADD, stdlib_la_LIBADD, time_la_LIBADD): Add
- $(LTLIBINTL) for gettext support on cygwin.
- * src/Makefile.am (m4_LDADD): Remove $(INTLLIBS), since we now
- have $(LTLIBINTL) from the preloaded module la files.
- * README: Remove the warning about using --disable-nls on Windows
- machines.
-
-2003-09-15 Gary V. Vaughan <gary@gnu.org>
-
- * gnulib/m4/regex.c: s/<regex.h>/"regex.h"/ or else the compiler
- picks up the system regex.h if gl_REGEX decides gnulib/m4/regex.c
- is required.
-
-2003-09-12 Gary V. Vaughan <gary@gnu.org>
-
- * doc/STYLE: Document the gnulib header naming conventions, and
- #include policy.
- * gnulib/m4/error_.h, gnulib/m4/gettext_.h, gnulib/m4/obstack_.h,
- gnulib/m4/regex_.h: Renamed to gnulib/m4/error.h,
- gnulib/m4/gettext.h, gnulib/m4/obstack.h, gnulib/m4/regex.h
- respectively.
- * gnulib/m4/Makefile.am: Remove the rules to build these headers.
-
- * gnulib/m4/strtol.c, gnulib/config/strtol.m4: Import strtol
- module from CVS gnulib.
- * configure.ac (AC_REPLACE_FUNCS): Remove strtol.
- (gl_FUNC_STRTOL): In favour of the module macro.
-
-2003-09-12 Gary V. Vaughan <gary@gnu.org>
-
- Replace the getopt code with CVS gnulib getopt. The source files
- detect whether they are in a glibc environment and preprocess away
- all of the code if there is a system getopt, so we can compile
- them into the m4 executable unconditionally:
-
- * gnulib/m4/getopt.c, gnulib/m4/getopt1.c, gnulib/m4/getopt.h,
- gnulib/config/getopt.m4: Import getopt module from CVS gnulib.
- * configure.ac (gl_GETOPT): Use this instead of homebrew inline
- macros.
- * src/getopt.c, src/getopt1.c, src/gnu-getopt.h: Removed old
- version.
- * src/Makefile.am: Adjust.
- * src/main.c: Always include our shipped getopt.h.
- * po/POTFILES.in: Use new location of getopt.c.
-
-2003-09-12 Gary V. Vaughan <gary@gnu.org>
-
- * configure.ac (AC_CONFIG_FILES): Remove config/Makefile.
- * config/Makefile.am: Removed. Automake 1.8 distributes the files
- in this directory automatically.
- * Makefile.am (EXTRA_DIST): Except config/mkstamp.
-
- * configure.ac (pkglibexecdir): Don't try and set it here, PACKAGE
- isn't set yet.
- * m4/Makefile.am (MODULE_PATH): Removed. Calculate pkglibexecdir
- inline.
- * modules/Makefile.am (pkglibexecdir): Set it here.
- (pkgmodincdir): Renamed to pkgmodincludedir). Changed all clients.
-
- * gnulib/m4/regex.c, gnulib/m4/regex_.h, gnulib/config/regex.m4:
- Import regex module from CVS gnulib.
- * gnulib/config/restrict.m4: Ditto for dependee module restrict.
- * config/m4-regex.m4 (m4_REGEX): Wrap gnulib/config/regex.m4, but
- do extra substitutions for Makefile.
- * configure.ac: Use it.
- * gnulib/m4/Makefile.am: Maybe install regex.h after linking it
- from regex_.h if necessary.
- * m4/system_.h: Include the correct version of regex.h.
- * m4/regex.c, m4/regex.h, config/regex.m4: Removed legacy
- version.
- * po/POTFILES.in: Use new location of regex.c.
-
- * gnulib/m4/Makefile.am (EXTRA_DIST): Removed malloc.c and
- realloc.c: automake distributes these files already.
-
-2003-09-12 Gary V. Vaughan <gary@gnu.org>
-
- Replace the xstrzdup code by importing the xstrndup module from
- CVS gnulib, along with its dependencies: strndup and strnlen:
-
- * gnulib/m4/xstrndup.c, gnulib/m4/xstrndup.h,
- gnulib/config/xstrndup.m4: Import xstrndup module from CVS
- gnulib.
- * gnulib/m4/strndup.c, gnulib/m4/strndup.h,
- gnulib/config/strndup.m4: Ditto wrt strndup.
- * gnulib/m4/strnlen.c, gnulib/config/strnlen.m4: Ditto wrt
- strnlen.
- * gnulib/m4/Makefile.am: Add rules from newly imported modules.
- However, contrary to gnulib, we install xstrndup.h.
- * configure.ac (AC_REPLACE_FUNCS): Remove xstrzdup.
- * gnulib/lib/xstrzdup.c: Delete. This was never a gnulib file, it
- is an artifact of the old m4 portability layer.
- * configure.ac (gl_XSTRNDUP): This is the gnulib equivalent.
- * m4/system_.h: Include xstrndup.h.
- * m4/macro.c (process_macro): Call xstrndup, not xstrzdup.
-
-2003-09-11 Gary V. Vaughan <gary@gnu.org>
-
- Reimport the latest xalloc module from CVS gnulib, and adjust the
- m4 sources to take advantage of xalloc xfree. Also create a new
- macro DELETE with the same semantics as the old m4 XFREE macro,
- and carefully tweak callers:
-
- * gnulib/config/xalloc.m4, gnulib/m4/xalloc.h: Updated from CVS
- gnulib.
- * m4/utility.c (xfree): Removed. This function is now supplied by
- gnulib xalloc.
- * m4/m4private.h (WITH_DMALLOC): Removed XFREE redefine.
- * m4/path.c (search_path_add): Use NEW macro from xalloc.h.
- * m4/symtab.c (m4_symtab_create): Ditto.
- * m4/system_.h: Removed XFREE redefine.
- (DELETE): New macro with same functionality as the original m4
- XFREE macro, but based on xalloc.h now. Changed all callers.
- * src/main.c (main): Use XMALLOC macro.
- * m4/hash.c, m4/macro.c, m4/symtab.c, m4/syntax.c: Use xfree
- instead of XFREE.
- * m4/output.c (m4_output_exit): Use DELETE instead of XFREE.
-
-2003-09-10 Gary V. Vaughan <gary@gnu.org>
-
- Import the xalloc module from CVS gnulib, along with its
- dependencies: exitfail, malloc and realloc. We had different
- semantics for our XFREE and a function xfree() not supplied by
- gnulib, so also a bit of work to keep everything running
- smoothly:
-
- * configure.ac (AC_REPLACE_FUNCS): Removed xmalloc and xstrdup.
- (gl_XALLOC): Use gnulib equivalents.
- * gnulib/config/exitfail.m4, gnulib/m4/exitfail.h,
- gnulib/m4/exitfail.c: Import exitfail module from CVS gnulib.
- * gnulib/config/malloc.m4, gnulib/m4/malloc.c: Ditto wrt malloc.
- * gnulib/config/realloc.m4, gnulib/m4/realloc.c: Ditto wrt
- realloc.
- * gnulib/config/xalloc.m4, gnulib/m4/xalloc.h,
- gnulib/m4/xmalloc.c, gnulib/m4/xstrdup.c: Ditto wrt xalloc.
- * gnulib/m4/Makefile.am: Add fragment from gnulib for newly
- imported modules.
- (pkgincdir): Removed. Use pkgincludedir instead.
- * m4/m4private.h (XFREE): xfree already checks for NULL.
- * m4/system_.h: Use xalloc module, and remove macros already
- supplied by xalloc.h.
- * m4/utility.c (xfree): xalloc does not yet implement xfree, so
- moved the old definition from m4/xmalloc.c to here for now.
-
-2003-09-09 Gary V. Vaughan <gary@gnu.org>
-
- Import the error and progname modules from CVS gnulib. Our old
- error.c subsumed the functionality of both, so a little adjustment
- was required to accomodate the split in sources. Also added more
- wrapper macros to choose between a system installed error.h or our
- shipped gnulib error module:
-
- * m4/error.c, m4/error.h: Removed.
- * m4/Makefile.am: Adjust.
- (pkgincdir): Removed. Use pkgincludedir instead.
- * m4/module.h, src/main.c: Don't include `m4/error.h'.
- * m4/system_.h (INCLUDE_ERROR_H): Add a substitution for suitable
- error.h.
- * gnulib/m4/progname.c: Imported from CVS gnulib.
- * gnulib/m4/progname.h: Ditto.
- * src/main.c: Adjust to use progname module.
- * gnulib/m4/error.c: Imported from CVS gnulib.
- * gnulib/m4/error_.h: Ditto.
- * gnulib/m4/Makefile.am: Build the error module into our libgnu.la
- if appropriate, and link a local error.h if the system version is
- missing.
- (libgnu_la_SOURCES) Add progname module sources.
- * gnulib/config/error.m4: Imported from CVS gnulib.
- * gnulib/config/strerror_r.m4: Ditto.
- * config/m4-error.c: New file. Wrap gnulib error.m4 but arrange
- to have ERROR_H for Makefile substitutions and tell system.h
- whether the system error.h should be used, or a locally installed
- version.
- * configure.ac (jm_PREREQ_ERROR): Replaced by a call to m4_ERROR.
-
-2003-09-09 Gary V. Vaughan <gary@gnu.org>
-
- * gnulib/m4/Makefile.am (MOSTLYCLEANFILES): Typo
- s/gettext_.h/gettext.h/.
-
- * bootstrap: Revert 2003-09-04 patch now that CVS autoconf and
- automake have been fixed.
-
- * config/m4-obstack.m4 (m4_FUNC_OBSTACK): D'oh! Now that we wrap
- gl_OBSTACK, which in turn calls AC_FUNC_OBSTACK, don't rerun bits
- of code originally snarfed from AC_FUNC_OBSTACK!!! While I'm here
- rename to m4_OBSTACK in light of wrapping gl_OBSTACK.
-
-2003-09-09 Gary V. Vaughan <gary@gnu.org>
-
- The gnulib obstack module requires the gnulib gettext module for
- systems that do not have GNU gettext installed. Because we use
- -Ignulib/m4 in our Makefiles it is not safe to drop gettext.h in
- that directory incase it clashes with the system gettext.h. This
- delta uses gettext_.h and extra rules in the Makefile to make a
- link to gettext.h when needed:
-
- * Makefile.am (auxdir): Removed. No longer used.
- * configure.ac (ac_aux_dir): Removed AC_SUBST. No longer used.
- (TIMESTAMP): List path to `mkstamp' literally, as ac_aux_dir has
- moved.
- (AC_CONFIG_LIBOBJ_DIR): Declare this for possible future single
- Makefile based build.
- (AC_CONFIG_AUX_DIR): Now we use gnulib/config where the majority
- of the macros are kept.
- * Makefile.am (ACLOCAL_MFLAGS): Search gnulib/config first.
- * configure.ac (AM_INIT_AUTOMAKE): Require 1.7a.
- * config/Makefile (ACLOCAL_MACROS): Removed. Automake 1.7a
- distributes these automatically.
- * config/regex.m4 (jm_WITH_REGEX): Fixed underquoting to prevent
- warning from automake-1.7a.
- * config/debug.m4 (M4_AC_CHECK_DEBUGGING): Renamed to
- m4_CHECK_DEBUGGING for consistency with gnulib prefixes. Changed
- all callers.
- * config/m4-obstack.m4 (M4_AC_FUNC_OBSTACK): Ditto
- wrt. m4_FUNC_OBSTACK.
- * config/stackovf.m4 (M4_AC_SYS_STACKOVF): Ditto
- wrt. m4_sys_STACKOVF.
- * config/gmp.m4 (_M4_AC_LIB_GMP, M4_AC_LIB_GMP): Ditto
- wrt. _m4_LIB_GMP, m4_LIB_GMP.
- (ac_gmp_save_LIBS, ac_cv_using_lib_gmp): Don't use autoconf's
- namespace. Renamed to m4_gmp_save_LIBS and m4_cv_using_lib_gmp
- respectively.
- * config/m4-gettext.m4: New file to set GETTEXT_H appropriately.
- * gnulib/m4/Makefile.am: Added a new block to make an appropriate
- gettext.h link on deficient systems.
- (pkginc_HEADERS): Mention $(GETTEXT_H).
- (EXTRA_HEADERS): Mention gettext.h.
- * gnulib/config/gettext_.h: New file from gnulib's gettext.h.
- * gnulib/config/codeset.m4, gnulib/config/gettext.m4,
- gnulib/config/glibc21.m4, gnulib/config/iconv.m4,
- gnulib/config/intdiv.m4, gnulib/config/inttypes-pri.m4,
- gnulib/config/inttypes.m4, gnulib/config/inttypes_h.m4,
- gnulib/config/isc-posix.m4, gnulib/config/lcmessage.m4,
- gnulib/config/lib-ld.m4, gnulib/config/lib-link.m4,
- gnulib/config/lib-prefix.m4, gnulib/config/nls.m4,
- gnulib/config/po.m4, gnulib/config/progtest.m4,
- gnulib/config/stdint_h.m4, gnulib/config/uintmax_t.m4,
- gnulib/config/ulonglong.m4: Imported from CVS gnulib.
-
-2003-09-05 Gary V. Vaughan <gary@gnu.org>
-
- We can't mirror the gnulib directory structure here, since we need
- to be able to eg. `#include <m4/obstack.h>' from our source files,
- which is much easier if the local obstack.h is created in a
- directory named m4. Rather than trying to symlink everything into
- the m4 directory, now we build a libtool convenience library from
- the sources we get from gnulib and link that with libm4.la:
-
- * gnulib/config/extensions.m4: Imported from CVS gnulib.
- * gnulib/config/unlocked-io.m4: Ditto.
- * gnulib/m4/unlocked-io.h: Ditto.
- * gnulib/m4/obstack.m4, gnulib/m4/onceonly_2_57.m4,
- gnulib/m4/stdbool.m4: All moved to gnulib/config directory.
- * gnulib/lib/obstack.c, gnulib/lib/obstack_.h,
- gnulib/lib/stdbool_.h: All moved to gnulib/m4 directory.
- * m4/strtol.c, m4/xmalloc.c, m4/xstrdup.c, m4/xstrzdup.c: Ditto.
- * m4/Makefile.am: Adjust.
- * gnulib/Makefile.am (EXTRA_DIST): Name just the additional gnulib
- macros we redistribute.
- * gnulib/m4/Makefile.am: New file. Build libgnu.la convenience
- library among others.
- (GNULIB_SRCS, GNULIB_MACROS): Removed.
- * Makefile.am (ACLOCAL_AMFLAGS): Adjust.
- * config/m4-obstack.m4: Adjust.
- * po/POTFILES.in: Adjust.
- * configure.ac: Reformatting. Call newly imported gnulib macros.
- * m4/builtin.c, m4/macro.c, m4/module.c, m4/utility.c: Removed
- bogus calls of `#include "m4.h"'.
- * Makefile.am: INCLUDES has been deprecated in favour of
- AM_CPPFLAGS.
- * m4/Makefile.am: Ditto.
- * modules/Makefile.am: Ditto.
- * src/Makefile.am: Ditto.
-
-2003-09-05 Gary V. Vaughan <gary@gnu.org>
-
- * config/Makefile.am: Reverting yesterdays patch for VPATH builds.
-
-2003-09-04 Gary V. Vaughan <gary@gnu.org>
-
- Migrate the obstack support into the gnulib directories for easy
- synchronisation with upstream files in gnulib:
-
- * config/gnu-obstack.m4: Moved from here...
- * config/m4-obstack.m4: ...to here.
- * config/Makefile.am (SPECIFIC_MACROS): Adjust.
- * m4/obstack.c, m4/obstack_.h: Moved from here...
- * gnulib/obstack.c, gnulib/obstack.h: ...to here.
- * po/POTFILES.in: Adjust.
- * gnulib/Makefile.am (GNULIB_SRCS, GNULIB_MACROS): Adjust.
- * m4/Makefile.am: Add a whole new section to link the obstack
- sources from the gnulib tree if necessary.
- * gnulib/m4/onceonly_2_57.m4, gnulib/m4/obstack.m4: New macros
- from gnulib.
- * config/m4-obstack.m4: Rewrite as a wrapper for
- gnulib/m4/obstack.m4.
-
-2003-09-04 Gary V. Vaughan <gary@gnu.org>
-
- GNU M4 currently builds with a number of files adapted from
- upstream sources. Recently the gnulib project on savannah.gnu.org
- has pulled together a great many of these externally maintained
- files. This delta is the beginnings of isolating those files
- maintained in gnulib to make it easy to synchronise M4 with the
- upstream files prior to releases.
-
- * Makefile.am (ACLOCAL_AMFLAGS): Mention gnulib/m4 macro
- directory.
- (SUBDIRS): Added new gnulib subdirectory.
- * configure.ac (AC_CONFIG_FILES): Add new gnulib tree Makefiles.
- * config/stdbool.m4: Moved from here...
- * gnulib/m4/stdbool.m4: ...to here.
- * m4/stdbool_.h: Moved from here...
- * gnulib/lib/stdbool_.h: ...to here.
- * gnulib/Makefile.am: New file. Make sure the gnulib tree is
- distributed.
- * m4/Makefile.am: Adjust gnulib/modules/stdbool:Makefile.am based
- code to work with new stdbool_.h location.
- (gnulib_srcdir): New.
-
-2003-09-04 Gary V. Vaughan <gary@gnu.org>
-
- * config/Makefile.am (MAINTAINERCLEANFILES, ACLOCAL_MACROS)
- (STANDARD_TOOLS, SPECIFIC_MACROS): Needed `$(srcdir)/' for VPATH
- builds to work.
- (SPECIFIC_TOOLS): New variable. Moved mkstamp to here.
- (EXTRA_DIST): Use it.
-
- * bootstrap: CVS autoreconf leaves file droppings. Remove
- aclocal.m4t incase autoreconf doesn't.
-
-2003-08-29 Gary V. Vaughan <gary@gnu.org>
-
- * m4/gnu-obstack.h: Updated from CVS gnulib. For consistency with
- the other gnulib imports, renamed to m4/obstack_.h.
- * m4/obstack.c: Updated from CVS gnulib.
- * m4/Makefile.am (EXTRA_HEADERS): Adjust.
- * config/gnu-obstack.m4 (M4_AC_FUNC_OBSTACK): Merge in additional
- header tests from gnulib obstack module. AC_CONFIG_LINKS knows
- about vpath already, and $top_srcdir upsets CVS Automake, so the
- $top_srcdir reference was removed.
-
- * m4/system-h.in: For consistency with the gnulib imports, renamed
- to m4/system_.h.
- * m4/Makefile (EXTRA_HEADERS): Adjust.
- * configure.ac (AC_CONFIG_FILES): Adjust.
-
- * m4/stdbool_.h: New file from gnulib for systems without their
- own.
- * m4/Makefile.am: Add snippets from gnulib for C99 bool support.
- * config/stdbool.m4: New file. Macros from gnulib for same.
- * configure.ac: Use it.
-
-2003-08-27 Gary V. Vaughan <gary@gnu.org>
-
- * config/debug.m4: `perl -pi.bak -e 's/(Copyright) (\d)/$1 (C) $2/g'`
- * config/gmp.m4: Ditto.
- * config/gnu-obstack.m4: Ditto.
- * config/stackovf.m4: Ditto.
- * m4/builtin.c: Ditto.
- * m4/debug.c: Ditto.
- * m4/error.c: Ditto.
- * m4/error.h: Ditto.
- * m4/gnu-obstack.h: Ditto.
- * m4/hash.c: Ditto.
- * m4/hash.h: Ditto.
- * m4/input.c: Ditto.
- * m4/m4.c: Ditto.
- * m4/m4module.h: Ditto.
- * m4/m4private.h: Ditto.
- * m4/macro.c: Ditto.
- * m4/module.c: Ditto.
- * m4/obstack.c: Ditto.
- * m4/output.c: Ditto.
- * m4/path.c: Ditto.
- * m4/regex.c: Ditto.
- * m4/regex.h: Ditto.
- * m4/strtol.c: Ditto.
- * m4/symtab.c: Ditto.
- * m4/syntax.c: Ditto.
- * m4/utility.c: Ditto.
- * m4/xmalloc.c: Ditto.
- * m4/xstrdup.c: Ditto.
- * m4/xstrzdup.c: Ditto.
- * modules/evalparse.c: Ditto.
- * modules/format.c: Ditto.
- * modules/gnu.c: Ditto.
- * modules/import.c: Ditto.
- * modules/load.c: Ditto.
- * modules/m4.c: Ditto.
- * modules/m4.h: Ditto.
- * modules/modtest.c: Ditto.
- * modules/mpeval.c: Ditto.
- * modules/perl.c: Ditto.
- * modules/shadow.c: Ditto.
- * modules/stdlib.c: Ditto.
- * modules/time.c: Ditto.
- * modules/traditional.c: Ditto.
- * src/freeze.c: Ditto.
- * src/getopt.c: Ditto.
- * src/getopt1.c: Ditto.
- * src/m4.h: Ditto.
- * src/main.c: Ditto.
- * src/stackovf.c: Ditto.
-
- * config/gmp.m4 (M4_AC_LIB_GMP): Use AC_INCLUDES_DEFAULT:
- ac_default_headers is an autoconf internal variable.
- * config/gnu-obstack.m4 (M4_AC_FUNC_OBSTACK): Ditto.
- * config/stackovf.m4 (M4_AC_SYS_STACKOVF): Ditto.
-
- * configure.ac (AC_CONFIG_FILES): Add tests/atlocal.
- * tests/Makefile.am (TESTS_ENVIRONMENT): Revert the 2003-08-14
- delta.
-
-2003-08-15 Gary V. Vaughan <gary@gnu.org>
-
- * configure.ac (AC_HEADER_STDBOOL, INCLUDE_STDBOOL_H): Check for
- C99 bool.
- * system-h.in (m4_boolean): Removed in favour of using C99 bool if
- possible or faking one with a typedef. Changed all callers.
-
-2003-08-15 Gary V. Vaughan <gary@gnu.org>
-
- Still cleaning up the users' module API, by taking out the stuff
- that isn't used by any existing modules, and moving specialised
- functions out of libm4 and into the module they are used by.
-
- * m4/m4module.h (m4_skip_space): No need to export this. Moved...
- * m4/utility.c (m4_skip_space): ...to here the home of its only
- use, made static and renamed to `skip_space'. Changed all
- callers.
- * m4/m4module.h (m4_expand_ranges): Removed prototype.
- * m4/utility.c (m4_expand_ranges): Moved definition from here...
- * modules/m4.c (m4_expand_ranges): ...to here, and exported using
- ltdl.
- * modules/m4.h (m4_expand_ranges_func): For lt_dlsym import
- casting .
- * modules/gnu.c (builtin_syntax): Import and use in this
- builtin implementation.
- * m4/m4module.h (M4_DEBUG_PRINT1, M4_DEBUG_PRINT2, M4_DEBUG_PRINT3):
- Not used. Deleted.
- * m4/macro.c (trace_flush): Except here where the macro is now
- manually inlined.
- * m4/m4module.h (M4_DEBUG_MESSAGE, M4_DEBUG_MESSAGE1)
- (M4_DEBUG_MESSAGE2, M4_DEBUG_MESSAGE3): Only used internally, so
- moved...
- * m4/m4private.h (M4_DEBUG_MESSAGE, M4_DEBUG_MESSAGE1)
- (M4_DEBUG_MESSAGE2, M4_DEBUG_MESSAGE3): ...to here.
-
-2003-08-14 Gary V. Vaughan <gary@gnu.org>
-
- * config/gnu-obstack.m4 (M4_AC_FUNC_OBSTACK): Use the interrim new
- compiler based AC_CHECK_HEADER that was introduced in
- autoconf-2.56.
- * config/stackovf.m4 (M4_AC_SYS_STACKOVF): Ditto.
- * config/gmp.m4 (AC_LIB_GMP): Ditto. And renamed to M4_AC_LIB_GMP.
- * configure.ac: Use renamed M4_AC_LIB_GMP.
-
- * config/debug.m4 (M4_AC_CHECK_DEBUGGING): Don't AC_REQUIRE a
- macro that requires arguments! This stops the shell's bad
- substitution error at configure time.
-
- * tests/Makefile.am (TESTS_ENVIRONMENT): Now we can pass make
- variables to the testsuite shell. Set the value of USE_GMP so
- that the gmp test will run!
- (check-local, clean-local): Use the TESTS_ENVIRONMENT variable.
-
-2003-08-11 Gary V. Vaughan <gary@gnu.org>
-
- Libltdl already has an excellent mechanism for accessing C symbols
- in modules. Lets use that! Remove all the exporting cruft and
- just use lt_dlsym in conjunction with a few conventions to
- simplify module writers' jobs. Also removed the table address
- caching code and otherwise simplified the module loader quite a
- bit. To access exported symbols in other modules, first the
- exporting module must name the symbols <modname>_LTX_<symname>,
- and the importing module must define a function type called
- <symname>_func. The importer then adds
- M4_MODULE_IMPORT(<modname>, <symname>) at the top of any function
- that wishes to call out to the exported functions. Care must be
- taken that <symname> is non-NULL in the importing module incase
- M4_MODULE_IMPORT fails, but otherwise it can be called as if the
- definition was in the importers source. Study
- `modules/{gnu.c,m4.{c,h}' for a model example. At the moment,
- m4_module_import will attempt to automatically load a module
- required for symbol access if it is not loaded already.
-
- * TODO: Removed the items fixed in this delta.
- * m4/ltdl.c (lt_dlhandle_find): New function to find a handle by
- module name.
- * m4/ltdl.h (lt_dlhandle_find): Declare it.
- * m4/module.c (m4_module_unload): Use it.
- * src/freeze.c (reload_frozen_state): Ditto.
- * m4/m4module.h (m4_export): Deleted. Removed all references.
- (M4_MODULE_IMPORT): New user convenience macro for importing
- arbitrary symbols from other modules.
- * m4/module.c (m4_module_import): New function to service
- M4_MODULE_IMPORT macro.
- (module_data): Removed. Looking up the tables on demand with
- lt_dlsym, rather than caching their addresses here simplifies the
- code substantially.
- (m4_get_module_builtin_table, m4_get_module_macro_table):
- Removed. Changed all callers.
- (set_module_macro_table, set_module_builtin_table): Renamed to
- install_macro_table and install_builtin_table respectively, and
- simplified now that the cache is no more.
- * modules/gnu.c (builtin_symbols): Use this new mechanism to
- import m4_dump_symbols from the m4 module.
- (builtin_esyscmd): Likewise for m4_set_sysval and
- m4_sysval_flush.
- * modules/m4.c (m4_export_table): Removed. Functions are
- addressed with the new mechanism which doesn't need this.
- (m4_set_sysval): New exported accessor function to prevent
- problems with variable access on inferior architectures.
- * modules/m4.h (m4_sysval_flush_func, m4_set_sysval_func)
- (m4_dump_symbols_func): Typedefs required by M4_MODULE_IMPORT so
- that we can have some type safety.
- * modules/modtest.c (export_test): C level exported function for
- testing the new import mechanism.
- * modules/import.c: New file for the import end of the test.
- * modules/Makefile.am (pkglibexec_LTLIBRARIES): Added import.la.
- * tests/modules.at: New test cases for intermodule symbol
- importing.
-
-2003-08-07 Gary V. Vaughan <gary@gnu.org>
-
- * m4/m4module.c (m4_string): Moved from here...
- * m4/m4private.c (m4_string): ...to here.
-
- * m4/utility.c (dumpdef_cmp): Removed stale declaration.
-
-2003-07-29 Gary V. Vaughan <gary@gnu.org>
-
- * m4/m4module.h (M4_DEFAULT_NESTING_LIMIT): This value is
- already available to module writers through
- m4_{get,set}_nesting_limit_opt(), so moved from here...
- * m4/m4.c (DEFAULT_NESTING_LIMIT): ...to here and renamed.
- (m4_create): Use it.
-
-2003-07-28 Gary V. Vaughan <gary@gnu.org>
-
- Aside from auditing path.c for m4module.h api obfuscation, this
- delta introduces the concept of private struct members in opaque
- data types to GNU m4: See the STYLE file for details.
-
- * TODO: Remind ourselves that a rewrite of path.c is needed.
- * m4/m4module.h (m4_search_path, struct m4_search_path_info):
- Moved from here...
- * m4/m4private.h (m4__search_path, m4__search_path_info): ...to
- here and renamed. These type definitions are for internal api use
- only. Changed all callers.
- * m4/m4module.h (m4_search_path_env_init, m4_search_path_add):
- Moved from here...
- * m4/path.c (search_path_env_init, search_path_add): ...to here
- and renamed. These calls were never used outside this file.
- Changed all callers.
- (dirpath): Moved functionality of this static declaration...
- * m4/m4private.h (struct m4): ...to this new internal only
- search_path field. Changed all callers.
- (m4__get_search_path): Added new internal api accessor.
- * m4/path.c (m4_search_path_info_new): Removed. Not used.
- (m4_include_init): Removed...
- * m4/m4.c (m4_create): ...because the new m4 field is now
- initialised here.
- (m4_delete): Recycle search_path memory.
- * src/main.c (main): Don't call m4_include_init now that it's
- gone!
- * doc/STYLE: Document convention for private fields in opaque
- ADTs.
-
-2003-07-24 Gary V. Vaughan <gary@gnu.org>
-
- Sometimes exporting the address of a symbol from a module isn't
- enough for other modules to call that symbol correctly. If
- custom data types are used for function parameters, they need to
- be known to the caller. This change introduces the concept of
- $(prefix)/include/modules/$(modulename).h to declare those
- structures. Also we move m4_dump_symbols from libm4 to the m4
- module to show this concept in action.
-
- * m4/m4module.h (m4_dump_symbol_data): Moved from here...
- * modules/m4.h (m4_dump_symbol_data): ...to this new file for
- exporting data structures from modules/m4.c.
- * modules/m4.c, modules/gnu.c: Include it.
- * modules/Makefile.am (pkgmodinc_HEADERS): Install it.
- * m4/m4module.h (m4_dump_symbol_CB, m4_dump_symbols): Removed
- prototypes.
- * m4/utility.c (dumpdef_cmp, m4_dump_symbol_CB, m4_dump_symbols):
- Moved from here...
- * modules/m4.c (dumpdef_cmp_CB, dump_symbol_CB, m4_dump_symbols):
- ...to here, with slight renaming.
- (m4_export_table): Prototype and add m4_dump_symbols.
- * m4/symtab.c (m4_is_symbol_value_void): Needed for an external
- definition of m4_dump_symbols.
- * m4/m4module.h (m4_is_symbol_value_void): Prototype it.
- * m4/m4private.h (m4_is_symbol_value_void): Fast macro version.
-
-2003-07-24 Gary V. Vaughan <gary@gnu.org>
-
- Create an export table in modules/m4.c in readiness for beefing up
- the module loader to track module exports and imports.
-
- * m4/m4module.h (m4_debug_flush_files): Removed prototype.
- * m4/debug.c (m4_debug_flush_files): Moved...
- * modules/m4.c (m4_sysval_flush): ...to here and renamed.
- * modules/gnu.c (builtin_esysval): Use it.
- * m4/m4module.h (m4_export): New type for declaring module symbols
- for export.
- * modules/m4.c (m4_export_table): List symbols exported from this
- module for use by other modules.
-
-2003-07-24 Gary V. Vaughan <gary@gnu.org>
-
- An experiment: There is loads of code in libm4 which should be in
- the m4 module, but is also used by another module. Just because
- some linkers won't cope with calls across dynamic runtime loaded
- objects I initially left the code in libm4. It will tidy the
- module api immensely if this code moves to the right place, I just
- need to remember to invent a suitable calling mechanism at some
- point. For now, only modules that are statically linked and
- preloaded will get this treatment, so the only platforms that will
- break are those that require all symbols to be resolved at link
- time.
-
- * TODO: Reminder that what I am doing could reduce portability
- unless I do something more robust later.
- * m4/m4module.h (m4_sysval): No longer exported from libm4.
- * m4/utility.c (m4_sysval): No longer declared in libm4.
- * modules/Makefile.am: Reformatting.
- * modules/m4.c (m4_sysval): Declare it at place of use.
- * modules/gnu.c (m4_sysval): Import it for use in esyscmd.
-
-2003-07-23 Gary V. Vaughan <gary@gnu.org>
-
- * m4/m4module.h: Reformatting and rearranging lines a bit.
- (m4_obstack): Save typing by typedefing `struct obstack'. Changed
- all users.
- (m4_call_macro, m4_expand_input): Renamed...
- (m4_macro_call, m4_macro_expand_input): ...to these. Changed all
- callers.
- (m4_expansion_level, m4_process_macro): Moved...
- * m4/macro.c (expansion_level, process_macro): ...to here, and
- made static.
-
- * m4/m4module.h (program_name): Not used by modules at all, so
- moved...
- * src/main.c (program_name): ...to here.
- (print_program_name): Renamed...
- (print_program_name_CB): ...to conform to the STYLE guide.
-
-2003-07-23 Gary V. Vaughan <gary@gnu.org>
-
- More refactoring of the m4module.h API. Replace #defines with an
- enum, and move non-public functions out of the public API.
-
- * m4/debug.c (stdarg.h, varargs.h): Remove variadic header
- inclusion.
- * m4/macro.c (stdarg.h): Add ANSI C variadic header.
- * m4/debug.c (m4_debug, trace): Moved...
- * m4/m4private.h (struct m4): ...to fields of this struct.
- (m4_get_debug_file, m4_get_trace_messages): New fast access macros
- for the new fields.
- * m4/debug.c (m4_debug_init, m4_debug_exit): Removed functions...
- * src/main.c (m4_debug_init, m4_debug_exit): ...invocations...
- * m4/m4.c (m4_create, m4_delete): ...and handled here instead.
- * m4/m4module.h (m4_context_field_table): Add entries for new
- debug_file and trace_messages fields.
- (M4_DEBUG_TRACE_ARGS, M4_DEBUG_TRACE_EXPANSION)
- (M4_DEBUG_TRACE_QUOTE, M4_DEBUG_TRACE_ALL, M4_DEBUG_TRACE_LINE)
- (M4_DEBUG_TRACE_FILE, M4_DEBUG_TRACE_PATH, M4_DEBUG_TRACE_CALL)
- (M4_DEBUG_TRACE_INPUT, M4_DEBUG_TRACE_CALLID)
- (M4_DEBUG_TRACE_VERBOSE): Replaced #defines with an enum.
- (m4_is_debug_bit): New macro to simplfy checks against the debug
- bits above.
- (m4_trace_format, m4_trace_header, m4_trace_flush)
- (m4_trace_prepre, m4_trace_pre, m4_trace_post): Removed
- prototypes.
- * m4/debug.c (m4_trace_format, m4_trace_header, m4_trace_flush)
- (m4_trace_prepre, m4_trace_pre, m4_trace_post): Moved...
- * m4/macro.c (trace_format, trace_header, trace_flush)
- (trace_prepre, trace_pre, trace_post): ...to these newly static
- functions, since they are only ever used from this file. Changed
- all callers.
-
-2003-07-17 Gary V. Vaughan <gary@gnu.org>
-
- Change the macros for checking syntax so that matching against
- multiple possible syntax classes can be done with a single
- comparison some of the time. The various classes are now bits of
- an int that can be checked with bitwise logic operators.
-
- * m4/m4module.h (M4_SYNTAX_IGNORE, M4_SYNTAX_OTHER)
- (M4_SYNTAX_SPACE, M4_SYNTAX_OPEN, M4_SYNTAX_CLOSE, M4_SYNTAX_COMMA)
- (M4_SYNTAX_DOLLAR, M4_SYNTAX_ACTIVE, M4_SYNTAX_ESCAPE)
- (M4_SYNTAX_ASSIGN, M4_SYNTAX_ALPHA, M4_SYNTAX_NUM)
- (M4_SYNTAX_LQUOTE, M4_SYNTAX_RQUOTE, M4_SYNTAX_BCOMM)
- (M4_SYNTAX_ECOMM): Replaced #defines with an enum.
- (M4_SYNTAX_ALNUM): Removed. Changed all callers.
- (M4_IS_IGNORE, M4_IS_OTHER, M4_IS_SPACE, M4_IS_OPEN, M4_IS_CLOSE)
- (M4_IS_COMMA, M4_IS_DOLLAR, M4_IS_ACTIVE, M4_IS_ESCAPE)
- (M4_IS_ASSIGN, M4_IS_ALPHA, M4_IS_NUM, M4_IS_LQUOTE, M4_IS_RQUOTE)
- (M4_IS_BCOMM, M4_IS_ECOMM, M4__IS_STRING, M4_IS_IDENT): Removed.
- Replace all calls with invocations of these...
- (m4_is_syntax, m4_has_syntax): ...New macros.
- * src/freeze.c (produce_syntax_dump): Remove mask argument, which
- is no longer required with new macros. Changed all callers.
-
-2003-07-15 Gary V. Vaughan <gary@gnu.org>
-
- * m4/input.c (CHAR_EOF, CHAR_BUILTIN, CHAR_RETRY): These token
- values are returned as part of the internal interface, so they
- need to be moved...
- * m4/private.h: ...to here.
- * m4/macro.c (expand_token): Check for out of range
- m4_peek_input() results before looking up in the syntax table.
- (collect_arguments): Ditto.
-
- * NEWS: Note `$' syntax class.
-
-2003-07-08 Paul Eggert <eggert@twinsun.com> and
- Gary V. Vaughan <gary@gnu.org>
-
- Conform to POSIX if the POSIXLY_CORRECT environment is set.
- --traditional `define' now smashes all the definitions.
-
- * NEWS: Explain this.
- * doc/m4.texinfo (Defn): `defn' takes any number of arguments.
- (Extensions): Explain that extensions that are incompatible with
- POSIX are disabled if POSIXLY_CORRECT is set.
- (Incompatibilities): Remove.
- (Define, Other Incompat): Explain difference
- between GNU and POSIX behavior of define, pushdef, popdef.
- * m4/m4.c (m4_get_posixly_correct_opt): New undef.
- * m4/m4module.h (m4_context_opt_bit_table): Add POSIXLY_CORRECT entry.
- * m4/m4private.h (M4_OPT_POSIXLY_CORRECT_BIT): New macro.
- (m4_get_posixly_correct_opt): New macro.
- * m4/m4macro.c (m4_process_macro): Disable $10, $abc etc. if
- POSIXLY_CORRECT.
- * modules/m4.c (builtin_functions): defn now takes any number of args.
- (builtin_define): Smash all the definitions if
- POSIXLY_CORRECT.
- (builtin_defn)): Allow any number of arguments.
- (builtin_undivert): Do not allow nonnumeric arguments
- if POSIXLY_CORRECT.
- * src/main.c (main): Set posixly-correct behavior if either
- POSIXLY_CORRECT is set, or if -G is given.
- * tests/builtins.at: New test for smashed definitions.
-
-2003-06-27 Gary V. Vaughan <gary@gnu.org>
-
- * doc/m4.texinfo (Changesyntax): Document Dollar syntax class.
- * m4/m4module.h (M4__SYNTAX_STRING): New syntax class. Be careful
- not to slow the parser down.
- (M4__IS_STRING): New macro to test string syntax class membership.
- * m4/syntax.c: Adjust docucomment.
- (m4_syntax_create): Add a default M4_SYNTAX_DOLLAR element.
- (m4_syntax_code): Translate `$' -> M4_SYNTAX_DOLLAR.
- * m4/input.c (init_builtin_token): Comment typo.
- (m4__next_token): Comment typo.
- Accept M4_SYNTAX_DOLLAR items into M4_TOKEN_STRING type tokens
- by using the new M4__IS_STRING macro.
- * m4/macro.c (m4_process_macro): Use M4_IS_DOLLAR to test for
- variable references in macro expansions.
-
- * doc/m4.texinfo (Eregexp and Regexp): Typo.
- (Epatsubst and Patsubst): Typo.
- (Eval): Typo.
-
-2003-06-26 Gary V. Vaughan <gary@gnu.org>
-
- Move the global variables that pertain to syntax to a new `struct
- m4_syntax_table', and then add one of these to `struct m4'. The
- ripple effect through the code to both change formerly global
- references, and make sure a suitable context is available in
- lexical scope is disproportionately large compared to the size of
- the change proper. This change is a large part of decoupling
- syntax.c from the rest of the code that uses it.
-
- * m4/m4private.h (struct m4): Add a syntax field.
- * m4/m4.c (m4_create): Initialise it,
- (m4_delete): Recycle it.
- (m4_get_symtab): Remove hand coded version...
- (m4_get_symbol_table): ...and generate this with cpp. Changed all
- callers.
- * m4/m4module.h (m4_context_field_table): Add an extra field so we
- can generate m4_get_symbol_table. Add a new row for
- m4_get_syntax_table.
- (M4SYNTAX): Syntactic sugar for module writers.
- (m4_symtab): Renamed to m4_symbol_table. Changed all callers.
- (m4_syntax_table): New home for syntax related formerly global
- variables.
- * m4/m4private.h (struct m4_syntax_table): Define it.
- * m4/input.c (m4_input_init): Initialisation of these formerly
- global variables moved...
- * m4/syntax.c (m4_syntax_create): ...to here.
- * m4/input.c (m4_input_exit): And similarly, recycling of the
- memory used by those values moved...
- * m4/syntax.c (m4_syntax_delete): ...to here.
- * m4/m4module.h (DEF_LQUOTE, DEF_RQUOTE, DEF_BCOMM, DEF_ECOMM):
- Moved to m4/m4private.h.
- * m4/syntax.c (m4_get_syntax_lquote, m4_get_syntax_rquote)
- (m4_get_syntax_bcomm, m4_get_syntax_ecomm)
- (m4_is_syntax_single_quotes, m4_is_syntax_single_comments)
- (m4_is_syntax_macro_escaped): New accessors for m4_syntax_table
- objects. Changed all callers that used to directly access the
- global equivalents.
- (m4__single_quotes, m4__single_comments, m4__use_macro_escape):
- Removed and incorporated into m4_syntax_table structure.
- * m4/utility.c (lquote, rquote, bcomm, ecomm): Ditto.
- * m4/syntax.c (m4_set_syntax): Now returns an error status,
- instead of requiring a `struct m4' to generate its own errors.
- Changed all callers.
- * src/main.c (main): Now that the syntax table is initialised as
- part of m4_create, we have to manually wipe the syntax entries if
- we are about to read a frozen file.
-
-2003-06-26 Gary V. Vaughan <gary@gnu.org>
-
- * doc/STYLE: Added notes on callback naming schemes.
-
- * m4/module.c (m4_set_module_macro_table)
- (m4_set_module_builtin_table): Declarations weren't changed when
- definitions were renamed on 2003-06-19.
-
- * m4/hash.c (m4_hash_resize): ifdefed out. This function is
- neither used nor particularly appropriate since it exposes the
- internal workings of the hash module. I haven't yet decided
- whether to remove it entirely.
-
-2003-06-20 Gary V. Vaughan <gary@gnu.org>
-
- Two related changes, and a huge knockon effect throughout the
- source: Moved the option variables out of global space and into
- `struct m4'; made `m4_symtab' a real datatype, so that its api
- is not marred passing `struct m4' around just so it can decide
- whether to keep traced symbol names or not. Added setters and
- getters for the formerly global option variables, and obviously
- changed a vast number of functions to take a `struct m4' and use
- the getter funcs to find option values.
-
- * m4/utility.c (interactive, sync_output, debug_level)
- (no_gnu_extensions, prefix_all_builtins, suppress_warnings)
- (max_debug_argument_length, warning_status, nesting_limit)
- (discard_comments): Removed.
- * m4/m4module (warning_status, no_gnu_extensions, nesting_limit)
- (debug_level, max_debug_argument_length, prefix_all_builtins)
- (suppress_warnings, discard_comments, interactive, sync_output):
- Removed from here...
- * m4/m4private.h (struct m4): ...and equivalent fields added to
- this structure.
- (m4_get_warning_status_opt, m4_get_no_gnu_extensions_opt)
- (m4_get_nesting_limit_opt, m4_get_debug_level_opt)
- (m4_get_max_debug_arg_length_opt, m4_get_prefix_builtins_opt)
- (m4_get_suppress_warnings_opt, m4_get_discard_comments_opt)
- (m4_get_interactive_opt, m4_get_sync_output_opt): Fast access
- macros for the new fields.
- * m4/m4module.h (m4_context_field_table)
- (m4_context_opt_bit_table): Helper macros used to generate
- prototypes, setters and getters for new option fields
- consistently.
- * m4/m4.c (m4_get_warning_status_opt, m4_get_no_gnu_extensions_opt)
- (m4_get_nesting_limit_opt, m4_get_debug_level_opt)
- (m4_get_max_debug_arg_length_opt, m4_get_prefix_builtins_opt)
- (m4_get_suppress_warnings_opt, m4_get_discard_comments_opt)
- (m4_get_interactive_opt, m4_get_sync_output_opt)
- (m4_set_warning_status_opt, m4_set_no_gnu_extensions_opt)
- (m4_set_nesting_limit_opt, m4_set_debug_level_opt)
- (m4_set_max_debug_arg_length_opt, m4_set_prefix_builtins_opt)
- (m4_set_suppress_warnings_opt, m4_set_discard_comments_opt)
- (m4_set_interactive_opt, m4_set_sync_output_opt): Addressable
- setter and getter functions generated by cpp from
- m4_context_field_table and m4_context_opt_bit_table, exported as
- part of the module api. Changed all callers.
- * m4/symtab (struct m4_symtab): Used as the concrete type for
- m4_symtab now.
- (m4_symtab_create): Allocate and initialise a new struct.
- (m4_symtab_apply): New function that works like m4_hash_apply, but
- with different callbacks specific to symbol tables. Changed all
- callers.
- (symbol_destroy, arg_destroy, arg_copy): Renamed
- symbol_destroy_CB, arg_destroy_CB, arg_copy_CB to remind me that
- they have unused parameters for a reason!
- (dump_symbol_CB): New callback to dump the contents of a single
- symbol.
- (symtob_dump): Rewritten in terms of dump_symbol_CB.
- * m4/utility.c (m4_dump_symbol): Renamed to m4_dump_symbol_CB.
- Changed all callers.
- * m4/m4.c (m4_create): By default point the `nuke_trace_bit' field
- of the contained `m4_symtab' at the `no_gnu_extensions' field.
- Although I'm not convinced these semantics are correct, they are
- at least consistent with how things were before this delta. Also
- set the default nesting limit to M4_DEFAULT_NESTING_LIMIT.
-
-2003-06-19 Gary V. Vaughan <gary@gnu.org>
-
- Tie down the interface to libm4 some more. Make more structures
- opaque to modules by moving them to m4private.h, and writing
- setters and getters. To win back the speed penalty for doing this
- also wrote macroized versions that do know about structure layout
- in m4private.h and #include that file into modules when NDEBUG is
- defined at compile time. There are still some accessor macros in
- m4private.h that need to go, but that is not necessary to clean
- the module api up.
-
- * m4/m4module.h (m4_symbol_type): Moved...
- * m4/m4private.h (m4__symbol_type): ...to here.
- * m4/symtab.c (m4_get_symbol_value, m4_get_symbol_traced)
- (m4_set_symbol_traced, m4_set_symbol_name_traced)
- (m4_is_symbol_text, m4_is_symbol_func, m4_get_symbol_text)
- (m4_get_symbol_func, m4_symbol_value_create)
- (m4_symbol_value_delete, m4_set_symbol_value_text)
- (m4_set_symbol_value_func): New exported api to symbols.
- (m4_get_symbol_value_type): Replaced by m4_is_symbol_value_text
- and m4_is_symbol_value_func.
- * m4/m4module.h: Prototype these guys.
- * m4/module.c (m4_set_module_macro_table)
- (m4_set_module_builtin_table): Make these static, there is no
- reason to pollute the api with them.
- * m4/m4private.h: Reformatting.
- (m4_get_symtab): Only define when NDEBUG is defined.
- (m4_get_symbol_value, m4_get_symbol_traced)
- (m4_set_symbol_traced, m4_set_symbol_name_traced)
- (m4_is_symbol_text, m4_is_symbol_func, m4_get_symbol_text)
- (m4_get_symbol_func, m4_symbol_value_create)
- (m4_symbol_value_delete, m4_set_symbol_value_text)
- (m4_set_symbol_value_func): Macro implementations of the new
- functions when NDEBUG is defined.
- (SYMBOL_TRACED, SYMBOL_VALUE, SYMBOL_TYPE, SYMBOL_TEXT)
- (SYMBOL_FUNC, VALUE_TYPE, VALUE_TEXT, VALUE_FUNC): Removed.
- Superceded by the above. All callers changed.
- (M4ARG): Removed. This is no longer different to the
- m4/m4module.h definition.
- * modules/gnu.c, modules/m4.c: Only include m4private.h when
- NDEBUG is defined. That way we exercise the same (albeit slower)
- api that external modules must use.
-
-2003-06-18 Gary V. Vaughan <gary@gnu.org>
-
- Renamed some of the types and their accessors to make more sense.
- Now we have a SYMTAB in which we store SYMBOLs, and each SYMBOL
- has a stack of SYMBOL_VALUEs.
-
- * m4/m4module.h (m4_token, m4_get_token_type, m4_get_token_text)
- (m4_get_token_func, m4_token_copy): Renamed to m4_symbol_value,
- m4_get_symbol_value_type, m4_get_symbol_value_text,
- m4_get_symbol_value_func and m4_symbol_value_copy respectively.
- Changed all callers.
- (m4_symbol_type): s/M4_TOKEN_/M4_SYMBOL_/
- (m4_get_token_type): Renamed
- * m4/input.c (m4_next_token): Renamed to m4__next_token, and moved
- to the internal api.
- * m4/m4private.h: s/TOKEN_ARG_/SYMBOL_ARG_/
- s/TOKEN_/VALUE_/
- (m4__symtab_init, m4__symtab_exit): Removed prototypes.
- (m4_token_arg): Renamed to m4_symbol_arg. Changed all callers.
- (m4__token_type): Moved here from m4module.h.
- (m4__next_token): Renamed from m4_next_token.
- * m4/symtab.c: Removed some of the parameterised macro support
- functions for modularisation later.
- (m4_token_copy): Renamed to m4_symbol_value_copy, and use new
- m4_hash_dup to perform a true deep copy of the SRC.
- (arg_copy): Callback for m4_symbol_value_copy.
- * utility.c (m4_token_get_type, m4_token_text, m4_token_func):
- Renamed to m4_get_symbol_value_type, m4_get_symbol_value_text and
- m4_get_symbol_value_func. Changed all callers.
-
-2003-06-18 Gary V. Vaughan <gary@gnu.org>
-
- Tidy up style of hash.[ch] in accordance with doc/STYLE.
-
- * m4/hash.c: Internal symbol renaming and formatting.
- (m4_hash_dup): New function to facilitate deep copies of hash
- tables.
- (m4_hash_apply_func): Returns a void* now, which is a richer type
- for returning exceptions (NULL means keep going).
- (m4_hash_apply): Ditto.
- * m4/hash.h: Declare exported symbols with an explicit extern.
- Reformated.
-
-2003-06-17 Gary V. Vaughan <gary@gnu.org>
-
- Still refactoring furiously. This delta represents a change in
- semantics to symtab.c. Instead of building temporary m4_tokens
- in the caller, and copying fields in the methods, we now create
- the actual m4_token for hashing in the caller so the methods just
- slot them in directly. Also, this means that we don't lookup a
- symbol and get back an allocated but VOID token to copy fields
- into, we create the token we want to push and pass that to
- m4_symbol_define or m4_symbol_pushdef. And that's it. There are
- a few other small changes to stop knowledge of the implementation
- of symtab.c leaking out into other files.
-
- * m4/macro.c (expand_argument): Comment typo corrected.
- * m4/symtab.c (symtab_fetch): New function to fetch the address of
- an interned symbol.
- (m4_symbol_pushdef): Take an extra value parameter and use this
- directly as the new top of the value stack. All callers changed
- to build a token and pass responsibility for memory in, rather
- than copying as we used to.
- (m4_symbol_define): Also use the new value parameter directly as a
- replacement for the top of the value stack. All callers changed
- to build a token as above.
- (m4_set_symbol_traced): New function to set the traced bit on the
- named symbol, creating it if necessary.
- (symbol_popval): The guts of the old m4_symbol_popdef.
- (m4_symbol_popdef): Use it.
- * m4/builtin.c (m4_symbol_set_token): Removed,
- (m4__symbol_set_builtin, m4__symbol_set_macro): Removed and
- replaced...
- * m4/module.c (m4_set_module_builtin_table)
- (m4_set_module_macro_table): ...with these more orthogonal
- functions.
- * m4/m4module.h (m4_macro_pushdef, m4_macro_define)
- (m4_builtin_pushdef, m4_builtin_define): Removed. No longer
- required.
- * m4/builtin.c (M4_ARG_SIGNATURE_DEFAULT_SIZE)
- (m4_arg_signature_parse): Moved...
- * m4/symtab.c: ...to here.
- * m4/input.c (m4_token_copy): Arghh... I'm amazed this didn't
- screw something up. Moved...
- * m4/symtab.c (m4_token_copy): ...to here, and fixed so that it
- actually does a proper deep copy of source to dest.
-
-2003-06-16 Gary V. Vaughan <gary@gnu.org>
-
- Further refactoring to stabilise the module API. Renaming some
- functions for orthogonality, and judicious definition migration to
- move things out of the set of exported symbols.
-
- * doc/STYLE: New file. Notes on coding style.
- * m4/m4module.c: Updated bitrotted docucomment at the top of the
- file.
- (m4_module_name, m4_module_builtins, m4_module_macros): Renamed to
- m4_get_module_name, m4_get_module_builtin_table,
- m4_get_module_macro_table which are verb phrases. Changed all
- callers.
- * m4/builtin.c (m4_builtin_table_install, m4_macro_table_install):
- Moved to...
- * m4/module.c (m4_set_module_builtin_table)
- (m4_set_module_macro_table): ...here, and renamed. Changed all
- callers.
- * m4/m4module.c (m4_module_data): This...
- * m4/m4private.c (struct m4_module_data): ...and this...
- * m4/module.c (module_data) ...consolidated here and no longer
- exported. Changed all callers.
-
-2003-06-16 Gary V. Vaughan <gary@gnu.org>
-
- Begin work on lifting the curse of the global variables. To start
- with create a `struct m4' context container, and replace
- `m4__symtab' with `context->symtab' throughout. This means
- initialising a context container in main, and adjusting many
- functions between main and the module entry points so that the
- container gets passed through. It would have been nice to
- defer this until after 1.5, but it has a major effect on the
- user's module writing ABI, so it needs to be addressed now - at
- least in the areas that impact the ABI. An interrelated change
- in the symtab API removes the dependency on a global symbol table,
- and instead focuses on a passed table (from the context
- container).
-
- * TODO: Reminders for finishing context functionality.
- * m4/Makefile.am (libm4_la_SOURCES): Add m4.c.
- * m4/m4.c: New file. Manage new struct m4 objects to eliminate
- global variables and eventually allow m4 to be reentrant.
- * m4/m4private.h (m4): Define the new structure here...
- (M4_SYMTAB, m4_get_symtab): ...so we can have fast accessors that
- don't carry the overhead of a function call.
- * m4/m4module.h: Prototype extern functions from m4/m4.c.
- (m4): Declare type for new struct m4 objects.
- (M4SYMTAB): User macro to ease finding the symbol table for the
- current context for module developers.
- (m4_symbol_token): Renamed to m4_symbol_set_token which contains a
- verb.
- (M4_BUILTIN, m4_builtin_func, M4_BUILTIN_HANDLER)
- (m4_builtin_define, m4_builtin_pushdef, m4_builtin_table_install)
- (m4_call_macro, m4_dump_symbols, m4_expand_input)
- (M4_FINISH_HANDLER, M4_INIT_HANDLE, m4_macro_define)
- (m4_macro_pushdef, m4_macro_table_install, m4_module_load)
- (m4_module_unload, m4_process_macro, m4_symbol_set_token): Add an
- m4* context parameter. Changed definitions and all callers.
- (m4_symtab): Alias for m4_hash to decouple the
- m4_symtab api from m4_hash.
- (m4_symtab_apply, m4_symtab_apply_func): Use m4_symtab instead of
- m4_hash.
- (m4_symtab_create): New function to return an initialised
- m4_symtab.
- (m4_symtab_delete): New function to delete an m4_symtab's memory.
- (m4_symbol_define, m4_symbol_delete, m4_symbol_lookup)
- (m4_symbol_popdef, m4_symbol_pushdef): Add an m4_symtab parameter
- instead of simply using the global m4__symtab. Changed
- definitions and all callers.
- * m4/m4private.h (m4__symtab_remove_module_references): Ditto.
- * m4/symtab.c (m4__symtab_init, m4__symtab_exit): Removed.
- * src/main.c (main): Create a context and use that instead of the
- former global m4__symtab.
-
-2003-06-13 Gary V. Vaughan <gary@gnu.org>
-
- * m4/hash.c (m4_hash_apply): Pass an initial hash table parameter
- to the callback. Callbacks should not need to hardcode the
- hashtable they are working from, nor should we have to waste the
- userdata parameter to pass the table in.
- * m4/hash.h (m4_hash_apply_func): Require the initial table
- parameter.
- * m4/symtab.c (symtab_destroy): Use the passed table instead
- of hardcoding m4__symtab.
- (m4_symbol_popdef): Don't use the userdata parameter to pass the
- table to arg_destroy.
- (arg_destroy): Use the hash parameter, ignore userdata.
- * modules/m4.c (set_trace): Make it fit the m4_hash_apply_func
- prototype.
- (traceon, traceoff): Call set_trace with the extra initial
- parameter.
-
-2003-06-13 Gary V. Vaughan <gary@gnu.org>
-
- More refactoring to stabilise the module api, this time for
- symtab.c. Additionally, start to pay attention to function names
- that don't contain a verb like they should.
-
- * m4/m4module.h (m4_symtab_apply): Reintroduced this function as a
- wrapper for m4_hash_apply to decouple the symtab module from the
- hash module.
- (m4_symbol_builtin, m4_symbol_macro): Renamed to
- m4__symbol_set_builtin and m4__symbol_set_macro. Changed all
- callers.
- (m4_symbol_delete): Create a macro version to save a function
- call.
- (m4_token_t, m4_data_t): These violate the POSIX reserved
- namespace. Renamed to m4_token_type and m4_symbol_type. Changed
- all callers.
- (m4_token_type): Renamed to m4_token_get_type.
- (m4_symtab, m4_symtab_init, m4_symtab_remove_module_references)
- (m4_symtab_exit): Removed from the exported module
- api...
- * m4/m4private.h (m4__symtab, m4__symtab_init)
- (m4__symtab_remove_module_references, m4__symtab_exit): ...and
- renamed and added to the internal api. Changed all callers.
- (m4_symtab_apply): A faster macro version of the function for
- users of the internal api.
- * m4/symtab.c (m4_symbol_destroy, m4_arg_destroy): Renamed to
- symbol_destroy and arg_destroy.
- (symtab_debug): Added a prototype.
- (m4_symtab_apply, m4_symbol_delete): Moved to the end of the file
- so that callers in this file get the faster macro versions from
- m4/m4private.h.
-
-2003-06-12 Gary V. Vaughan <gary@gnu.org>
-
- Refactoring modules to rationalise the API into an external
- documented (eventually!) API for use by modules in the `m4_'
- namespace declared in m4/m4module.h, an internal API between the
- source files we ship (including our shipped modules) in the `m4__'
- namespace declared in m4/m4private.h and making the rest as
- cohesive as possible with liberal use of the `static' keyword.
- This change represents an audit to m4/module.c along these
- guidelines.
-
- * m4/m4module.h (m4_module_close_all, m4_module_find_by_builtin):
- Removed. No longer used.
- (m4_module_close): Removed prototypes.
- (m4_module_init, m4_module_open, m4_module_unload_all): Removed
- from the exported module api...
- * m4/m4private.h (m4__module_init, m4__module_open)
- (m4__module_exit): ...and renamed and added to the internal api.
- Changed all callers.
- (BUILTIN_SYMBOL, MACRO_SYMBOL, INIT_SYMBOL, FINISH_SYMBOL):
- Centralised definitions after renaming...
- * m4/module.c (M4_BUILTIN_SYMBOL, M4_MACRO_SYMBOL, M4_INIT_SYMBOL)
- (M4_FINISH_SYMBOL): ...and removing from here.
- (m4_module_dlerror, m4_module_remove, m4_module_close)
- (m4_caller_id): Not exported at all, so renamed to module_dlerror,
- module_remove, module_close and caller_id.
- (MODULE_SELF_NAME): New macro to make reporting self errors
- easier.
- (m4_module_load, module_close, module_remove): Use it.
- * m4/m4private.h (USER_MODULE_PATH_ENV): Macro to hold "M4MODPATH"
- name.
- * src/main.c (main): Use it.
-
-2003-06-12 Gary V. Vaughan <gary@gnu.org>
-
- * README: Remove references to --enable-changeword, which has been
- removed from the code.
-
-2003-06-11 Gary V. Vaughan <gary@gnu.org>
-
- Getting rid of the annoying bug with configure --enable-debug,
- which spewed -e: command not found errors. This was an interaction
- between libtool-1.5's LT_AC_COMPILER_OPTION, and config/debug.m4.
- You'll need to re-bootstrap the m4 tree with cvs libtool (HEAD or
- branch-1-5) to get the full fix.
-
- * config/debug.m4 (M4_AC_CHECK_DEBUGGING): Require libtools version
- of AC_LIBTOOL_COMPILER_OPTION (which now requires LT_AC_PROG_SED),
- and then use the probed value of $SED.
- (AC_LIBTOOL_COMPILER_OPTION): Removed. Don't conditionally define
- this, it messes up the AC_REQUIRE stack.
-
-2003-06-10 Gary V. Vaughan <gary@gnu.org>
-
- * m4/symtab.c (m4_symbol_popdef): Need to pass the hash address to
- the destroy callback.
- (m4_arg_destroy): Use the hash address to free the hash node key
- field.
-
-2003-06-06 Gary V. Vaughan <gary@gnu.org>
-
- First cut at formal parameters in macros.
-
- * configure.ac (AC_REPLACE_FUNCS): Add xstrzdup.
- * m4/xstrzdup.c: New file.
- * m4/builtin.c (M4_ARG_SIGNATURE_DEFAULT_SIZE): Start size for
- associative array of parameter names to details.
- (m4_symbol_token): Capture macro names with parameter lists.
- (m4_arg_signature_parse): And build an associative array to hang
- from the symbol structure to map names to details.
- * m4/hash.c (m4_hash_new): Break the m4_hash_new followed by
- m4_hash_resize idiom. Now that we potentially add a little hash
- table to many of the entries in the symbol table, added an extra
- arg to set the initial size. Changed all callers.
- (m4_hash_apply): New function that is basically a generalised
- version of...
- * m4/symtab.c (m4_symbol_apply): ...this. Now deleted. Adjusted
- all callers to call m4_hash_apply instead.
- (m4_arg_destroy): Recycle memory used by an m4_token_arg.
- (m4_symbol_popdef): Use m4_arg_destroy to help recycle the
- m4_arg_signature association that might be attached to the symbol,
- * m4/hash.h (m4_hash_apply_func): Replacement type for...
- * m4/m4module.h (m4_symtab_apply_func): ...this. Now deleted.
- (M4_SYNTAX_ASSIGN): Placeholder for assigning default values in
- parameter lists.
- (M4_IS_ASSIGN): Detect characters with M4_SYNTAX_ASSIGN syntax.
- (M4_IS_IDENT): Detect characters that can be safely used in
- parameter names.
- * m4/syntax.c (m4_syntax_init): Add an M4_SYNTAX_ASSIGN character.
- * m4/macro.c: Corrected grammar in some comments. Use `token'
- rather than `td' for m4_token variables.
- (m4_process_macro): If we find a dollar followed by some
- M4_IS_IDENT characters, replace that with the contents of the argv
- entry with offset stored in the m4_token_arg associated with the
- collected identifier.
-
-2003-06-05 Gary V. Vaughan <gary@gnu.org>
-
- Begin preparations for supporting formal parameters in m4 macros.
-
- * m4/m4private.h (struct m4_token_arg): Placeholder for holding
- the details of a formal parameter.
- (m4_token): Add an arg_signature member to hold a hash table for
- looking up formal parameters.
- * m4/input.c: Update more bitrotted comments.
- (m4_push_builtin): Initialise arg_signature member.
- (init_builtin_token): Copy arg_signature member.
- * m4/m4module.h (m4_builtin_pushdef, m4_builtin_define)
- (m4_macro_pushdef, m4_macro_define): Rewritten as macros to
- replace...
- * m4/builtin.c (m4_builtin_pushdef, m4_builtin_define)
- (m4_macro_pushdef, m4_macro_define): ...these, And...
- (m4_symbol_token): ...wrapped around this new function, which
- vastly simplifies the arguments required by the functions it
- replaces.
- Changed all callers.
-
-2003-06-05 Gary V. Vaughan <gary@gnu.org>
-
- * m4/macro.c: Format changes.
-
-2003-06-04 Gary V. Vaughan <gary@gnu.org>
-
- * m4/input.c: Updated various bitrotted comments.
- (m4_push_builtin): Just pass the whole m4_token, rather than
- extracting all the fields in the caller. This also allows us to
- check the token type for consistency.
- (macro_funcs, macro_peek, macro_read, m4_push_macro, CHAR_MACRO):
- Renamed to builtin_funcs, builtin_peek, builtin_read,
- m4_push_builtin and CHAR_BUILTIN for consistency with the rest of
- the code. Changed all callers.
- (struct input_block): Similarly renamed u_m member to u_b, and
- changed all callers.
- (m4_next_token): Use bzero to initialise the data fields.
- * m4/m4module (m4_push_macro): Renamed to m4_push_builtin.
-
-2003-05-29 Gary V. Vaughan <gary@gnu.org>
-
- These changes were necessary to get m4 to build on my iBook
- running "powerpc-apple-darwin6.6" using Apples build of gcc "gcc
- (GCC) 3.1 20020420 (prerelease)":
-
- * src/main.c: Don't include dlfcn.h, ltdl.h handles correct
- inclusion of module loader headers.
- * modules/Makefile.am: Use AM_LDFLAGS, not LDFLAGS.
- * m4/Makefile.am: Ditto.
- (libm4_la_LIBADD): Added $(LTLIBINTL).
- * m4/utility.c (program_name): Removed declaration in favour of
- the one already in error.c!
- * m4/m4module.h (program_name): Define to program_invocation_name
- when using GNU C library. Use an explicit extern declaration.
- (interactive, sync_output, debug_level, hash_table_size)
- (no_gnu_extensions, prefix_all_builtins, max_debug_argument_length)
- (suppress_warnings, warning_status, nesting_limit, discard_comments)
- (lquote, rquote, bcomm, ecomm, m4_bad_argc, m4_skip_space)
- (m4_numeric_arg, m4_shipout_int, m4_shipout_string, m4_dump_args)
- (m4_debug, m4_debug_init, m4_debug_exit, m4_debug_decode)
- (m4_debug_flush_files, m4_debug_set_output, m4_debug_message_prefix)
- (m4_trace_prepre, m4_trace_pre, m4_trace_post, m4_sysval)
- (m4_expansion_level, m4_expand_ranges, m4_expand_input)
- (m4_call_macro, m4_process_macro, m4_syntax_table, m4_current_file)
- (m4_current_line, m4_current_diversion, m4_output_current_line):
- Don't rely on default, use an explicit extern.
- * m4/error.h (error, error_at_line, error_print_progname)
- (error_message_count, error_one_per_line): Ditto.
- * m4/ltdl.c: Update from CVS libtool.
- * m4/ltdl.h: Ditto.
- * commit: Update from CVS cvs-utils.
-
-2002-11-04 gettextize <bug-gnu-gettext@gnu.org>
-
- * po/Makefile.in.in: Upgrade to gettext-0.11.5.
- * po/boldquot.sed: New file, from gettext-0.11.5.
- * po/en@boldquot.header: New file, from gettext-0.11.5.
- * po/en@quot.header: New file, from gettext-0.11.5.
- * po/insert-header.sin: New file, from gettext-0.11.5.
- * po/quot.sed: New file, from gettext-0.11.5.
- * po/remove-potcdate.sin: New file, from gettext-0.11.5.
- * po/Rules-quot: New file, from gettext-0.11.5.
-
-2002-11-04 Akim Demaille <akim@epita.fr>
-
- * doc/m4.texinfo (Esyscmd): Don't grep, use something easier:
- running m4 itself.
- * tests/others.at (iso8859): Use abs_srcdir, not srcdir.
-
-2002-11-04 Akim Demaille <akim@epita.fr>
-
- * config/Makefile.am (ACLOCAL_MACROS): Ship the Gettext macros.
-
-2002-11-04 Akim Demaille <akim@epita.fr>
-
- * configure.ac: Automake 1.7.1, Autoconf 2.54, Gettext 0.11.5,
- used as `external', and Libtool 1.4.3.
- (LINGUAS): Remove.
- (LTLIBOBJS): Don't play with it.
- * intl/: Remove.
- * Makefile.am (SUBDIRS): Remove intl.
- (ACLOCAL_AMFLAGS): Add -I config.
- (EXTRA_DIST): Add config/config.rpath.
- * po/LINGUAS: New.
- * po/Makevars: New.
- * modules/perl.c (M4INIT_HANDLER): Don't prototype xs_init.
-
-2002-05-29 Gary V. Vaughan <gary@gnu.org>
-
- Preparations for refactoring syntax tables to allow reverse
- lookups [fetch me a M4_SYNTAX_OPEN], without compromising the
- speed of normal lookups in an array of unsigned short.
-
- * m4/input.c (single_quotes, single_comments, use_macro_escape):
- Moved from here...
- * m4/m4private.h (m4__single_quotes, m4__single_comments,
- m4__use_macro_escape): ...to here, and renamed. The `m4__' prefix
- is for internal symbols which unavoidably pollute the global
- namespace, but are not published APIs.
- Adjusted all callers.
- * m4/input.c (m4_syntax_init, m4_syntax_code, m4_set_quotes,
- m4_set_comment, m4_set_syntax, set_syntax_internal,
- unset_syntax_attribute): Moved from this file...
- * m4/syntax.c: New. ...to this file.
- Also added an m4_syntax_exit stub for orthogonality.
- * src/main.c (main): Use it.
- * m4/Makefile.am (libm4_la_SOURCES): Add syntax.c.
- * m4/m4module.h: Reformatting. New prototypes.
-
-2002-05-29 Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap (aclocal_apiversion): The aclocal apiversion is
- distinct from the automake release number (in that the apiversion
- apparently has no micro-version-component).
- (aclocal_apilibdir): Use it.
-
-2002-05-28 Gary V. Vaughan <gary@gnu.org>
-
- * m4/hash.c (m4_hash_resize): New function.
- * m4/hash.h: Add prototype.
- * m4/symtab.c (m4_symtab_init): Use it. This could do with some
- benchmarking to find a good value for, say, autoconf. This is
- already a little quicker than before for me.
-
- * m4/symtab.c (m4_symtab_hash, m4_symtab_cmp): Moved from here...
- * m4/hash.c (m4_hash_string_hash, m4_hash_string_cmp): .. to here,
- and reenamed.
- * m4/hash.h: Adjust prototypes.
-
-2002-01-22 Akim Demaille <akim@epita.fr>
-
- * bootstrap (aclocal_apilibdir): New, to cope with Automake's new
- APIVERSION scheme.
- * tests/Makefile.am (package.m4): New.
- * tests/atlocal.in: Adjust to CVS Autotest.
- * config/gnu-obstack.m4 (M4_AC_FUNC_OBSTACK): Use AC_LIBOBJ.
- * configure.ac: LIBOBJ is a forbidden string.
- Simplify AM_INIT_AUTOMAKE invocation.
- * config/Makefile.am (ACLOCAL_MACROS): Add amversion.m4 and
- options.m4.
-
-2002-01-21 gettextize <bug-gnu-utils@gnu.org>
-
- * po/Makefile.in.in: Upgrade to gettext-0.10.40.
-
-2001-10-19 Akim Demaille <akim@epita.fr>
-
- * m4/module.c, m4/output.c, src/main.c: Normalize error messages.
-
-2001-10-19 Akim Demaille <akim@epita.fr>
-
- * m4/input.c (m4_next_token): Display where was opened what is
- not closed.
-
-2001-10-19 Akim Demaille <akim@epita.fr>
-
- * m4/macro.c (expand_argument): Display where was opened what is
- not closed.
-
-2001-10-18 Akim Demaille <akim@epita.fr>
-
- * m4/input.c, modules/m4.c: Formatting changes.
-
-2001-10-17 Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap: s/configure.in/configure.ac/
-
-2001-10-16 Gary V. Vaughan <gary@gnu.org>
-
- * m4/symtab.c (m4_symbol_destroy): This function calls
- m4_symbol_popdef, which recycles a symbols memory when the last
- definition is popped. Since we were passing the address of the
- symbol name found in the symbol table, and it was being removed
- partway through m4_symbol_destroy() we were referencing freed
- memory for the balance of the function. Now we take a copy of the
- symbol name tring and use that as a key into the symbol
- table... that way if the original symbol name is freed, the copy
- is still valid.
-
-2001-10-13 Akim Demaille <akim@epita.fr>
-
- * m4/ltdl.c: Update.
-
-2001-10-13 Akim Demaille <akim@epita.fr>
-
- * src/main.c, src/freeze.c, m4/debug.c, m4/input.c, m4/macro.c:
- Don't gettextize internal error messages.
-
-2001-10-13 Akim Demaille <akim@epita.fr>
-
- * tests/macros.at (Arity and defn): New failing test.
- (Arity, defn, and freeze): New.
-
- Fix `Arity and defn'.
-
- * m4/input.c (m4_push_macro): Don't forget the arity.
- * modules/m4.c (defn): Likewise.
-
-2001-10-13 Akim Demaille <akim@epita.fr>
-
- * tests/builtins.at (pushdef/popdef, trace, trace2, trace3): Move
- to...
- * tests/macros.at (pushdef/popdef, Tracing Hanoi Towers)
- (Propagation of traceon, Propagation of --trace): this new file.
-
-2001-10-13 Akim Demaille <akim@epita.fr>
-
- * m4/utility.c (m4_numeric_arg): Use the usual (argc, argv, ...)
- interface instead of (name, argc...).
- Upon failure, specify which argument was guilty.
- Adjust callers.
-
-2001-10-13 Akim Demaille <akim@epita.fr>
-
- * modules/evalparse.c: Save translators' time: don't translate
- internal error messages.
- (m4_evaluate): Simplify/normalize error messages.
- * doc/m4.texinfo (Eval): Adjust.
-
-2001-10-13 Akim Demaille <akim@epita.fr>
-
- * m4/macro.c (expand_macro): Let m4_bad_argc handle the cases
- where no checking is needed.
- * m4/utility.c (m4_bad_argc): Use the usual (argc, argv, ...)
- interface instead of (name, argc...).
- Adjust callers.
- * modules/gnu.c (m4_patsubst_do): Don't check argc, done
- elsewhere.
-
-2001-10-13 Akim Demaille <akim@epita.fr>
-
- * m4/utility.c (m4_bad_argc): Display user argument counts, i.e.,
- exclude the builtin name from the count.
- * modules/m4.c (ifelse): Do not use the regular argc mechanism, as
- calling ifelse with a single argument is valid.
- * doc/m4.texinfo (Ifelse): Add an example where ifelse is invoked
- with 1 and 2 args, mostly to strengthen the test suite.
-
-2001-10-13 Akim Demaille <akim@epita.fr>
-
- * m4/output.c (m4_make_diversion, m4_insert_file)
- (m4_insert_diversion, +m4_freeze_diversions): Ansify.
-
-2001-10-12 Gary V. Vaughan <gary@gnu.org>
-
- * m4/input.c (init_builtin_token): Renamed from init_macro_token,
- since we call these things builtins in the rest of the code!
-
- * modules/gnu.c (m4_regexp_compile): s/%0/%s/
-
-2001-10-12 Gary V. Vaughan <gary@gnu.org>
-
- Rather than forcing each builtin definition to manage its own
- argument range checking, tabulate the maxima and minima for all
- builtins in each module. This forces us to consider what the
- valid ranges for each builtin should be, and moves the checking
- code out of each builtin implementation and into the builtin
- caller infrastructure.
-
- * m4/m4module.h (struct m4_builtin): Add argument minima and
- maxima.
- * m4/m4private.h (struct m4_token): Reflect them here too.
- * m4/input.c (struct input_block): ...and here.
- (m4_token_copy): New function for token copying.
- (init_macro_token): Copy them from a token to the input stack.
- (m4_next_token): Don't forget to initialise them for text
- macros.
- * m4/macro.c (expand_argument): Use m4_token_copy, and also
- check argument counts before calling the builtin handler.
- * m4/symtab.c (m4_symbol_builtin): Take minima and maxima params.
- (m4_symbol_macro): Likewise.
- * m4/builtin.c (m4_builtin_pushdef): Add min_args and max_args
- parameters. Updated all callers.
- (m4_builtin_define): Ditto.
- (m4_macro_pushdef, m4_macro_define): Ditto.
- * m4/symtab.c (m4_symbol_builtin, m4_symbol_define): Ditto.
- * modules/evalparse.c: Declare argument counts for defined
- builtins and remove explicit calls to m4_bad_argc().
- * modules/gnu.c: Ditto.
- * modules/load.c: Ditto.
- * modules/m4.c: Ditto.
- * modules/modtest.c: Ditto.
- * modules/mpeval.c: Ditto.
- * modules/perl.c: Ditto.
- * modules/shadow.c: Ditto.
- * modules/stdlib.c: Ditto.
- * modules/time.c: Ditto.
- * TODO: Updated.
-
-2001-10-10 Gary V. Vaughan <gary@gnu.org>
-
- The trace semantics now attach the trace bit to a symbol name.
- For as long as a traceon(`foo') is active, calls to foo will be
- traced regardless of intervening undefines or module unloads.
- Fixed the flag propogation issues differently to the fixes
- reverted with the last attempt at nailing down trace:
-
- * m4/m4private.h: This file is not visible outside of the m4
- source tree, so I removed all the `M4_' and `m4_' prefixes to save
- on typing. Updated all clients.
- (m4_token): New typedef contains the fields that need to be passed
- around with the low level tokeniser.
- (m4_token_data): Removed.
- (m4_symbol): Now contains the traced flag again.
- * m4/symtab.c: Rewritten again. Now we don't remove symbols with
- the trace bit set. This change is contained entirely within this
- module and doesn't leak out into the callers. Updated all
- clients.
- (m4_symbol_builtin, m4_symbol_macro): Adjusted to make use of the
- new fields in m4_token. Updated all clients.
- * m4/builtin.c (m4_builtin_pushdef): Needs a flags argument so
- that `groks_macro_args' and `blind_if_no_args' flags are retained
- when defn() results are passed around in m4 code. Updated all
- callers.
- (m4_builtin_define): Ditto.
- (m4_macro_pushdef, m4_macro_define): Ditto.
- * m4/input.c (struct input_block): Add a flags field to facilitate
- the above.
- (m4_push_macro): ...use it.
- (init_macro_token): Retrieve it.
- (m4_next_token): Initialise it.
- * m4/macro.c (expand_argument): Copy it.
- * m4/m4module.h: Adjust.
- * tests/builtins.at: Adjust the expected output of the trace
- tests to reflect the change in semantics.
- * tests/modules.at (modules: trace): Check that unloading a
- module which supplies a traced symbol definition doesn't lose te
- trace bit.
-
-2001-10-07 Gary V. Vaughan <gary@gnu.org>
-
- * modules/gnu.c (m4_macro_table): Display the timetamp when
- expanding __m4_version__.
-
- * configure.ac (--with-modules): Forgot a comma in the
- AC_HELP_STRING parameter list.
-
-2001-10-05 Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap: Remove aclocal.m4t when it is no longer required.
-
-2001-10-05 Akim Demaille <akim@epita.fr>
-
- * tests/Makefile.am: Adjust for gnuprog2.
- * tests/m4.in: There can be a leading path.
- * tests/modules.at (AT_CHECK_M4_MODTEST): No need for $4 and $5.
- * tests/testsuite.at: Adjust to the most recent Autotest.
- (AT_CHECK_M4_FILTER): Fix and rename as...
- (AT_TEST_M4): this.
- * tests/others.at: Use it.
-
- * config/gmp.m4 (_AC_LIB_GMP): In order to read the content of a
- variable in shell scripts, one uses `$'...
-
-2001-10-04 Gary V. Vaughan <gary@gnu.org>
-
- * configure.ac: `rm -f $m4_getopt_h' was lost.
-
-2001-10-04 Gary V. Vaughan <gary@gnu.org>
-
- * configure.ac (TIMESTAMP): Display with AS_BOX at configure
- time. Define it for config.h in order to...
- * src/main.c (main): ...display the timestamp for --version.
-
-2001-10-04 Akim Demaille <akim@epita.fr>
-
- * modules/gnu.c (m4_regexp_do, m4_patsubst_do): Extracted from
- previous builtins `regexp' and `patsubst'.
- (regexp, patsubst): Use them.
- (eregexp, epatsubst): New builtins.
- * doc/m4.texinfo (Patsubst, Regexp): Rename and complete as...
- (Epatsubst and Patsubst, Eregexp and Regexp): these.
- (Extensions): More info on REs.
-
-2001-10-04 Akim Demaille <akim@epita.fr>
-
- * modules/modtest.c (init_handler): Consistently output to stderr.
- (finish_handler): New.
- (test): The `if' is an `assert'.
- * tests/modules.at: Adjust.
-
-2001-10-04 Akim Demaille <akim@epita.fr>
-
- * m4/utility.c (m4_bad_argc): Detail the mismatches.
-
-2001-10-01 Akim Demaille <akim@epita.fr>
-
- * tests/generate.awk: Tag the tests with `documentation'.
- * tests/modules.at (AT_CHECK_M4_MODTEST): New.
- Use the make the existing modtest tests more uniform, and complete
- the set of possibilities.
-
-2001-10-01 Akim Demaille <akim@epita.fr>
-
- * config/gmp.m4: Consult the user before using GMP: use
- --without-gmp.
- * configure.ac: Adjust.
- * modules/gmp.c: No protection needed as the module is not built
- if GMP is not used.
-
-2001-10-01 Akim Demaille <akim@epita.fr>
-
- * tests/generate.awk: Remove debugging code.
- (fatal): Specify the current location.
-
- * m4/debug.c, m4/macro.c, m4/utility.c, modules/format.c,
- * modules/gnu.c, modules/m4.c: Use M4ARG.
-
-2001-10-01 Akim Demaille <akim@epita.fr>
-
- * modules/gnu.c (RE_SYNTAX_BRE, RE_SYNTAX_ERE): New.
- (m4_regexp_compile): New.
- (regexp, patsubst): Use it.
-
-2001-09-30 Gary V. Vaughan <gary@gnu.org>
-
- Reinstate the memory handling improvements from the patch I just
- reverted. Relevant ChangeLog entries repeated here:
-
- * m4/module.c (m4_module_remove): New function that holds the core
- of the old m4_module_unload.
- (m4_module_unload): Use it.
- (m4_module_unload_all): When we know the modules will never be
- used again (i.e. on exit), free up as much module memory as
- possible. There are still some artifacts from resident modules
- living inside ltdl.c, but everything else is freed.
- * m4/debug.c (m4_debug_exit): Free memory allocated in
- m4_debug_init().
- * m4/input.c (m4_input_exit): Ditto wrt m4_input_init().
- * m4/output.c (m4_output_exit): Ditto wrt m4_output_init ().
- * src/stackovf.c (stackovf_exit): Ditto wrt setup_stackovf_trap ().
- * m4/m4module.h: Updated prototypes.
- * m4/hash.c (m4_hash_exit): Free the nodes on the free list.
- * m4/hash.h: Updated prototypes.
- * src/main.c (main): Use all these new functions to clean up as
- much memory as possible before exit.
-
-2001-09-30 Gary V. Vaughan <gary@gnu.org>
-
- Reverted my large patch for removing the old m4_symbol
- structure on 2001-09-20. We are still not happy about the way
- trace works in conjunction with defn and undefine, and leaving
- the reverted patch active prevents us from moving the traced
- bit from the definition back to the symbol.
-
-2001-09-30 Gary V. Vaughan <gary@gnu.org>
-
- * configure.in: Moved to...
- * configure.ac: ...here. Added a libtool like timestamped
- banner, and tidied up the libltdl cruft.
- * config/mkstamp: Script to extract a timestamp from ChangeLog.
- * modules/Makefile.am (INCLTDL): Removed. This is required
- only when libltdl is configured in a subdirectory.
- * src/Makefile.am: Ditto.
- (LIBADD_DL): No need to add this again, libtool already knows
- that libm4.la depends on it.
- * m4/Makefile.am: Automake sets variables from AC_SUBST. Use
- them.
-
- * TODO: stackovf.c is basically broken.
- Reported by Marc Espie <espie@schutzenberger.liafa.jussieu.fr>
-
-2001-09-28 Akim Demaille <akim@epita.fr>
-
- * tests/Makefile.am (EXTRA_DIST): `m4' is not to be shipped.
-
-2001-09-27 Akim Demaille <akim@epita.fr>
-
- * tests/m4.in: Don't use short options.
- Simplify the stderr signature normalization.
-
-2001-09-27 Akim Demaille <akim@epita.fr>
-
- tests/m4 shall be position independent.
-
- * tests/m4.in: New.
- * tests/m4: Remove.
- * tests/testsuite.at: No args to AT_INIT.
- * configure.in, tests/Makefile.am: Adjust.
-
-2001-09-22 Akim Demaille <akim@epita.fr>
-
- Autotest has changed again.
-
- * tests/Makefile.am (DISTCLEANFILES): Add package.m4.
- (package.m4): Remove.
- * configure.in: Adjust to LIBADD_GMP.
-
-2001-09-21 Gary V. Vaughan <gary@gnu.org>
-
- * config/gmp.m4 (AC_ARG_WITH): Removed.
- (GMP_LIB): Renamed to LIBADD_GMP for consistency.
- (AC_LIB_GMP): When performing a test compile against libgmp,
- include the header gmp.h if possible, and link against -lgmp. If
- they both work define USE_GMP.
- * modules/Makefile.am (mpeval_la_LIBADD): Add LIBADD_GMP.
- (mpeval_LTX_init_func): Complain on load that there was no libgmp
- at compile time.
-
-2001-09-20 Gary V. Vaughan <gary@gnu.org>
-
- * m4/evalparse.c: Moved to...
- * modules/evalparse.c: ...here. This code is shared between
- modules/mpeval.c and modules/m4.c, so there is no need to pollute
- the libm4 API with its details. Moderately rewritten to interface
- into its clients more simply.
- * m4/eval.c: Deleted. Migrated functionality to...
- * modules/m4.c: ...here.
- (builtin_eval): Implemented in terms of the new interface style.
- * modules/mpeval.c (builtin_mpeval): Ditto.
- * m4/m4module.h: Removed references to the former m4/eval.c.
- * m4/Makefile.am (libm4_la_SOURCES): Removed eval.c.
- (EXTRA_libm4_la_SOURCES): Deleted.
- * modules/Makefile.am (EXTRA_m4_la_SOURCES): Reference evalparse.c.
- (EXTRA_mpeval_la_SOURCES): Reference evalparse.c.
-
-2001-09-20 Akim Demaille <akim@epita.fr>
-
- * config/gmp.m4 (AM_WITH_GMP): Rename as...
- (AC_LIB_GMP): this.
- By default, use gmp.
- Massive revamping.
- * configure.in: Adjust.
- Use Automake conditionals for USE_GMP.
- Always compute sizeof (long long int).
- This was a bug BTW, as `eval' (not `mpeval') depends on it:
- before, it was used _only_ if mpeval was not activated.
- * modules/Makefile.am (pkglibexec2dir, +pkglibexec2_LTLIBRARIES)
- (mpeval_la_LIBADD): New macros.
- * modules/mpeval.c: No longer be conditioned by WITH_GMP.
- Indent.
- * tests/Makefile.am ($(srcdir)/$(TESTSUITE)): Create package.m4.
- * tests/atlocal.in, tests/builtins.at: Depend upon USE_GMP, not
- WITH_GMP.
-
-2001-09-20 Akim Demaille <akim@epita.fr>
-
- * tests/Makefile.am (package.m4): New.
- * tests/testsuite.at: Adjust AT_INIT and AT_VICTIMS.
-
-2001-09-20 Gary V. Vaughan <gary@gnu.org>
-
- More cleanup. After the last patch, m4_symbol holds nothing but
- the head of a chain of m4_token_data. So I have removed the old
- m4_symbol, so that m4_token_data chains are stored directly in the
- value cell of a hash table node. But there's more... m4_symbol
- was a more natural name for the symbol value cell, and now that it
- is gone I have renamed the former m4_token_data structure to
- m4_symbol. This change turned out to be a pig to get right, since
- the original code didn't need to modify the value cell itself,
- since changing the chain happened inside the m4_symbol that used
- to be returned -- I had to pass the address of the value cell
- across various function calls, incase the head value changed. I
- also tightened up the memory management to help me find a nasty
- memory corruption bug that took me all night to track down...
-
- * m4/m4private.h (struct m4_symbol): Removed.
- (struct m4_token_data): Renamed to `struct m4_symbol'. Updated
- all references.
- * m4/hash.c (m4_hash_iterator_value): Return the address of the
- value cell. Updated all callers.
- * m4/symtab.c: Took advantage of the simplification in the data
- structures to rewrite a lot of this file more simply. There is
- still some room for optimisation here, but we should tackle that
- systematically closer to the release.
-
- * m4/ltdl.c: Added dmalloc support, and fixed some memory leaks it
- revealed. This version is ahead of CVS libtool until I get chance
- to flush my changes.
- * m4/module.c (m4_module_remove): New function that holds the core
- of the old m4_module_unload.
- (m4_module_unload): Use it.
- (m4_module_unload_all): When we know the modules will never be
- used again (i.e. on exit), free up as much module memory as
- possible. There are still some artifacts from resident modules
- living inside ltdl.c, but everything else is freed.
- * m4/debug.c (m4_debug_exit): Free memory allocated in
- m4_debug_init().
- * m4/input.c (m4_input_exit): Ditto wrt m4_input_init().
- * m4/output.c (m4_output_exit): Ditto wrt m4_output_init ().
- * src/stackovf.c (stackovf_exit): Ditto wrt setup_stackovf_trap ().
- * m4/m4module.h: Updated prototypes.
- * m4/hash.c (m4_hash_exit): Free the nodes on the free list.
- * m4/hash.h: Updated prototypes.
- * src/main.c (main): Use all these new functions to clean up as
- much memory as possible before exit.
-
-2001-09-18 Gary V. Vaughan <gary@gnu.org>
-
- The `traced' flag needs to be attached to the definition of a
- symbol rather than the current symbol containing the definition.
- Implementing this showed up some long standing post 1.4 bugs in
- flag propogation which I also fixed.
-
- * m4/m4private.h (struct m4_symbol): Remove the traced flag.
- (struct m4_token_data): And add it back in here.
- * m4/input.c (init_macro_token): Propogate the traced flag
- correctly.
- * m4/macro.c (expand_argument): Ditto.
- * tests/builtins.at (trace2, trace3): New tests based on Akim's
- sadistic email ;-)
-
-2001-09-08 Gary V. Vaughan <gary@gnu.org>
-
- * m4/m4private.h (struct m4_token_data): Simplified by removing
- the redundant `traced' flag, and one level of structure nesting.
- (M4_TOKEN_DATA_FUNC_TRACED): Removed.
- * m4/input.c (init_macro_token): No need to initialise removed
- `traced' field.
- * m4/macro.c (expand_argument): No need to copy it either.
- * m4/utility.c (m4_token_data_func_traced): Or provide an access
- function.
-
- * m4/hash.c (m4_hash_bucket_insert): Symbol shadowing is no longer
- dependant on multiple symbols with the same key, so preserving
- relative symbol order in each bucket during resizing is no longer
- required. The resize function is considerably faster as a result.
-
- * m4/m4module.h, m4/builtin.c, m4/symtab.c:
- s/m4_symbol_insert/m4_symbol_define/g;
- s/m4_builtin_insert/m4_builtin_define/g;
- s/m4_macro_insert/m4_macro_define/g. Updated all callers.
-
-2001-09-08 Gary V. Vaughan <gary@gnu.org>
-
- Get rid of m4_symbol_lookup_t entirely. With Akim's earlier
- commits, the m4_lookup_symbol dispatch function is split into
- specialised functions that must be called directly.
-
- * m4/m4module.h (m4_symbol_lookup_t): Removed.
- * m4/symtab.c (m4_lookup_symbol): Removed.
- (m4_symbol_builtin, m4_symbol_macro): New functions.
- * m4/builtin.c (m4_builtin_define): Split into...
- (m4_builtin_pushdef, m4_builtin_insert): ...these.
- (m4_macro_define): Split into...
- (m4_macro_pushdef, m4_macro_insert): ...these.
- * src/main.c (main): Set command line macros from `-D' parameters
- using `m4_macro_define'.
-
-2001-09-08 Gary V. Vaughan <gary@gnu.org>
-
- * m4/symtab.c (m4_symtab_remove_module_references): Renamed as
- this from m4_remove_table_reference_symbols().
- * m4/m4module.h, m4/module.c: Updated all references.
-
-2001-09-07 Akim Demaille <akim@epita.fr>
-
- * modules/stdlib.c, modules/times.c: Misc cleanups.
-
-2001-09-07 Akim Demaille <akim@epita.fr>
-
- * configure.in: We now need Autoconf 2.52e.
- * m4/m4module.h (m4_symbol_lookup_t): Remove `M4_SYMBOL_POPDEF'
- and `M4_SYMBOL_DELETE'.
- * m4/symtab.c (m4_lookup_symbol, symtab_debug): Adjust.
- * src/main.c (main): Adjust.
-
-2001-09-06 Gary V. Vaughan <gary@gnu.org>
-
- Fix the obstack.h problem once and for all! At configure time we
- can test for a system supplied obstack.h: depending on the
- result, we now generate system.h with an #include of the correct
- header. As a bonus, I've also added a --with-included-obstack,
- incase the user doesn't like the system obstack for some
- reason... and also we can test the shipped obstack on a system
- that has oe of its own. We also now need to be careful to add
- build directories to the include search path, since the generated
- system.h will be in the build tree.
-
- * configure.in (AC_CONFIG_FILES): Generate system.h from
- system-h.in.
- * config/gnu-obstack.m4 (M4_AC_FUNC_OBSTACK): Determine whether to
- include the system obstack header or the copy shipped with M4.
- Allow the user to override configure and force the build to use
- the shipped version.
- * m4/system-h.in: New file, template for...
- * m4/system.h: ...this. Now deleted.
- * m4/m4module.h: Include system.h before everything else.
- * src/freeze.c: Ditto.
- * m4/Makefile.am (dist-hook): Remove generated system.h.
- (INCLUDES): Check builddir for generated headers before checking
- srcdir.
- * modules/Makefile.am (INCLUDES): Ditto.
- * src/Makefile.am (INCLUDES): Ditto.
-
-2001-09-05 Gary V. Vaughan <gary@gnu.org>
-
- * TODO: Remove the items that have been addressed already.
-
-2001-09-05 Akim Demaille <akim@epita.fr>
-
- * src/main.c (main): Standardize --version.
-
-2001-09-05 Akim Demaille <akim@epita.fr>
-
- * modules/format.c (format): Have a bigger `str'.
-
-2001-09-05 Akim Demaille <akim@epita.fr>
-
- Rationalize warnings, reporting the macro name as if it were a
- program name, and assertions.
-
- * m4/m4module.h (m4_lookup_symbol): Prototype, it is still used.
- (M4WARN): New.
- * m4/symtab.c (m4_lookup_symbol, m4_symbol_popdef)
- (m4_symbol_delete):
- Use assert for internal errors.
- * m4/utility.c (m4_bad_argc, m4_numeric_arg, m4_dump_symbols): Use
- M4WARN.
- * modules/m4.c (undefine, defn, traceon, traceoff, dumpdef): use
- M4WARN and assert.
- * tests/builtins.at (pushpop): Adjust.
-
-2001-09-05 Akim Demaille <akim@epita.fr>
-
- * m4/symtab.c (m4_symbol_insert): Don't use `foo () || bar ()'
- with pointers.
-
-2001-09-05 Akim Demaille <akim@epita.fr>
-
- * m4/m4module.h (m4_symbol_lookup): Remove M4_SYMBOL_LOOKUP.
- * m4/macro.c, m4/symtab.c: Adjust.
-
-2001-09-05 Akim Demaille <akim@epita.fr>
-
- * m4/symtab.c (m4_symbol_popdef, m4_symbol_delete): Rename as...
- (m4_symbol_pop, m4_symbol_del): this.
- (m4_symbol_lookup, m4_symbol_pushdef, m4_symbol_insert)
- (m4_symbol_popdef, m4_symbol_delete): New.
- (m4_lookup_symbol): Adjust.
- * m4/m4module.h, src/main.c, modules/gnu.c, modules/m4.c: Adjust.
-
-2001-09-05 Akim Demaille <akim@epita.fr>
-
- * m4/m4module.h (m4_symbol_lookup): Rename as...
- (m4_symbol_lookup_t): this.
-
-2001-09-05 Akim Demaille <akim@epita.fr>
-
- * m4/m4module.h (m4_symbol_lookup): Remove M4_SYMBOL_IGNORE,
- unused.
- * m4/symtab.c (m4_lookup_symbol): Adjust.
-
-2001-09-03 Gary V. Vaughan <gary@gnu.org>
-
- Bootstrap will now work with Libtool 1.4.1 or higher:
- * bootstrap: Remove stale autom4te.cache files when
- rebootstrapping.
- * config/Makefile.am (ACLOCAL_MACROS): Add ltdl.m4 and
- libtool.m4.
- * bootstrap: Ignore acinclude.m4 now the we include ltdl.m4 and
- libtool.m4 directly.
- Run libtoolize to refresh ltmain.sh.
- * config/ltmain.sh: Deleted.
- * acinclude.m4: Deleted.
- * m4/ltdl.c, m4/ltdl.h: Updated from libtool-1.4.1.
-
- * config/debug.m4 (AC_LIBTOOL_COMPILER_OPTION): Provide a fallback
- implementation for the cvs impaired libtool user.
-
-2001-09-03 Akim Demaille <akim@epita.fr>
-
- * m4/symtab.c (m4_lookup_symbol): Give more details when reporting
- internal errors.
- Avoid using `default' in switch, as it hides useful compiler
- warnings when a case is forgotten.
-
-2001-09-03 Akim Demaille <akim@epita.fr>
-
- * src/main.c (MODULE_SHORTOPT, MODULEPATH_SHORTOPT): Remove, there
- is no such thing as `WITH_MODULES'.
-
-2001-09-03 Akim Demaille <akim@epita.fr>
-
- Improve the test suite's selfcontainedness.
-
- * doc/m4.texinfo: Let `input.m4' be the input file, not `in'.
- (Include, Undivert): Tag the other input files.
- * tests/generate.awk: Catch `@comment file:'.
- `-I $src' is no longer needed.
- `next' is really like `return': the rest is skipped.
- Adjust to `input.m4'.
- (fatal): New function.
- * tests/foo, tests/incl.m4: Remove.
-
-2001-09-01 Gary V. Vaughan <gary@gnu.org>
-
- The shadowing mechanism and, infact, the whole symbol table
- implementation was creaking under the weight of the features piled
- on top of it. We now have a separate hash table module which will
- dynamically resize to keep symbol density withing good performace
- limits, and a new symtab module layered above it. Symbol lookups
- are now marginally more efficient (since the shadowed flag is no
- longer required) and symbol removal, such as on module unload, is
- considerably faster due to a reorganisation of the data structures
- used in symtab.c.
-
- * src/main.c (main): Don't mention `-H'.
- * doc/m4.texinfo (Invoking m4): Document that -H no longer has any
- effect.
- * NEWS: Updated.
- * m4/hash.c: New generalised dynamic hash table data structure
- management module.
- * m4/hash.h: Public interface.
- * m4/Makefile.am (pkginc_HEADERS): Add hash.h.
- (libm4_la_SOURCES): Add hash.c.
- * m4/symtab.c: More or less rewritten from scratch, within the
- bounds of the previous API.
- (m4_symtab_apply): A cleaner version of the old hack_all_symbols
- call. Updated all callers.
- * m4/m4module.c: #include <m4/hash.h>, and changed all affected
- declarations to reflect API changes.
- (M4INIT): Generate a declaration too, to avoid the warning with
- --enable-debug builds.
- (M4FINISH): Ditto.
- (HASHMAX): Removed.
- * m4/utility.c (hash_table_size): Removed.
- (m4_dump_symbols): Rewritten to build and qsort an array of symbol
- names, which are then looked up by builtin_dumpdef() as necessary.
- This implies a small speedup in builtin_symbols(), which discarded
- all of the symbol info under the old call.
- * m4/m4private.h (m4_symbol): Removed shadowed flag -- symbol
- shadowing is implicit in respect to the new data structures.
- symbol names are no longer duplicated here, they are stored in the
- key field of the hash table.
- Moved macro_args and blind_no_args...
- (m4_token_data): ...to here.
- m4/macro.c (expand_macro): Added a name argument since the symbol
- name is no longer copied into each struct m4_symbol. Modified all
- callers.
- (collect_arguments): Ditto.
- * modules/m4.c (set_trace): Ditto.
- * modules/gnu.c (builtin_symbols): Updated.
- * src/freeze.c (produce_symbol_dump): Much improved in light of
- the improved symbol table layout.
-
-2001-09-01 Gary V. Vaughan <gary@gnu.org>
-
- * m4/m4private.h (SYMBOL_NEXT): Move into m4's name space; renamed
- to M4_SYMBOL_NEXT.
- (SYMBOL_TRACED): Similarly renamed by prefixing with `M4_'.
- (SYMBOL_SHADOWED, SYMBOL_MACRO_ARGS, SYMBOL_BLIND_NO_ARGS,
- SYMBOL_NAME, SYMBOL_TYPE, SYMBOL_TEXT, SYMBOL_FUNC,
- SYMBOL_HANDLE): Ditto.
- * m4/builtin.c, m4/macro.c, m4/symtab.c, m4/utility.c,
- modules/gnu.c, modules/m4.c, src/freeze.c,
- src/main.c: Updated all references.
-
- * src/Makefile.am (m4_SOURCES): Don't list $(M4OBJS) here, since
- Automake 1.5 chokes on dynamic source file lists, Besides, it is
- already listed in m4_LDADD... how did that ever used to work?
- * configure.in (getopt.h): Use AC_CONFIG_LINKS instead of a manual
- link.
- * config/gnu-obstack.m4 (M4_AC_FUNC_OBSTACK): Ditto.
- Suggested by Tim Van Holder <tim.van.holder@pandora.be>
-
- * tests/m4: Don't call the m4 wrapper script with libtool, it
- works fine all by itself.
-
-2001-08-30 Gary V. Vaughan <gary@gnu.org>
-
- The experimental `changeword' feature never took off, and has
- no obvious advantages over `changesyntax' to compensate the
- enormous speed penalty it carries:
- * configure.in (ENABLE_CHANGEWORD): Removed.
- * m4/m4module.h (m4_set_word_regexp): Removed.
- * m4/m4private.h (m4_token_data): Removed original_text field.
- * m4/utility.c (m4_token_data_orig_text): Removed.
- * m4/input,c: Removed all conditional ENABLE_CHANGEWORD code.
- * m4/macro.c: Ditto.
- * src/main.c: Ditto.
- * modules/Makefile.am (changeword.la): Removed.
- * modules/changeword.c: File removed.
- * doc/m4.texinfo: References to changeword and --word-regexp
- removed.
- * po/POTFILES.in: modules/changeword.c removed.
- * tests/atlocal.in (ENABLE_CHANGEWORD): Removed.
- * tests/builtins.at (changeword): Test removed.
-
-2001-08-30 Akim Demaille <akim@epita.fr>
-
- * bootstrap.sh: Create aclocal.m4 instead of modifying it.
- This also help having a single list of m4 files: in
- config/Makefile.am.
- * config/Makefile.am (STANDARD_MACROS): Rename as...
- (ACLOCAL_MACROS): this.
- (list-standard-macros): Remove.
- (spy): New.
-
-2001-08-29 Gary V. Vaughan <gary@gnu.org>
-
- In an attempt to moderate my egomania...
- * tests/modules.at: Remove attributions.
-
- * tests/generate.awk: When making substitutions to "@&t@", either
- "&" or "\&" in the substitution string argument to gsub refer back
- to the matched text. "@\\&t@" seems to work though, Tests 43 and
- 67 now pass for me.
-
-2001-08-29 Akim Demaille <akim@epita.fr>
-
- * tests/others.at (changeword, ddivert, debug, esyscmd, exp, gmp)
- (include, indir, multiquotes, patsubst, pushdef/popdef, regexp)
- (sync-lines, trace, translit, undivert, wrap): Move to...
- * tests/builtins.at: this new file.
- * tests/others.at (Discard comments, import-environment): Move to...
- * tests/options.at: this new file.
-
-2001-08-29 Akim Demaille <akim@epita.fr>
-
- * tests/others.at (Freezing modules)
- (--module-directory: absolute path, modpath2, modpath3)
- (M4MODPATH: absolute path, modtest, shadow, unload): Move to...
- * tests/modules.at: here, new file.
- * tests/others.at, tests/generate.awk: Add a banner.
- * tests/testsuite.at: Adjust.
- (AT_CHECK_M4_FILTER): New, but unused.
-
-2001-08-29 Akim Demaille <akim@epita.fr>
-
- * tests/testsuite.at (AT_CHECK_M4): Don't pass -I, let the tests
- handle that.
- * tests/others.at (wrap): Inline wrap.m4.
- (shadow): Inline shadow.m4.
- (iso8859): Don't specify the path from top_srcdir, but from srcdir.
- * tests/m4: Simplify.
-
-2001-08-29 Akim Demaille <akim@epita.fr>
-
- * tests/Makefile.am ($(srcdir)/$(TESTSUITE)): Use autom4te's
- --language.
-
-2001-08-29 Akim Demaille <akim@epita.fr>
-
- * tests/generate.awk (normalize): s/@__@/@&t@/.
-
-2001-08-28 Akim Demaille <akim@epita.fr>
-
- * examples/indir.m4, tests/others.at (indir): s/nonsens/nonsense/.
-
-2001-08-28 Gary V. Vaughan <gary@gnu.org>
-
- * bootstrap (generate.awk): Generate test cases with new script.
-
-2001-08-27 Akim Demaille <akim@epita.fr>
-
- * tests/Makefile.am (installcheck-local): Don't use
- `dc_install_base' which is not visible here, but `exec_prefix'
- which is clearly the RT anyway.
- * tests/testsuite.at (AT_CHECK_M4): Don't pass -M here since it is
- related to testing a now installed m4.
- * tests/m4: Do it here.
-
-2001-08-27 Akim Demaille <akim@epita.fr>
-
- * tests/others.at (indir): Formatting change.
-
-2001-08-27 Akim Demaille <akim@epita.fr>
-
- * tests/Makefile.am (installcheck-local): New.
- * tests/testsuite.at (AT_CHECK_M4): Pass `-b' so that C-c works on
- the test suite.
- Prefer options over envvars.
- * src/main.c (main): First bug caught by the test suite (yeah!):
- --batch lacked a `break' which resulted in an accidental
- invocation of --discard-comments.
-
-2001-08-27 Akim Demaille <akim@epita.fr>
-
- * tests/others.at (capitalize, changeword, comments, ddivert)
- (debug, esyscmd, exp, foreach, forloop, fstab, hanoi, include)
- (misc, multiquotes, patsubst, pushdef/popdef, regexp, reverse)
- (sysv-args, trace, translit, undivert): Don't rely on files in
- examples/: AT_DATA them.
-
-2001-08-27 Akim Demaille <akim@epita.fr>
-
- Let the test suite use a wrapper around the not installed m4 to
- pretend it is (installed).
-
- * bootstrap (aclocal.m4): Output AC_SUBST's and AM_CONDITIONAL's in
- such a way that m4 does not process them.
- * configure.in: The package name seems to be `m4', not `M4'.
- * tests/m4: New.
- * tests/atlocal.in (at_package, M4): Remove.
- * tests/testsuite.at, tests/others.at: Use m4, not $M4.
-
-2001-08-27 Akim Demaille <akim@epita.fr>
-
- * tests/Makefile.am (CLEANFILES): Remove.
- (DISTCLEANFILES, clean-local): New.
- * examples/mktests.sh: Remove.
-
-2001-08-27 Akim Demaille <akim@epita.fr>
-
- * Makefile.am (AUTOMAKE_OPTIONS): 1.5.
- Don't use aclocal: it's written by hand.
- * aclocal.m4: m4_include all the files instead of being built by
- aclocal.
- * bootstrap: Help automake find the AC_SUBSTs and AM_CONDITIONALs
- until it reads the traces by itself.
- * configure.in: Require Autoconf 2.42c as we are now using
- AC_CONFIG_TESTDIR instead of AT_CONFIG.
- Catch unexpanded `jm_' macros.
- * config/atconfig.m4: Remove.
- * config/error.m4: new.
- * config/Makefile.am: Ship the files included by aclocal.m4.
- * tests/Makefile.am (TESTSUITE_SOURCES): Rename as...
- (TESTSUITE_AT): this, to please Automake.
- (TESTSUITE): This target uses autotest/autotest.m4, not
- autotest/general.m4.
- * tests/testsuite.at: Prereq Autotest 2.52c.
- * examples/Makefile.am (pkgdata_DATA): Rename as...
- (dist_pkgdata_DATA): this.
- * doc/Makefile.am (man_MANS): Rename as...
- (dist_man_mans): this.
-
-2001-08-20 Gary V. Vaughan <gary@gnu.org>
-
- * m4/system.h [cygwin*]: Thanks to Paul Sokolovsky and
- Robert Collins, building on Cygwin no longer requires Windows
- import and export symbol decorations.
- * m4/m4module.h (M4_SCOPE) [cygwin*]: Deleted all occurences.
- * m4/error.h (M4_SCOPE) [cygwin*]: Ditto.
- * m4/debug.c (M4_GLOBAL_DATA) [cygwin*]: Ditto.
- * m4/error.c (M4_GLOBAL_DATA) [cygwin*]: Ditto.
- * m4/input.c (M4_GLOBAL_DATA) [cygwin*]: Ditto.
- * m4/macro.c (M4_GLOBAL_DATA) [cygwin*]: Ditto.
- * m4/output.c (M4_GLOBAL_DATA) [cygwin*]: Ditto.
- * m4/utilty.c (M4_GLOBAL_DATA) [cygwin*]: Ditto.
- * m4/xmalloc.c (M4_GLOBAL_DATA) [cygwin*]: Ditto.
- * configure.in (LIBM4_DLL_IMPORT) [cygwin*]: Don't set this
- anymore.
- * src/Makefile.am (AM_CPPFLAGS) [cygwin*]: Don't use it either!
- * modules/Makefile.am (AM_CPPFLAGS) [cygwin*]: Ditto.
-
-2001-08-20 Gary V. Vaughan <gary@gnu.org>
-
- Ansify the source. Previously we had a mix, where my code was
- in a K&R compatible style, and the preexisting code was in ANSI
- style. Nothing is lost wrt release 1.4 by reverting to ANSI,
- and now the code base is much cleaner.
-
- * m4/system.h: Remove M4_PARAMS macro and all users. Remove
- VOID macro and all users.
- * m4/m4module.h: Ansify function prototypes and headers.
- * m4/builtin.c: Ditto.
- * m4/evalparse.c: Ditto.
- * m4/input.c: Ditto.
- * m4/macro.c: Ditto.
- * m4/module.c: Ditto.
- * m4/output.c: Ditto.
- * m4/path.c: Ditto.
- * m4/symtab.c: Ditto.
- * m4/utility.c: Ditto.
- * modules/format.c: Ditto.
- * modules/gnu.c: Ditto.
- * modules/m4.c: Ditto.
- * modules/mpeval.c: Ditto.
- * src/freeze.c: Ditto.
- * src/m4.h: Ditto.
- * src/main.c: Ditto.
-
-2001-08-20 Akim Demaille <akim@epita.fr>
-
- * config/atconfig.m4: s/EOF/ATEOF/, so that configure can be
- generated with stock 2.52.
-
-2001-08-20 Akim Demaille <akim@epita.fr>
-
- * config/atconfig.m4: New, until part of Autoconf per se.
- * configure.in (AT_CONFIG): Use it.
- Adjust.
- * tests/mkconfig.sh, tests/atconfig.in, tests/defs: Remove.
- * tests/atlocal.in: New.
- * tests/generate.awk: For the time being, the empty quadrigraph is
- `@__@'.
- * tests/others.at (changeword, gmp): Check the configuration
- variable against `yes'.
- * tests/testsuite.at (dnl): Allow it, as it's used all over the
- place.
-
-2001-08-20 Akim Demaille <akim@epita.fr>
-
- * m4/utility.c (m4_numeric_arg): Spell out the culprit.
- * modules/m4.c (undivert): Disable the possibility of undiverting
- several files at once: it is not documented, it is inconsistent
- with the other macros, it can be straightforwardly mocked by
- several invocations, and most importantly, it prevents the
- possibility of other kinds of extension.
- Use `m4_numeric_arg'.
-
-2001-08-20 Akim Demaille <akim@epita.fr>
-
- * examples/include.m4: Typo.
- * tests/generate.awk: Really add it.
- * tests/Makefile.am: Adjust.
- * tests/others.at (Discard comments): It sure fails without `-c'.
- (include, undivert): Add -I examples/.
-
-2001-08-20 Akim Demaille <akim@epita.fr>
-
- Use sprintf, not ecft and friends since it is standard, portable,
- simplifies the code, and since the latter is even deprecated
- according to the GNU libc documentation.
-
- * modules/format.c: Drop evct support.
-
-2001-08-19 Gary V. Vaughan <gary@gnu.org>
-
- * config/debug.m4 (M4_AC_CHECK_DEBUGGING): Cleaned up. Don't test
- for `-pipe' here...
- * configure.in: ...do it here instead.
-
- * c-boxes.el: Deleted.
- * m4/builtin.c: Reformat box comments to be closer to GNU
- standards.
- * m4/debug.c: Ditto.
- * m4/eval.c: Ditto.
- * m4/evalparse.c: Ditto.
- * m4/input.c: Ditto.
- * m4/m4module.h: Ditto.
- * m4/macro.c: Ditto.
- * m4/output.c: Ditto.
- * m4/symtab.c: Ditto.
- * m4/utility.c: Ditto.
- * modules/changeword.c: Ditto.
- * modules/format.c: Ditto.
- * modules/gnu.c: Ditto.
- * modules/load.c: Ditto.
- * modules/m4.c: Ditto.
- * modules/modtest.c: Ditto.
- * modules/mpeval.c: Ditto.
- * modules/perl.c: Ditto.
- * modules/shadow.c: Ditto.
- * modules/stdlib.c: Ditto.
- * modules/time.c: Ditto.
- * src/freeze.c: Ditto.
- * src/main.c: Ditto.
-
-2001-08-17 Gary V. Vaughan <gary@gnu.org>
-
- * m4/module.c: Fixup some errors in the description comment.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- * tests/others.at (iso8859): Specify the path to the M4 test file.
- * tests/testsuite.at (AT_CHECK_M4): Normalize the path of input
- files in error messages.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- * tests/testsuite.at (AT_CHECK_M4): Anchor M4PATH in $top_srcdir.
- * tests/others.at: Adjust input files paths.
- * tests/atconfig.in: Set top_builddir.
- * tests/Makefile.am: Adjust.
- `testsuite' is in src, not build.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- * tests/Makefile.am (EXTRA_DIST): Ship generate.awk.
- (generate.at): Install a temporary hack until the actual
- generate.awk is added to the repository.
- * tests/atconfig.in: New.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- Really apply the patch ``Drop Autoconf 2.13 compatibility.''
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- * doc/m4.texinfo: Promote proper quotation.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- Remove the non Autotest tests.
-
- * tests/other-tests/capitalize.test,
- * tests/other-tests/changeword.test,
- * tests/other-tests/comments.test, tests/other-tests/ddivert.test,
- * tests/other-tests/debug.test,
- * tests/other-tests/discard-comments.m4,
- * tests/other-tests/discard-comments.test,
- * tests/other-tests/esyscmd.test, tests/other-tests/exp.test,
- * tests/other-tests/foreach.test, tests/other-tests/forloop.test,
- * tests/other-tests/frozen.m4, tests/other-tests/fstab.test,
- * tests/other-tests/gmp.m4, tests/other-tests/gmp.test,
- * tests/other-tests/hanoi.test,
- * tests/other-tests/import-environment.m4,
- * tests/other-tests/import-environment.test,
- * tests/other-tests/include.test, tests/other-tests/indir.test,
- * tests/other-tests/iso8859.m4, tests/other-tests/iso8859.test,
- * tests/other-tests/misc.test, tests/other-tests/modfreeze.test,
- * tests/other-tests/modpath1.test, tests/other-tests/modpath2.test,
- * tests/other-tests/modpath3.test, tests/other-tests/modpath4.test,
- * tests/other-tests/modtest.test,
- * tests/other-tests/multiquotes.test,
- * tests/other-tests/patsubst.test, tests/other-tests/pushpop.test,
- * tests/other-tests/regexp.test, tests/other-tests/reverse.test,
- * tests/other-tests/shadow.test, tests/other-tests/stackovf.test,
- * tests/other-tests/sync-lines.m4,
- * tests/other-tests/sync-lines.test,
- * tests/other-tests/sysv-args.test, tests/other-tests/trace.test,
- * tests/other-tests/translit.test, tests/other-tests/undivert.test,
- * tests/other-tests/unfrozen.m4, tests/other-tests/unload.test,
- * tests/other-tests/wrap.test: Remove.
-
- * tests/run-test, tests/get-them: Remove.
- * tests/Makefile.am: Adjust.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- others.at no longer depends on other-tests/.
-
- * tests/others.at (stackovf): You're actually...
- (sync-lines): this.
- (modfreeze, modpath1, modpath2, modpath3, modpath4, modtest, shadow)
- (unload.test): Keep their authorship.
- (discard-comments, gmp, import-environment, modfreeze)
- (sync-lines): Embed the input files.
- * tests/stackovf.test: Copy from other-tests/stackovf.test.
- * tests/iso8850.m4: Copy from other-tests/iso8859.m4.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- * doc/m4.texinfo (Esyscmd): Fix the paths in the Vice example.
- (M4exit): Tag the exit status of the example.
- * tests/get-them: Adjust.
- * tests/generate.awk: New, based on get-them.
- * tests/Makefile.am: Adjust to generate `generated.at'.
- * tests/testsuite.at: Adjust.
- (AT_CHECK_M4): Don't overquote. Blush...
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- Start using Autotest. atconfig creation is still lacking.
-
- * examples/patsubst.m4, modules/modtest.m4, modules/shadow.m4,
- * examples/reverse.m4, tests/other-tests/import-environment.m4,
- * tests/other-tests/iso8859.m4: Don't produce trailing blanks.
- * tests/other-tests/import-environment.test: Don't check LANGUAGE
- as it might be `unset', or set to `C'.
- * tests/other-tests/iso8859.test, tests/other-tests/modpath1.test,
- * tests/other-tests/modpath2.test, tests/other-tests/modpath3.test,
- * tests/other-tests/modpath4.test, tests/other-tests/modtest.test,
- * tests/other-tests/patsubst.test, tests/other-tests/reverse.test,
- * tests/other-tests/shadow.test: Adjust.
- * tests/testsuite.at, tests/others.at: New.
- * tests/Makefile.am: Adjust.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- Drop Autoconf 2.13 compatibility.
-
- * configure.in (changeword): No need to undefine it, as anyway if
- it's defined, M4sugar moved it as m4_changeword.
- And anyway, proper quotation is enough.
- (m4_pattern_allow): As it exists in 2.50, just use it.
- (AC_OUTPUT): Split in AC_CONFIG_FILES and AC_CONFIG_COMMANDS.
- Don't handle Gettext's duties, let it handle them.
- * config/gnu-obstack.m4: Use m4_pattern_allow directly.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- * modules/m4.c (m4_dumpdef): Output to stderr, not m4_debug.
- (m4_errprint): Use fputs.
- * doc/m4.texinfo (Invoking m4) <--error-output>: errprint and
- dumpdef are not concerned.
- (Dumpdef, Errprint): Emphasize their insensitivity to
- --error-output.
- * doc/Makefile.am: Add `TAGS' support.
- (MAINTAINERCLEANFILES): Remove texinfo.tex and mdate-sh which are
- in `config/' now.
- * config/Makefile.am (MAINTAINERCLEANFILES): New.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- * modules/Makefile.am (ETAGS_ARGS): New.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- * m4/symtab.c (m4_hack_all_symbols, m4_lookup_symbol): Formatting
- changes.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- * m4/builtin.c (m4_macro_define): Do not reset SYMBOL_TRACED.
-
-2001-08-17 Akim Demaille <akim@epita.fr>
-
- * m4/m4module.h (m4/list.h): Don't include it.
-
-2001-08-16 Gary V. Vaughan <gary@gnu.org>
-
- m4_modules are no more, we use lt_dlhandles directly and let
- latest libltdl features manage the list of loaded modules.
- * acinclude.m4: Regenerated.
- * m4/ltdl.c: Updated from master copy.
- * m4/module.c: Reimplemented to take advantage of advances in
- libltdl.
- * m4/builtin.c (m4_builtin_find_by_name): Traverse loaded module
- list with lt_dlhandle_next.
- (m4_builtin_find_by_func): Ditto.
- (m4_builtin_table_install): Use lt_dlhandle.
- (m4_macro_define): Ditto.
- (m4_macro_table_install): Ditto.
- m4/module.h: Prototype new module management API.
- (m4_modules): No longer required.
- (m4_module_init_t, m4_module_finish_t): POSIX namespace
- violations, renamed to...
- (m4_module_init_func, m4_module_finish_func): ...these,
- respectively.
- (M4INIT_HANDLER): Clean way to declare init functions in modules.
- (M4FINISH_HANDLER): And similarly for finish functions.
- * m4/system.h (_CONC): Used by M4INIT_HANDLER and M4FINISH_HANDLER
- -- Add indirection to the CONC macro so that arguments are
- correctly expanded.
- * modules/modtest.c (m4_init_module): Replaced with M4INIT_HANDLER.
- * modules/shadow.c (m4_init_module): Ditto.
- Due to new init function semantics, be careful to perform the
- initialisation only on first load.
- * modules/perl.c (m4_init_module): Ditto. And Ditto.
- (m4_finish_module): Replaced with M4FINISH_HANDLER.
- Due to new finish function semantics, be careful to perform the
- finalisation only on first load.
- * m4/m4private.h (m4_module): Removed in favour of...
- (m4_module_data): ...structure without all the wrapper fields.
- Instances of this new structure are stored associated lt_dlhandles
- with lt_dlcaller_data_set().
- * m4/builtin.c (m4_builtin_define): Takes a handle argument
- instead of the old module argument.
- (m4_builtin_table_install): Ditto.
- * modules/load.c (m4_resident_module): Removed. This is no
- longer implemented as a magic symbol...
- * modules/m4.c (m4_resident_module): Ditto.
- * modules/load.c (M4INIT_HANDLER): ...the module init function now
- uses the ltdl api to make the module resident.
- * modules/m4.c (M4INIT_HANDLER): Ditto.
- * modules/load.c (builtin_modules): Traverse the loaded module
- list with lt_dlhandle_next.
- (builtin_load): Much simplified in light of the reimplemented
- module loader.
- * src/freeze.c (produce_module_dump): Cleaned up and optimised in
- light of the m4/module.c rewrite.
- (produce_symbol_dump): Ditto.
- (reload_frozen_state): Ditto.
- * m4/list.c, m4/list.h: Files deleted. No longer required.
- * m4/Makefile.am (pkginc_HEADERS): Delete list.h reference.
- (libm4_la_SOURCES): Delete list.c reference.
- * m4/m4private.h (m4_token_data): Add a handle field. This
- eliminates many of the searches to find the handle associated with
- various tokens that are passed between functions.
- (struct m4_symbol): Removed the module field. The
- module association does not belong with the symbol...
- * m4/input.c (struct m4_builtin): ...it belongs with the builtin
- that the module implementation code is from. Added a handle
- field.
- (m4_push_macro): Add a `handle' argument. Changed all callers.
- (init_macro_token): Set the `handle' field for the
- m4_token_data.
- * m4/macro.c (expand_argument): Copy the new handle field during
- reassignment.
- * modules/m4.c (macro_install): Use the new handle field to
- optimise the search for the correct builtin structure, and pass
- the handle details to m4_builtin_define.
-
-2001-08-15 Akim Demaille <akim@epita.fr>
-
- * config/gnu-obstack.m4 (M4_AC_FUNC_OBSTACK): Be sure `m4/' exists
- when creating `m4/obstack.h'.
- * tests/Makefile.am (TESTS_ENVIRONMENT): Pass top_srcdir and
- top_builddir.
- * tests/defs: Make them absolute.
- (CDPATH) Neutralize.
- * tests/gethem: Use them.
-
-2001-08-14 Gary V. Vaughan <gary@gnu.org>
-
- * config/ltmain.sh: Doh! Import again for a quoting fix that
- prevented any regression test from passing.
-
- * m4/m4module.h (obstack.h): Choose between installed version
- and shipped version based on configure tests.
- * src/freeze.c (obstack.h): Ditto.
-
- * acconfig.h: Removed. No longer required.
-
- * bootstrap: Rewritten to play nicely with Autoconf 2.5x.
- * configure.in (MY_NAME, MY_VERSION): Define these once, and feed
- them to AC_INIT and AM_INIT_AUTOMAKE.
- * Makefile.am (AUTOMAKE_OPTIONS): Remove `gnits' which would
- disallow MY_NAME and MY_VERSION arguments to AM_INIT_AUTOMAKE.
- * config/gnu-obstack.m4 (M4_AC_FUNC_OBSTACK): Don't choke on
- shell variable m4_cv_func_obstack_h.
- * tests/defs (M4): Be more careful about relative path to libtool
- script and m4 binary by using $srcdir.
-
- * src/main.c (main): Use lt_dlinsertsearchdir to prepend -M
- optargs to the existing libltdl search path.
- * acinclude.m4: Regenerate from latest libtool,m4 and ltdl.m4.
- * m4/ltdl.c: Updated.
- * m4/ltdl.h: Ditto.
- * config/ltmain.sh: Ditto.
-
-2001-08-11 Gary V. Vaughan <gary@gnu.org>
-
- * src/main.c (main): Add `-b' (for `batch') mode switch to force
- interactive mode off.
-
-2001-08-10 Akim Demaille <akim@epita.fr>
-
- * configure.in: Require Autoconf 2.52.
- (AC_ARG_PROGRAM): Remove, handled by Automake.
- (m4_getopt): Rename as...
- (m4_getopt_h): this.
- Allow the tokens `m4_cv_*', `m4_top_srcdir', and `m4_getopt_h'.
- Undefine `changeword' only if defined.
- * config/gnu-obstack.m4: Require Autoconf 2.52.
- (M4_AC_FUNC_OBSTACK): Rename `m4_obstack' and `m4_obstack_h'.
- Allow this token.
-
-2001-08-09 Yuji Minejima <ggb01164@nifty.ne.jp>
-
- * doc/m4.texinfo: Fix some typos, and apply some small
- clarifications.
-
-2001-08-09 Andreas Schwab <schwab@suse.de>
-
- * src/main.c (main): Fix improper uses of error (missing format
- string).
-
-2001-08-07 Akim Demaille <akim@epita.fr>
-
- Improve `make distcheck'.
-
- * configure.in: Be sure to be able to run `mkconfig.sh' when src
- != build.
- * Makefile.am (dist-hook): Remove, as it is no longer needed.
- * doc/m4.texinfo (Include): Add missing blank.
- * m4/Makefile.am (EXTRA_DIST): Distribute gnu-obstack.h and
- obstack.c.
-
-2001-08-07 Akim Demaille <akim@epita.fr>
-
- * m4/evalparse.c: A better introductory comment.
- * m4/m4module.h (M4_DEBUG_PRINT2): s/M4_debug/m4_debug/.
- * m4/macro.c: Adjust old comments.
- * modules/README: Typo.
-
-2001-08-07 Akim Demaille <akim@epita.fr>
-
- * config/gnu-obstack.m4: New.
-
-2001-08-07 Akim Demaille <akim@epita.fr>
-
- * config/Makefile.am, config/stackovf.m4: New.
- * configure.in, Makefile.am: Adjust.
-
-2001-08-05 gettextize <bug-gnu-utils@gnu.org>
-
- * po/Makefile.in.in: Upgrade to gettext-0.10.39.
- * po/cat-id-tbl.c: Remove file.
- * po/stamp-cat-id: Remove file.
-
-2001-04-08 Roderick Koehle <Roderick.Koehle@infineon.com>
-
- * modules/format.c (format): Formatting for %f was not
- interpreting the position of the decimal point correctly for
- whole numbers.
-
-2000-12-01 Gary V. Vaughan <gary@gnu.org>
-
- * TODO: Removed m4exit bug.
- * modules/load.c (m4_resident_module): Make this module resident.
- * module/m4.c (m4_resident_module): Ditto.
- * m4/modules.c (m4_module_load): Use new ltdl resident modules
- feature to mark modules as resident if they export
- `m4_resident_module' as TRUE.
- (m4_module_unload): Do not remove resident modules, and take care
- with symbol insertion and deletion with resident modules.
- * m4/ltdl.c, m4/ltdl.h: Update to latest unreleased versions to
- use resident modules feature.
-
-2000-11-30 Gary V. Vaughan <gary@gnu.org>
-
- * TODO: Updated. Removed some cruft that has since been fixed
- or implemented. Added some more entries.
- * NEWS: Updated.
- * README: Updated.
- * modules/README: Updated.
- * doc/m4.texinfo: Updated.
-
- * modules/gnu.c (builtin_functions): Make indir orthogonal to
- builtin, in that each is recognised as a macro only with parameters
- (builtin_indir): Passing 0 arguments is now an error, as with
- builtin.
-
- * src/main.c (usage): Added missing description of `-c' option.
-
-2000-11-29 Gary V. Vaughan <gary@gnu.org>
-
- Consolidate the myriad of dispersed test scripts into the
- tests subdirectory. I think I now have all the file where I
- want them, so there shouldn't be anymore upheaval =)O|
- Honest!
- * tests/Makefile.am: Updated to run the new tests added below.
- * tests/other-tests/capitalize.test, tests/other-tests/comments.test,
- tests/other-tests/ddivert.test, tests/other-tests/debug.test,
- tests/other-tests/esyscmd.test, tests/other-tests/exp.test,
- tests/other-tests/foreach.test, tests/other-tests/forloop.test,
- tests/other-tests/frozen.m4, tests/other-tests/fstab.test,
- tests/other-tests/hanoi.test, tests/other-tests/include.test,
- tests/other-tests/indir.test, tests/other-tests/misc.test,
- tests/other-tests/modfreeze.test, tests/other-tests/modpath1.test,
- tests/other-tests/modpath2.test, tests/other-tests/modpath3.test,
- tests/other-tests/modpath4.test, tests/other-tests/modtest.test,
- tests/other-tests/multiquotes.test, tests/other-tests/patsubst.test,
- tests/other-tests/pushpop.test, tests/other-tests/regexp.test,
- tests/other-tests/reverse.test, tests/other-tests/shadow.test,
- tests/other-tests/sysv-args.test, tests/other-tests/trace.test,
- tests/other-tests/translit.test, tests/other-tests/undivert.test,
- tests/other-tests/unfrozen.m4, tests/other-tests/unload.test,
- tests/other-tests/wrap.test: New tests based on the contents
- of the tests removed below.
- * examples/Makefile.am, modules/Makefile.am: Updated to
- reflect removed tests.
- * examples/defs,modules/defs: Removed.
- * examples/capitalize.test, examples/comments.test,
- examples/ddivert.test, examples/debug.test,
- examples/esyscmd.test, examples/exp.test,
- examples/foreach.test, examples/forloop.test,
- examples/fstab.test, examples/hanoi.test,
- examples/include.test, examples/indir.test,
- examples/misc.test, examples/multiquotes.test,
- examples/patsubst.test, examples/pushpop.test,
- examples/regexp.test, examples/reverse.test,
- examples/sysv-args.test, examples/trace.test,
- examples/translit.test, examples/undivert.test,
- examples/wrap.test, modules/frozen.m4, modules/modfreeze.test,
- modules/modpath1.test, modules/modpath2.test,
- modules/modpath3.test, modules/modpath4.test,
- modules/modtest.test, modules/shadow.test,
- modules/unfrozen.m4, modules/unload.test: Removed.
-
- Move the implementation of GMP support for the mpeval() builtin
- into a loadable module that depends on libgmp. mpeval() and
- eval() share a common parser, now in m4/evalparser.c; the code
- in m4/numb.c and m4/numb.h is now physically split between
- m4/eval.c (the eval() backend) and modules/mpeval.c (the
- mpeval() backend), rather than being differentiated by cpp
- macros and multiple inclusion. The mpeval module is always
- built but will generate an diagnostic if it is used from an
- installation that didn't link in the gmp library.
- * modules/Makefile.am: build and install the new mpeval module.
- * modules/mpeval.c: Now contains the former parts of m4/numb.c
- and m4/numb.h that are required for gmp support in mpeval().
- * m4/Makefile.am (libm4_la_SOURCES): Removed evalmp.c.
- * m4/evalmp.c: Removed.
- * m4/m4module.h: Removed conditional prototype for
- m4_mp_evaluate().
- * m4/eval.c: Rewritten. Contains the former parts of m4/numb.c
- and m4/numb.h that do not rely on gmp.
- * m4/evalparse.c: New file, contains the shared parts of the
- eval() and evalmp() parser implementations, and is no longer
- unencumbered by cpp magic to uncover the right parts.
- * m4/numb.h: Removed. It's former contents are split between
- m4/eval.c and modules/mpeval.c.
- * m4/numb.c: ditto.
-
- * tests/other-tests/changeword.test: New test. Rudimentary
- testing of changeword builtin runs only if --wnable-changeword
- was used at configure time.
- * tests/mkconfig.sh: Solaris sed (at least) does not parse nested
- alternation correctly. Split into two expressions to compensate.
- * m4/input.c (m4_input_init): Use m4_ prefix on m4_set_word_regexp.
- * modules/Makefile.am: Build changeword module.
- * modules/changeword.c (m4_macro_table): Define __m4_changeword__
- only when --enable-changeword was passed to configure.
- (builtin_changeword): If --enable-changeword was not used, then
- report that changeword() builtin has no support in m4 binary.
-
-2000-11-28 Gary V. Vaughan <gary@gnu.org>
-
- * src/main.c (main): Fixed a particularly nasty bug is
- user_search_path setting -- the -M flag processing must be
- extremely careful with search path ordering, or else the default
- installed module directory (possibly containing modules from a
- previous release) is placed earlier in the search path than any -M
- arguments (which are relied upon to load uninstalled modules with
- most of the tests in the regresion suite).
-
- * modules/load.c (builtin_load): Nasty hack to prevent adding
- symbols to symtab again if a module is loaded more than once.
- * modules/m4.c (builtin_ifelse): removed unused variable argv0.
-
- * m4/symtab.c (m4_remove_table_reference_symbols): Fixed a
- possible NULL pointer dereference.
-
- * m4/module.c (m4_module_find_by_modname): Renamed from
- m4_module_modname_find. Fixed all references.
- (m4_module_find_by_builtin): New function.
-
- * modules/modfreeze.test: load the `load' module with each
- invocation.
- * src/freeze.c (produce_frozen_state): Simplified in light of
- module field in m4_symbol. Allow a third argument for text macros
- to name the originating module.
- (reload_frozen_state): ditto.
- * m4/m4module.h: Fixup prototypes.
- * m4/builtin.h (m4_builtin_define): Add a module argument so
- that symbols can be registered against the defining module.
- (m4_macro_define): ditto.
- * m4/m4private.h (m4_symbol): Make the module field const to save
- on casting in the rest of the code.
- (SYMBOL_MODULE): New macro.
-
- * m4/symtab.c (m4_remove_table_reference_symbols): Fixed stupid
- symbol reference maintenance bugs when removing a symbol from the
- symtab.
-
- * src/stackovf.c (setup_stackovf_trap): Fixed some memory leaks.
-
-2000-11-27 Gary V. Vaughan <gary@gnu.org>
-
- * configure.in (m4_cv_func_obstack): A better check for whether
- libc has an obstack implementation.
- * m4/Makefile.am (EXTRA_libm4_la_SOURCES): add gnu-obstack.h.
-
- * configure.in (--with-modules): Changed semantics. This
- option is now used to list modules to be preopened.
- * src/m4.h: #include "ltdl.h" unconditionally.
- * src/main.c: Removed all dependencies on WITH_MODULES.
- * src/freeze.c: ditto.
- * modules/Makefile.am: ditto.
- * m4/m4.c (builtin_m4exit): ditto.
- * modules/modpath1.test: ditto.
- * modules/modpath2.test: ditto.
- * modules/modpath3.test: ditto.
- * modules/modpath4.test: ditto.
- * modules/modtest.test: ditto.
- * modules/shadow.test: ditto.
- * modules/unload.test: ditto.
-
- * m4/Makefile.am (libm4_la_SOURCES): Removed obstack.c, since it
- comes up on demand in LTLIBOBJS now.
- * configure.in (getopt_long): Creating and relying on a link for
- getopt.h on hosts with no getopt_long() of thier own works
- correctly now. This is necessary so that callers of getopt_long()
- can simply `#include <getopt.h>': the naive way of doing this
- would end up using our own getopt.h and the installed
- getopt_long(), which is asking for trouble!
- (obstack_init): A similar argument applies to obstack.h and
- obstack_init().
-
- * m4/ltdl.c: Upgraded to latest bleeding edge version again.
- On Solaris-2.5 (at least) the native dlopen implementation
- gets confused about m4.o when looking for module "m4". This
- version always looks for .la an .$lib_ext suffixed names first
- to work around the problem. Sigh.
-
- * po/POTFILES.in: Take account of these file movements.
- * src/Makefile.am (m4_SOURCES): removed eval.c.
- (EXTRA_m4_SOURCES): removed numb.c and numb.h.
- * m4/Makefile.am (libm4_la_SOURCES): added eval.c.
- (EXTRA_libm4_la_SOURCES): added numb.c and numb.h.
- * modules/m4.c (builtin_eval): Use m4_evaluate().
- * m4/eval.c: Moved here from src/eval.c to facilitate
- implementation of eval() builtin as part of the `m4' loadable
- module.
- (m4_evaluate): renamed from evaluate for namespace cleanliness.
- * m4/numb.c: Moved here from src/numb.c, since it is #included
- into eval.c at compile time.
- * m4/m4module.h (m4_evaluate): Added prototype.
- * src/m4.h (evaluate): Removed prototype.
-
-2000-11-25 Gary V. Vaughan <gary@gnu.org>
-
- * modules/perl.c (builtin_perleval): Use PL_na for
- compatibility with perl-5.6.
-
- * src/main.c (main): It is now safe to
- ``m4_module_install("m4")'', without tripping over the m4
- binary itself!
- * m4/ltdl.h, m4/ltdl.c: Upgraded to latest bleeding edge
- versions having fixed the insidious module search order bug.
-
- * m4/Makefile.am (libm4_la_LIBADD): New magic -- we are
- supposed to be using @LIBADD_DL@; @DLLDFLAGS@ is dead.
-
- * configure.in: Figure out whether to use the installed
- getopt.h or the supplied one.
- * src/Makefile.am: ditto.
-
- * po/POTFILES.in: List files in their new positions.
-
- * config/ltmain.sh: This needs to be checked in to match the
- libtool macros copied to acinclude.m4 (until a released
- libtool copes with m4's needs).
- * bootstrap: Run gettextize.
-
-2000-11-24 Gary V. Vaughan <gary@gnu.org>
-
- * AUTHORS: Added my details.
- * TODO: updated.
- * NEWS: updated.
- * bootstrap: temporary update until released libtool catches up.
-
- * All files: Use new GNU GPL copyright blurb with current contact
- address.
-
- * configure.in (LTLIBOBJS): Use canonical code for calculation of
- this variable.
-
- * config: renamed acm4 directory to config to be more like
- other autoconfiscated packages.
-
- * configure.in (M4_AC_CHECK_DEBUGGING): Use it.
- * config/debug.m4: New file implementing configure macros to add
- suitable debug flags to the compiler invocation.
-
- * modules/load.c: New file implementing the ``load'' and
- ``unload'' builtins.
- * tests/get-them: Set the module search directory to the modules
- build directory in generated tests.
- * modules/shadow.test: ditto.
- * modules/modtest.test: ditto.
- * modules/modpath1.test: ditto.
- * modules/modpath2.test: ditto.
- * modules/modpath3.test: ditto.
- * modules/modpath4.test: ditto.
- * modules/modtest.test: ditto.
- * modules/modfreeze.test: ditto.
- * modules/unload.test: ditto.
-
- * modules/changeword.c: New file implementing the ``changeword''
- builtin as a loadable module.
- * modules/mpeval.c: New file implementing the ``mpeval'' builtin
- as a loadable module.
-
- * src/main.c (main): Load the gnu module if m4 was started
- normally -- i.e. without the -G option.
- * modules/gnu.c: New file implementing a new loadable module wuth
- definitions for all the gnu extension builtins.
- * modules/format.c: Moved here from src/format.c. Now included
- directly by gnu.c.
-
- * src/main.c (main): Load the traditional module if m4 was
- started in `no_gnu_extensions' mode.
- * modules/traditional.c: New file implementing the ``unix'' macro,
- required when m4 is executed in traditional mode, as a loadable
- module.
-
- * src/main.c: Renamed from m4.c to avoid confusion with
- modules/m4.c.
- (main): Always load the m4 module.
- * modules/m4.c: New file implementing a new loadable module with
- definitions for all m4 builtins that are not gnu extensions.
-
- * m4/Makefile.am: Adjusted to take new files below into account.
- * m4/m4module.h: Prototypes for exported functions and types moved
- to this directory from the src directory.
- * m4/m4private.h: Moved here from src/m4private.h to facilitate
- the migration of all builtin implementations to loadable modules.
- * m4/macro.c: Moved this file here from the src directory,
- renaming all exported symbols to use the prefix ``m4_''.
- * m4/builtin.c: ditto.
- * m4/module.c: ditto.
- * m4/symtab.c: ditto.
- * m4/debug.c: ditto.
- * m4/input.c: ditto.
- * m4/output.c: ditto.
- * m4/path.c: ditto.
- * m4/ltdl.h, m4/ltdl.c: ditto.
- * m4/utility.c: Odd functions moved here from files in the src
- directory to facilitate builtin migration.
-
-2000-08-12 Gary V. Vaughan <gary@gnu.org>
-
- * src/builtin.c (dump_symbols): Use "Undefined name `%s'" for
- error message, to make translators' jobs a little easier.
- (builtin_builtin): ditto.
- (builtin_traceon): ditto.
- (builtin_traceoff): ditto.
- Reported by Akim Demaille <akim@epita.fr>
-
- * m4/Makefile.am (pkgincdir): Deleted. Use automake's built in
- pkgincludedir instead.
-
- * m4/m4module.h (rquote): Renamed with a prefix of `m4_' since
- it is exported globally. Fixed all references.
- (lquote): ditto.
- (bcomm): ditto.
- (ecomm): ditto.
- (DEF_RQUOTE): Renamed with a prefix of `M4_' since it is exported
- globally. Fixed all references.
- (DEF_LQUOTE): ditto.
- (DEF_BCOMM): ditto.
- (DEF_ECOMM): ditto.
-
-2000-07-28 Gary V. Vaughan <gary@gnu.org>
-
- * NEWS: updated.
- * TODO: updated.
-
- * configure.in (AC_CHECK_FUNCS): added bzero and calloc.
- (AC_OUTPUT): touch stamp-h.in, not stamp-h.
-
- * doc/m4.texinfo: Fixed to work with --html option of makeinfo.
- Removed `Prev', `Next' and `Up' fields of all @nodes now that
- makeinfo calculates them for us, and to make any future
- reorganisation easier.
- (Frozen files): Document format version 2.
- `V' now takes argument `2'.
- `F' can take a single argument if symbol and builtin names
- are the same, or 3 arguments if the builtin is from a module.
- New `S' specification for saving syntax table contents.
- New `M' specification for saving loaded module names.
- * src/freeze.c: Implement them.
- * src/input.c (syntax_code): For interpreting frozen syntax
- state.
-
- * examples/Makefile.am: Add the contents of the WWW directory to
- the distribution.
- * examples/WWW/Makefile: ditto,
- (%.htm): Compares file contents (not just sizes) to determine
- whether a change has occured.
- * examples/WWW/_header.htm: Bumped version number.
- * examples/WWW: Regenerated content.
-
- * m4/Makefile.am (AUTOMAKE_OPTIONS): Support for non-ANSI
- compilers comes much easier without ansi2knr.
- * src/Makefile.am (AUTOMAKE_OPTIONS): ditto.
-
- * m4/list.c: New generic list container type.
- * m4/list.h: Interface to new container type.
- * m4/Makefile.am (pkginc_HEADERS): Install list.h.
- (libm4_la_SOURCES): compile and link list.c.
- * src/builtin.c (builtin_tables): Use list container.
- * src/module.c (symtab): ditto.
- * src/symtab.c (symtab): ditto.
-
- * m4/system.h: New file for common preprocessor definitions.
- * m4/Makefile.am (pkginc_HEADERS): install system.h.
- * m4/error.c: Use system.h in place of inline preprocessor.
- * m4/error.h: ditto.
- * m4/module.c: ditto.
- * m4/module.h: ditto.
- * m4/xmalloc.c: ditto.
-
- * m4/error.h (error_one_per_line): Make M4_GLOBAL_DATA for WIN32
- compatibility.
- * m4/xmalloc.c (xmalloc_exit_failure): ditto.
-
- * m4module.h (syntax_table): Renamed with a prefix of `m4_' since
- it is exported globally. Fixed all references.
- (builtin): ditto.
- (module_init_t): ditto.
- (module_finish_t): ditto.
- (token_data): ditto.
- (SYNTAX_OTHER): Renamed with a prefix of `M4_' since
- it is exported globally. Fixed all references.
- (SYNTAX_IGNORE): ditto.
- (SYNTAX_SPACE): ditto.
- (SYNTAX_OPEN): ditto.
- (SYNTAX_CLOSE): ditto.
- (SYNTAX_COMMA): ditto.
- (SYNTAX_DOLLAR): ditto.
- (SYNTAX_ACTIVE): ditto.
- (SYNTAX_ESCAPE): ditto.
- (SYNTAX_ALPHA): ditto.
- (SYNTAX_NUM): ditto.
- (SYNTAX_ALNUM): ditto.
- (SYNTAX_LQUOTE): ditto.
- (SYNTAX_RQUOTE): ditto.
- (SYNTAX_BCOMM): ditto.
- (SYNTAX_ECOMM): ditto.
- (SYNTAX_VALUE): ditto.
- (SYNTAX_MASKS): ditto.
- (IS_OTHER): ditto.
- (IS_IGNORE): ditto.
- (IS_SPACE): ditto.
- (IS_OPEN): ditto.
- (IS_CLOSE): ditto.
- (IS_COMMA): ditto.
- (IS_DOLLAR): ditto.
- (IS_ACTIVE): ditto.
- (IS_ESCAPE): ditto.
- (IS_ALPHA): ditto.
- (IS_NUM): ditto.
- (IS_ALNUM): ditto.
- (IS_LQUOTE): ditto.
- (IS_RQUOTE): ditto.
- (IS_BCOMM): ditto.
- (IS_ECOMM): ditto.
- (TOKEN_EOF): ditto.
- (TOKEN_NONE): ditto.
- (TOKEN_STRING): ditto.
- (TOKEN_SPACE): ditto.
- (TOKEN_WORD): ditto.
- (TOKEN_SIMPLE): ditto.
- (TOKEN_MACDEF): ditto.
-
- * m4/m4module.h (voidstar): Removed in favour of `VOID' for
- consistency. Fixed all references.
- (STRING): Renamed to `m4_string' for consistency, and because if
- is exported globally. Fixed all references.
- (token_type): Renamed to `m4_token_t' for the same reasons.
- (token_data_type): Renamed to `m4_token_data_t' for the same
- reasons.
-
- * m4/m4module.h (XCALLOC): Wrapper macro which handles type
- sizes.
- (XMALLOC): ditto.
- (XREALLOC): ditto.
- (XFREE): Wrapper macro which avoids freeing NULL pointers.
-
- * m4/m4module.h (m4_macro): New type for module defined user
- macros.
- * modules/modtest.c (m4_macro_table): Define module user macros.
- * modules/shadow.c (m4_macro_table): ditto.
-
- * m4/m4module.h (M4BUILTIN_HANDLER): For defining handlers
- declared with M4BUILTIN.
-
- * m4/xmalloc.c: Use memset if bzero is not available when
- emulating calloc with malloc.
- (xcalloc): Fallback to malloc/bzero if calloc is not available.
- (xfree): Added for consistency. Will not try to free NULL
- pointers.
- * src/m4.c (xfree): Deleted in favour of the above.
- * m4/xmalloc.c (WITH_DMALLOC): preprocess away the entire file if
- linking with libdmalloc.
- * m4/xstrdup.c (WITH_DMALLOC): ditto.
-
- * modules/frozen.m4: New test case.
- * modules/unfrozen.m4: ditto.
- * modules/modfreeze.test: New test.
- * modules/unload.test: ditto.
- * modules/Makefile.am (EXTRA_DIST): Distribute them.
- (TESTS): Use them.
- * modules/modpath1.test: Don't try this test if module support is
- not compiled in.
- * modules/modpath2.test: ditto.
- * modules/modpath3.test: ditto.
- * modules/modpath4.test: ditto.
- * modules/modtest.test: ditto.
- * modules/shadow.test: ditto.
-
- * modules/perl.c: New module.
- * modules/perl.m4: Example of using it.
- * modules/Makefile.am (perl_la_SOURCES): Build new perl module.
-
- * src/m4.c (main): Assume interactive mode if STDIN is connected
- to a tty.
- Changed startup sequence slightly so that syntax is not
- initialised from here when loading a frozen file.
-
- * src/builtin.c: Much improved macro definition style.
- * src/m4private.h: Internal structures for m4_builtin and
- m4_macro instances. These are not exposed to module writers.
- * src/module.c (module_modname_find): Find a module structure
- from the its name.
- (make_macro_table): Build an internal macro table from a external
- definition.
- (make_builtin_table): Build an internal builtin table from an
- external definition.
-
- * src/module.c (module_unload): Be extremely careful to remove
- builtins and macros that match the module being unloaded -- no
- longer assume that the top element can be removed incase another
- odule defines an identical name.
- * src/symtab.c (remove_table_reference_symbols): remove all symbol
- table entries which refer to a given builtin table.
- * src/builtin.c (remove_tables): Use it!
-
-2000-07-13 Thomas Tanner <tanner@ffii.org>
-
- * Makefile.am (SUBDIRS): we need modules/ for "make dist"
- * acm4/modules.m4: deleted
- * bootstrap: don't libtoolize libltdl!
- * configure.in: AC_SUBST INCLTDL and LIBLTDL, -with-modules flag:
- if set, enable WITH_MODULES and add modules to DLPREOPEN
- * examples/misc.test: redirect standard output
- * lib/Makefile.am: don't use DLLDFLAGS
- * lib/m4module.c: include necessary headers to silence GCC -Wall
- * lib/m4regex.c: fixes to silence GCC -Wall
- * modules/Makefile.am: don't use DLLDFLAGS, add INCLTDL to INCLUDES,
- build modules conditionally
- * modules/shadow.c: define symbol aliases before using them
- * modules/test.c: define symbol aliases before using them
- * po/de.po: update translation
- * src/Makefile.am: delete pathconf.h, set MODULE_PATH to
- pkglibexecdir, don't use DLLDFLAGS, add INCLTDL to INCLUDES and
- LIBLTDL to LIBS.
- * src/m4.c: initialize libltdl's preloaded symbols via
- LTDL_SET_PRELOADED_SYMBOLS
- * src/module.c: libltdl's memory management must be initialized
- before calling lt_dlinit!, fix warnings
-
-2000-01-18 Gary V. Vaughan <gary@gnu.org>
-
- * README: Caveat about nls not supported by dll architecture on
- Windows.
-
- * TODO (MODULE SPECIFIC ISSUES): more ideas for the future.
-
- * tests/Makefile.am (stamp-TESTS): now works with VPATH.
- * src/Makefile.am (m4_LDADD): use $(builddir) for VPATH.
- * modules/Makefile.am (LIBS): ditto.
- (INCLUDES): search $(top_srcdir) (for eg. <m4/error.h>) and then
- $(top_srcdir)/m4 (for only <m4module.h>).
- * modules/shadow.test: fixed for VPATH.
- * modules/modtest.test: ditto.
- * modules/modpath4.test: ditto.
- * modules/modpath3.test: ditto.
- * modules/modpath2.test: ditto.
- * modules/modpath1.test: ditto.
-
- * modules/time.test: Removed due to timezone dependence,
- * modules/Makefile.am (TESTS): Removed time.test.
-
- * configure.in: Use $3 of AC_DEFINE so that we can,,,
- * acconfig.h: Remove everything except the gettext parameters.
- * acm4/gmp.m4: Add a serial number, and take advantage of $3 of
- AC_DEFINE.
- * acm4/ltdl.m4: Updated to latest from libtool cvs.
- * acm4/modules.m4: Remove code which duplicates ltdl.m4 and
- increment serial number.
-
- * Makefile.am (SUBDIRS): Moved @MODULES_DIR@ to compile before
- src dir and immediately after libm4 is built for confidence that
- it doesn't rely on the src directory.
- (SUBDIRS): Moved doc dir to the end since helptoman.pl and
- makeinfo stop the build on cygwin (because they don't work).
-
- * src/m4.h: use GNU standard #if HAVE_CONFIG_H ideom.
-
- * m4/m4private.h: ...is not a public header, so moved to src.
- Add `#include <config.h>', `#define _COMPILING_M4' and
- `#include "m4.h".
- * m4/Makefile.am (noinst_HEADERS): remove m4private.h.
- * src/Makefile.am (noinst_HEADERS): add m4private.h.
- * src/builtin.c: `#include "m4private.h"' now takes care of the
- above. Duplicates removed.
- * src/debug.c: ditto.
- * src/eval.c: ditto.
- * src/evalmp.c: ditto.
- * src/format.c: ditto.
- * src/freeze.c: ditto.
- * src/input.c: ditto.
- * src/m4.c: ditto.
- * src/macro.c: ditto.
- * src/module.c: ditto.
- * src/numb.h: ditto.
- * src/output.c: ditto.
- * src/path.c: ditto.
- * stackovf.c: ditto.
- * symtab.c: ditto.
-
- * po/POTFILES.in: compensate for renaming of lib/*.
- * m4/Makefile.am (CLEANFILES): @EXEEXT@ left libtool wrapper behind.
- (INCLUDES): Look first in $(top_srcdir) (for eg. <m4/error.h>),
- and then in $(top_srcdir)/lib (for eg. "m4private.h").
- * src/Makefile.am (m4_LDADD): replace libi/libm4.la with
- m4/libm4.la.
- * m4/m4error.h: Renamed error.h, for installation to
- $prefix/include/m4..
- * m4/m4obstack.h: Renamed obstack.h, for same reason.
- * m4/m4regex.h: Renamed regex.h, for same reason.
- * m4/m4error.c: Renamed error.c, and use #include "error.h".
- * m4/m4obstack.c: Renamed obstack.c, and fix #includes.
- * m4/m4regex.c: Renamed regex.c, and fix #includes.
-
- * lib: moved to m4 to easily support header installation to
- $prefix/include/m4.
- * Makefile.am (SUBDIRS): renamed lib dir to m4.
- * configure.in (AC_OUTPUT): reference m4/Makefile.in.
- * acm4/regex.m4: Point to m4/regex.c.
-
- * examples/foreach.m4: Sanitise quoting.
- * examples/foreach.test: New torture test.
- From Akim Demaille <akim@epita.fr>
-
-2000-01-17 Gary V. Vaughan <gary@gnu.org>
-
- * src/ltdl.c: Use access() to abort doomed module load attempts
- if module file does not exist.
-
- * src/Makefile.am (m4_SOURCES, EXTRA_SOURCES): getopt.o and
- getopt1.o will already be used if appropriate, so I moved getopt.c
- and getopt1.c from m4_SOURCES to EXTRA_SOURCES.
-
- * modules/modpath1.test: Use correct filename in header line.
- * modules/modpath2.test: ditto.
- * modules/modpath3.test: ditto.
- * modules/modpath4.test: ditto.
-
- Without these changes lt_dlopen("test") attempts to
- LoadLibrary("/bin/test") on Windows, which although harmless
- generates a spurious error message which spoils most of the tests:
- * modules/Makefile.am (EXTRA_DIST): s/test.m4 /modtest.m4 /
- (TESTS): s/test.test /modtest.test /
- (pkglibexec_LTLIBRARIES): s/test.la /modtest.la /
- (test_la_SOURCES, test_la_LDFLAGS): renamed to use modtest.
- * modules/modpath1.test: s/test.m4 /modtest.m4 /
- * modules/modpath2.test: ditto.
- * modules/modpath4.test: ditto.
- * modules/modpath3.test: s/-m test /-m modtest /
- * modules/shadow.m4: use {un,}loadmodule(`modtest').
-
-2000-01-16 Gary V. Vaughan <gary@gnu.org>
-
- * src/ltdl.c (find_file): Updated to new version with fixed memory
- allocation bug in `next'.
- * src/ltdl.h: updated to match.
-
- * modules/Makefile.am: Cleaned up and reordered.
-
-2000-01-16 René Seindal <rene@seindal.dk>
-
- * modules/Makefile.am (TESTS): New tests for the module system.
-
- * modules/*.test: New files.
-
- * src/m4.c (main): Added call to module_init().
- Treats -M and -m as the arguments -D -U and -t, ie deferred.
-
- * src/m4.h: Added declaration of module_init().
-
- * src/module.c (module_init): No longer static
-
- * modules/Makefile.am ({test,shadow,time,stdlib}_la_LDFLAGS):
- Added to shut up automake about non standard libtool library
- names.
-
- * src/module.c: Disabled DEBUG by default.
-
- * modules/README: Changed example from unload.m4 to shadow.m4
-
- * modules/shadow.m4: Renamed from unload.m4
-
- * modules/Makefile.am (EXTRA_DIST): Removed unload.m4.
-
- * src/m4.c (main): Functionality for -m and -M were reversed.
- Fixed.
-
-2000-01-12 Gary V. Vaughan <gary@gnu.org>
-
- * doc/help2man.pl: updated to version 1.020.
-
- * lib/COPYING.LIB: updated to version 2.1.
-
- * lib/m4module.h: restructure the M4_SCOPE code to work when
- creating a dll which links with libm4.la and both DLL_EXPORT
- (for the new dll) and LIBM4_DLL_IMPORT (for m4module.h) are
- both defined.
-
-2000-01-11 Gary V. Vaughan <gary@gnu.org>
-
- Merged the following changes from my tree:
-
- 1999-06-15 Gary V. Vaughan <gary@gnu.org>
-
- * configure.in (AC_LIBTOOL_WIN32_DLL): Declare that m4 has been
- ported to compile shared libs.
-
- * configure.in (LIBM4_DLL_IMPORT): Discover whether we need to
- use `__declspec(dllimport)' when linking libm4.la on win32.
- * src/Makefile.am (m4_LDFLAGS): Use dllimport if necessary.
-
- * configure.in (M4OBJS): Discover whether we need the shipped
- implementation of getopt_long.
- * src/Makefile.am (m4_LDADD): Link the getopt objects into the
- main binary here, as opposed to the module library in lib/libm4.la.
-
- 1999-06-14 Gary V. Vaughan <gary@gnu.org>
-
- * modules/README: Updated to describe the improved libltdl based
- module scheme.
- * README (cygwin): Added some compilation notes for building m4
- correctly under cygwin.
- * TODO: Cleaned out the entries for the module system since they
- are now implemented.
-
- * *.[ch]: __P is in the compiler's reserved namespace, so replaced
- all instances of __P with M4_PARAMS.
-
- * lib/getdate.h: removed unreferenced file.
-
- * lib/m4private.h: New file to define the private interface to the
- token_data struct, which must be shared between m4module.c, and
- builtin.c but not exported to modules built from the installed
- m4module.h since it's size changes depending on compile time
- options.
-
- * src/m4.h: Lots of stuff moved to lib/m4module.h.
-
- * lib/m4module.h: New file to define the interface available when
- compiling m4 modules.
- * lib/m4module.c: Moved parts of builtin.c, and m4.c which are
- necessary for module compilation into this new file.
-
- * lib/Makefile.am (include_HEADERS): install headers (renamed to
- avoid nameclash with other system headers) necessary for compiling
- modules.
- (libm4_la_SOURCES): always include error.c, obstack.c and regex.c
- so that modules can include the (renamed) installed headers and
- be guaranteed a matching implementation.
- * lib/m4error.h: renamed from error.h.
- * lib/m4obstack.h: renamed from obstack.h.
- * lib/m4regex.h: renamed from regex.h.
- * configure.in (AC_REPLACE_FUNCS): Don't look for a system
- implementation, simply include the shipped version
- unconditionally, otherwise it is hard for a module to know
- whether the m4obstack.h header it is using matches the
- implementation it ends up linking against.
- (jm_WITH_REGEX): Include regex into libm4 unconditionally for
- the same reason.
-
- 1999-05-18 Gary V. Vaughan <gary@gnu.org>
-
- * examples/misc.test: Don't run this test on machines which don't
- have a root user in /etc/passwd (e.g. cygwin).
-
- * tests/get-them (/^@example$/): Error messages might have a
- ``.exe'' suffix to the program name, or else use the libtool
- ``.libs/lt-m4'' binary, or generally have an unexpected path. All
- of these cases are now catered for when comparing error messages
- in generated tests.
- * tests/other-tests/*.test: ditto.
- * examples/*.test: ditto.
-
- * tests/defs (M4): use libtool execute mode.
- * examples/defs (M4): ditto.
-
- * tests/get-them (END): explicitly close any open file.
- (printthem): In a regular expression, '{' is the start of a repeat
- count! Use `[{]' for a literal open brace.
- (/^@node /): Don't use substr on a string shorter than the trim
- length.
-
- 1999-05-17 Gary V. Vaughan <gary@gnu.org>
-
- * configure.in (LTLIBOBJS): calculated from LIBOBJS, and
- substituted.
- (AC_LIBTOOL_DLOPEN): declare that this package will use dlopen.
-
-2000-01-10 Andreas Schwab <schwab@suse.de>
-
- * tests/other-tests/gmp.test: Find config.sh in build directory.
-
- * configure.in: Find tests/mkconfig.sh in $srcdir.
-
- * configure.in: Define HAVE_SIGINFO_T if siginfo_t is defined in
- <signal.h> (for SUS2 compliant systems).
-
- * src/stackovf.c: Check for HAVE_SIGINFO_T in addition to
- HAVE_SIGINFO_H.
-
-2000-01-10 René Seindal <rene@seindal.dk>
-
- * Prerelease 1.4o.
-
- * TODO, NEWS: Cleaned up and updated.
-
- * src/m4.c (main): New variable exit_status for exit status in
- case of unreadable files. Now m4 will exit with EXIT_FAILURE if a
- file cannot be read instead of EXIT_SUCCESS.
-
- * src/builtin.c (m4_indir): Changed error message to help
- translators (from Akim Demaille <demaille@inf.enst.fr>).
-
- * lib/obstack.[hc], getopt*.[ch]: Updated to newest version from
- Cygnus.
-
- * lib/error.[hc], lib/regex.[hc], lib/strtol.c: Updated to version
- from glic 2.1.2.
-
- * src/input.c (match_input): Reordering of code, to avoid multiple
- calls to push_string_init() from obstack_grow(), which can happen
- with some compilers (found and fixed by James Bonfield
- <jkb@mrc-lmb.cam.ac.uk>).
-
- * src/stackovf.c: Added prototypes for ultrix.
- (setup_stackovf_trap): Added __P to cast.
- (Both reported by John David Anglin <dave@hiauly1.hia.nrc.ca>)
-
-2000-01-09 René Seindal <rene@seindal.dk>
-
- * doc/m4.texinfo (Changequote): Added comment about changing
- quotes when the old quote is a part of the new.
-
- * src/builtin.c (expand_ranges): Added break after trailing dash.
- This caused misbehavious on some systems (found and fixed by Akim
- Demaille <demaille@inf.enst.fr>).
-
- * AUTHORS: Thomas Tanner included
-
- * acconfig.h: Added entry for ss_sp (see below).
-
- * configure.in (use_stackovf): Added check for stack_t with member
- ss_base instead of ss_sp (BSDI notably). (Reported by Paul Eggert
- <eggert@twinsun.com>).
-
- * doc/m4.texinfo (Frozen files): Added a simpler example for
- generating frozen files from several input files.
-
-1999-11-14 Paul Eggert <eggert@twinsun.com>
-
- * po/POTFILES.in: Add lib/getopt.c, lib/obstack.c,
- lib/regex.c, lib/xmalloc.c.
-
-1999-11-10 René Seindal <rene@seindal.dk>
-
- * Makefile.am (ACLOCAL_AMFLAGS): Passes -I acm4 to aclocal.
-
- * src/module.c: reindented.
- (module_load): return if this is a repeated load of same module.
- (module_init): slight change of logic to avoid repeated
- initialisation debug messages.
-
- * Makefile.am (DIST_SUBDIRS): Added to ensure modules/ is included
- in the distribution.
-
- * modules/Makefile.am (test_la_LDFLAGS): set to -module to silence
- automake warnings about missing lib prefix.
- (time_la_LDFLAGS): ditto
- (stdlib_la_LDFLAGS): ditto
-
-1999-11-10 Paul Eggert <eggert@twinsun.com>
-
- * src/m4.h: Include error.h, since our macros use error.
- * src/m4.c: Don't need to include error.h.
-
-1999-11-09 Paul Eggert <eggert@twinsun.com>
-
- * src/m4.h (voidstar): Define to void * if __STDC__ is defined
- and zero, as Solaris 7 cc does.
- (bcopy): Remove macro; no longer needed with new obstack.h.
-
- * src/output.c (freeze_diversions): Don't assume that a
- diversion size can fit in `int'. Check for diversion file
- size too large to be printed with `unsigned long'.
-
- * src/Makefile.am (CFLAGS): Omit -Wall.
-
- * src/stackovf.c (setup_stackovf_trap): Remove cast to unsigned.
-
- * src/debug.c (trace_format):
- Use ANSI C if (defined __STDC__ && __STDC__) || defined PROTOTYPES.
-
- * src/freeze.c (produce_frozen_state):
- Don't assume string lengths fit in int.
-
-1999-10-13 René Seindal <rene@seindal.dk>
-
- * po/cs.po: Czech translation added.
-
- * po/sv.po: Updated Swedish translation.
-
- * po/ru.po: Updated Russian translation.
-
- * po/pl.po: Updated Polish translation.
-
- * po/el.po: Greek translation added.
-
-1999-10-13 René Seindal <rene@seindal.dk>
-
- * configure.in (ALL_LINGUAS): Added Greek translation (el).
- (ALL_LINGUAS): Added Czech translation (cs).
-
-1999-03-30 Gary V. Vaughan <gary@gnu.org>
-
- * src/builtin.c: moved module loading functions into...
- * src/module.c: entirely new implementation using libltdl.
- * po/POTFILES.in: added src/module.c.
- * modules/Makefile.am (LTLIBRARIES): Removed lib prefix as these
- are modules, not linktime libraries.
- (LDFLAGS): added -no-undefined -module and -avoid-version flags.
- * modules/stdlib.c (m4_macro_table): use <name>_LTX collision
- avoidance on exported symbols.
- * modules/test.c (m4_macro_table, m4_init_module,
- m4_finish_module): ditto.
- * modules/time.c (m4_macro_table): ditto.
-
- * modules/time2.m4: new file which requires command line loading
- of modules.
- * src/m4.c (--load-module): dynamically load named runtime module
- into running executable before reading the source.
- (--module-directory): prepend a directory to the module search
- path.
- (module_init()): Do this the first time we load a module instead;
- if the module subsystem is broken normal m4 scripts can still run.
- * src/m4.h (install_builtin_table): is now exported.
-
-1999-03-26 Gary V. Vaughan <gary@gnu.org>
-
- * src/module.c: removed. No longer required.
- * po/POTFILES.in: removed src/module.c.
-
- * Makefile.am (MAINTAINERCLEANFILES): Remove all the files that
- the bootstrap script can recreate.
- * acm4/Makefile.am (MAINTAINERCLEANFILES): ditto.
- * doc/Makefile.am (MAINTAINERCLEANFILES): ditto.
- * examples/Makefile.am (MAINTAINERCLEANFILES): ditto.
- * lib/Makefile.am (MAINTAINERCLEANFILES): ditto.
- (AUTOMAKE_OPTIONS): reduced strictness to allow COPYING.LIB.
- * modules/Makefile.am (MAINTAINERCLEANFILES): ditto.
- * src/Makefile.am (MAINTAINERCLEANFILES): ditto.
- * tests/Makefile.am (MAINTAINERCLEANFILES): ditto.
-
- * acinclude.m4: removed. `aclocal -I acm4' handles this much
- better.
- * acm4/Makefile.am (ACINCLUDE_M4): ditto.
- * acm4/gettext.m4: removed. It causes a multiple definition vs.
- the installed gettext.m4 file when running aclocal.
-
-1999-03-25 Gary V. Vaughan <gary@gnu.org>
-
- * configure.in (AM_INIT_AUTOMAKE): bumped version number to
- distinguish this from the last prerelease.
- (AC_LIBLTDL_CONVENIENCE): build libltdl as a convenience library
- in its own subdirectory.
-
- * modules/Makefile.am (*_SOURCES): renamed to use libtool's "no
- lib prefix on a module" feature.
- (LDFLAGS): Added `-module -avoid-version' flags to build
- versionless module libraries.
- * src/builtin.c (m4_load_module): use libltdl.
- (module_unload_all): use libltdl.
- * src/m4.c (module_init): initialise module loading on demand for
- better diagnostics, and so that m4 will still work even if
- the module code is broken.
- * src/m4.h (module_init): removed. No longer relevant.
- * modules/stdlib.c (m4_macro_table): use stdlib_LTX_ prefix on
- exported symbols for compatibility with dlpreopening.
- * modules/test.c (m4_macro_table, m4_init_module,
- m4_finish_module): ditto.
- * modules/time.c (m4_macro_table): ditto.
-
- * bootstrap: New file. Runs all the autoutils in the right order
- after a fresh checkout, or a make maintainer-clean.
-
-1999-02-18 Akim Demaille <demaille@inf.enst.fr>
-
- * src/builtin.c (dump_symbols): New function, factoring common
- content of m4_dumpdef and m4_symbols.
- (m4_dumpdef): Use it.
- (m4_symbols): New function, implementing `symbols'. Use it.
- * doc/m4.texinfo: Fixed missing commas after @xref, so that the
- file compile with modern makeinfo.
- (Symbols): New node, documenting symbols.
- (direntry): Modernize.
-
-1998-12-11 René Seindal <rene@seindal.dk>
-
- * src/builtin.c (predefined_tab): New predefined macros
- __m4_changeword__, __m4_gmp__ and __m4_modules__ for testing for
- configure time options.
-
-1998-12-01 Andreas Schwab <schwab@issan.cs.uni-dortmund.de>
-
- * src/module.c (module_try_load): Don't try to be clever and
- overwrite argument string. Instead allocate all constructed
- strings locally, since they can have arbitrary lengths. Make
- arguments pointers to const.
- (module_search): Simplify due to above change.
-
-1998-11-29 René Seindal <rene@seindal.dk>
-
- * Prerelease 1.4n.
-
- * tests/Makefile.am (OTHER_TESTS, OTHER_FILES): New tests.
-
- * tests/other-tests/import-environment.{m4,test}: New test.
-
- * tests/other-tests/discard-comments.{m4,test}: New test.
-
- * doc/m4.texinfo (Invoking m4): Updated for --discard-comments.
-
- * src/m4.c (main): New option -c --discard-comments.
- New global variable discard_comments.
-
- * src/m4.h (token_type): New TOKEN_NONE for tokens to be
- discarded, ie never returned from next_token().
- Added declaration of discard_comments.
-
- * src/input.c (next_token): Now loops until token type is not
- TOKEN_NONE. Comments are now given this type when comments should
- be discarded.
-
- * doc/m4.texinfo (Invoking m4): Updated for --import-environment
- and mpeval.
-
-1998-11-28 René Seindal <rene@seindal.dk>
-
- * src/m4.c (main): New option --import-environment (no single
- letter option).
-
- * When configured with --with-gmp both the normal (fast) eval()
- and the gmp aware mpeval() are defined. To restore previous
- bahaviour use "define(`eval', defn(`mpeval'))".
-
- * tests/other-tests/gmp.m4: Changed to use mpeval().
-
- * src/evalmp.c: New file for compiling eval.c as gmp aware.
- Just defines USE_GMP if WITH_GMP is defined and includes eval.c.
-
- * src/eval.c: Now includes "numb.c" directly. Everything in this
- file must by static, except evaluate(), which is changed to
- mp_evaluate() if USE_GMP in force.
-
- * src/numb.c: Changed to be included by eval.c instead of being
- compiled separately. Everything is declared static.
-
- * src/numb.h: Removed declarations of functions, as numb.c is now
- included by eval.c.
-
- * src/builtin.c: Declaration of m4_mpeval() added.
- Inserted `mpeval' in builtin table.
- (do_eval): New function with common code for m4_eval and m4_mpeval.
- (m4_mpeval): New function for gmp version of eval.
-
- * src/m4.h: Declaration of mp_evaluate().
-
- * src/Makefile.am (m4_SOUCES): Includes mpeval.c.
- (EXTRA_m4_SOURCES): Now has numb.c and numb.h
-
- * src/m4.c (main): m4 --version also shows which options were used
- for compilation, such as: "GNU m4 1.4n (options: modules gmp)"
-
-1998-11-27 René Seindal <rene@seindal.dk>
-
- * Error messages now always print program name before input file
- name as specified by GNU coding standards. Reported by Akim
- Demaille <demaille@inf.enst.fr>.
-
- * doc/m4.texinfo (Include): Change due to changed error message
- format.
- (Eval): Do.
-
- * tests/get-them: Minor change to sed script due to changed error
- message format.
-
- * src/m4.c (print_program_name): New func used to print program
- name, input file and line number in error (). Used as an
- error_print_progname handler.
- (reference_error): Removed.
- (main): Assigns error_print_progname.
-
- * src/m4.h (M4ERROR): Removed reference_error ().
-
-1998-11-25 René Seindal <rene@seindal.dk>
-
- * Updated to libtool 1.2b.
-
- * src/builtin.c (install_builtin_table): Added braces to avoid
- warning of ambiguous 'else'.
-
- * src/module.c: Inserted search path code from path.c modified to
- use new interface.
- (module_init): Configured default path used only if M4MODPATH is
- not set.
- (module_try_load): Now reads libMODULE.la as generated by libtool
- for actual module name.
- (module_load): Gives better error messages on failure.
-
- * src/m4.h: Added declarations of structures and functions for
- generic search path handling.
-
- * src/path.c: Removed all module specific code and introduced new
- functions of more generic search path handling.
-
-1998-11-24 René Seindal <rene@seindal.dk>
-
- * configure.in: Defines INTLINCL to -I$(top_srcdir)/intl if using
- included gettext, as <libintl.h> might not be found
- otherwise. Reported by Andrew Bettison <andrewb@zip.com.au>.
-
-1998-11-22 René Seindal <rene@seindal.dk>
-
- * src/output.c (insert_diversion): Fixed bug that might cause m4
- to read from standard output! Triggered by input
- 'divert(1)undivert(0)'. Test for divnum>0 changed to divnum>=0,
- so now 'undivert(0)' does nothing.
-
-1998-11-18 René Seindal <rene@seindal.dk>
-
- * Prerelease 1.4m.
-
- * src/input.c (set_word_regexp): Fixed a bug, where word_regexp
- could be changed when compiling a illegal regexp, causing later
- use of the regexp to dump core.
-
- * src/module.c (module_load): Changed error message to conform to
- standards.
-
- * src/m4.c (usage): Added message about reporting bugs.
-
- * doc/m4.texinfo (Changeword): Corrected a wrong example.
- (Changeword): Added note about the type of regexps used.
-
- * ltconfig, ltmain.sh: New files from Libtool 1.2.
-
- * configure.in: Added calls to AM_ENABLE_SHARED, AM_DISABLE_STATIC
- and AM_PROG_LIBTOOL.
-
- * acm4/modules.m4 (AM_WITH_MODULES): Redone completely to work
- with libtool.
-
- * modules/Makefile.am: Changed completely to compile modules using
- libtool. The modules are compiled as shared libraries, and are
- renamed when installed.
-
- * src/m4.h, src/module.c, acm4/modules.m4, acconfig.h: Renamed
- USE_SHL_LOAD to HAVE_SHL_LOAD
-
- * src/builtin.c (shipout_string): Now tests for a NULL string.
-
- * src/module.c: New level of indirection around non-portable
- functions to load shared objects. Intended to encapsulate the non
- portable parts better and to reduce the number of #ifdefs in the
- code.
-
- * Makefile.am (DIST_SUBDIRS): Instead of EXTRA_DIST for added
- directory modules/ to the distribution.
-
-1998-11-15 René Seindal <rene@seindal.dk>
-
- * Prerelease 1.4l.
-
- * modules/stdlib.c: New module `stdlib' defining some standard
- functions: getcwd, getlogin, getpid, getppid, getuid, getpwnam,
- getpwuid, hostname, rand, srand, getenv, setenv, unsetenv, uname.
-
- * src/builtin.c (shipout_string): New convenience function for
- builtins and modules.
-
- * src/module.c (module_load): Tentative support for
- shl_load/shl_findsym, but I cannot test it. Copied from MetaHTML.
-
- * Makefile.am (SUBDIRS): Directory modules added if configured.
-
- * modules/Makefile.am: Now correctly compiles and installs
- modules in pkglibexecdir.
-
- * src/m4.h: WITH_MODULES defined iff HAVE_DLOPEN or USE_SHL_LOAD.
- These two are now initialised by autoconf macros.
-
- * src/path.c (module_env_init): MODULE_PATH is always on the
- search path.
-
- * src/Makefile.am: Now generated pathconf.h which defined the
- default MODULE_PATH.
-
- * configure.in (pkglibexecdir): Added defintion of pkglibexecdir,
- where modules are installed.
-
- * acm4/modules.m4: Enhanced with code from MetaHTML, contributed
- by Brian J. Fox <bfox@datawave.net>. This change allow modules to
- build and install automatically, and it is prepared for other
- interfacec than dlopen().
-
- * src/builtin.c (predefined_tab): Added __m4_version__ for the
- current version of GNU m4. It is a GNU extension.
-
-1998-11-14 René Seindal <rene@seindal.dk>
-
- * tests/Makefile.am (GENERATED_TESTS): Added new
- generated-tests/changesy.8.test
-
- * doc/m4.texinfo (Changesyntax): Documentation for escape
- syntax class.
-
- * src/macro.c (expand_token): Check for escaped macro call before
- symbol table lookup.
-
- * src/builtin.c (m4_changesyntax): Added `@' flag to define escape
- characters
-
- * src/input.c: New static variable use_macro_escape, which is TRUE
- iff some character has code SYNTAX_ESCAPE
- (input_init): Added initialisation of use_macro_escape.
- (check_use_macro_escape): New function to synchronise
- use_macro_escape with the syntax table.
- (set_quotes): Added call to check_use_macro_escape()
- (set_comment): Do.
- (set_syntax): Do.
- (next_token): Added new case for IS_ESCAPE.
-
- * src/m4.h (SYNTAX_ESCAPE): Defined as simple syntax category.
-
-1998-10-13 René Seindal <rene@seindal.dk>
-
- * Prerelease 1.4k.
-
- * tests/Makefile.am (GENERATED_TESTS): Renamed gentest to
- generated-tests.
-
- * tests/Makefile.am (OTHER_TESTS, OTHER_FILES): Added manually
- maintained tests in tests/other-tests. These currently tests for
- 8-bit transparency, multiple precision arithmetic and sync-line
- output. Test for stackoverflow detection does not work.
-
- * examples/Makefile.am (TESTS): Added tests for all example files.
-
- * examples/mktests.sh: New file. Help program for creating test
- files.
-
- * tests/mkconfig.sh: New file to generate tests/config.m4 and
- tests/config.sh. This is for tests of configure selectable
- features. Picks up all set WITH_ and ENABLE_ veriables from
- config.h
-
- * src/path.c (path_search): Added argument 'char **expanded_name'
- to return the expanded name.
-
- * src/m4.h: Added 2nd argument to declaration of path_search().
-
- * src/m4.c (main): Added 2nd argument to path_search().
-
- * src/freeze.c (reload_frozen_state): Do.
-
- * src/builtin.c (m4_undivert): Do.
- (include): Do.
-
-1998-10-11 René Seindal <rene@seindal.dk>
-
- * acm4/Makefile.am (ACINCLUDES_M4): Added gmp.m4 and modules.m4
-
- * acm4/modules.m4: New file. Defines AM_WITH_MODULES.
-
- * acm4/gmp.m4: New file. Defines AM_WITH_GMP.
-
- * configure.in: Introduced AM_WITH_MODULES and AM_WITH_GMP.
-
- * AUTHORS, ChangeLog: Changed all dates to ISO 8601.
-
- * intl/: Updated to GNU gettext 0.10.35.
-
- * doc/m4.texinfo (Format): Documented that format is blind.
-
- * src/builtin.c (builtin_tab): Builtin format marked as blind.
-
-1998-10-07 René Seindal <rene@seindal.dk>
-
- * Prerelease 1.4j.
-
- * tests/Makefile.am (GENERATED_TESTS): Changed .m4 extension to
- .test, as the files are no longer just m4 input.
-
- * tests/get-them (FILE): Changed .m4 extension to .test.
-
- * src/m4.h (token_type): New token type TOKEN_SPACE introduced.
- Otherwise quoted strings with leading whitespace first in a macro
- argument would be eliminated.
-
- * src/macro.c (expand_token): Handles new token type TOKEN_SPACE.
- (expand_argument): Do.
-
- * src/input.c (next_token): SPACE and NUM/OTHER characters are only
- grouped together iff both quote and comment strings are single
- character. Otherwise they might include a comment/quote leader.
- (next_token): Returns new token type TOKEN_SPACE.
-
- * src/builtin.c (push_builtin_table): New function to push a
- builtin_table on the stack without installing its contents.
- (find_builtin_by_name): Added call to push_builtin_table() if
- reading frozen files. Otherwise the builtins named in the frozen
- files could not be found.
- (install_builtin_table): Changed to use push_builtin_table()
-
-1998-10-04 René Seindal <rene@seindal.dk>
-
- * po/pl.po: Polish translation added.
-
- * po/POTFILES.in: src/module.c added.
-
-1998-10-04 René Seindal <rene@seindal.dk>
-
- * Prerelease 1.4i.
-
- * configure.in (ALL_LINGUAS): Added Polish pl.po
-
-1998-10-03 René Seindal <rene@seindal.dk>
-
- * Many files: Incorporated changes to implement dynamic modules.
- Detailed comments in src/modules.c and modules/README
-
- * src/module.c: New file, implements the OS dependant parts of
- dynamic module loading.
-
- * src/Makefile.am (m4_SOURCES): Added module.c
-
- * src/builtin.h: New file, declares some functions from builtin.c
- that are of use for other modules (shipout_int, numeric_arg,
- skip_space, bad_argc), and the macros ARG() and DECLARE().
-
- * src/builtin.c (install_builtin_table): New function. Each
- module brings in a builtin_table, which is pushed on a stack.
- (struct builtin_table): New struct for list of builtin_tables.
- (m4_loadmodule): New function to implement builtin "loadmodule".
- (shipout_int): No longer static, to be used by modules.
- (numeric_arg): do.
- (skip_space): do.
- (bad_argc): do.
- (builtin_init): changed to call install_builtin_table()
- (find_builtin_by_name): Now searches all builtin_tables
- (find_builtin_by_addr): do.
-
- * src/path.c: Reorganised to allow for two search paths, one for
- include files and one for modules.
-
- * src/m4.h: Added declarations for new functions in module.c and
- in path.c.
-
- * src/m4.c (main): Added call to module_init().
-
- * modules: New directory with a few demo modules.
-
- * Makefile.am (EXTRA_DIST): Added modules/* since modules/ is not
- in SUBDIRS.
-
- * configure.in: Added modules/Makefile to AC_OUTPUT.
-
- * configure.in: Added code to implement --with-modules. Tests for
- <dlfcn.h> and -ldl.
-
- * acconfig.h: Added WITH_MODULES
-
-1998-10-02 René Seindal <rene@seindal.dk>
-
- * examples/Makefile.am (pkgdata_DATA): Removed special target for
- check and variables TESTS. These tests are now run from the
- tests/ directory.
-
- * tests/Makefile.am (OTHER_TESTS): Added tests from the example/
- directory. The files stay there but the tests are run from the
- tests/ directory.
-
- * tests/Makefile.am (EXTRA_DIST): Added run-test.
-
- * tests/run-test: New file. Run a test manually
-
- * tests/Makefile.am, tests/get_them: Moved automatically generated
- tests (from the manual) to sub directory tests/gentest/. The
- tests/ directory had gotten a bit messy.
-
-1998-09-06 Erick Branderhorst <Erick.Branderhorst@asml.nl>
-
- * examples/{comments,ddivert,debug,iso8859,reverse,sysv-args,\
- wrap}.test: Added a few testcases.
-
-1998-08-21 Erick Branderhorst <Erick.Branderhorst@asml.nl>
-
- * Prerelease 1.4h.
-
- * lib/Makefile.am (noinst_HEADERS): regex.h added
-
- * configure.in (jm_WITH_REGEX, jm_PREREQ_ERROR):
- acm4/{error,regex}.m4 (from fileutils-3.16u.tar.gz).
-
- * acm4/Makefile.am: created providing rules to create
- $(top_srcdir)/acinclude.m4 to be used by aclocal.
-
- * tests/defs (LANGUAGE, LC_ALL, LANG): force them to be
- `C'. Reported by Ulrich Drepper.
-
- * Makefile.am (SUBDIRS): Removed checks directory
- * configure.in (AC_OUTPUT): Removed checks/Makefile
-
- * doc/m4.texinfo (Patsubst,example): @comment added to preserve
- the space when m4.texinfo is edited and whitespace.el is active.
- (Defn,example): idem.
-
-1998-08-20 Erick Branderhorst <Erick.Branderhorst@asml.nl>
-
- * doc/m4.texinfo (Esyscmd): grep ../Makefile instead of
- ../COPYING. ../Makefile is a file which is certainly present when
- test is executed in testSubDir. One can't be sure that the COPYING
- file is in .. or ../.. in all situations, the ../Makefile is
- always there.
-
- * doc/m4.texinfo (Include): adjusted expected test output
- according to new tests, i.e. the input will always come from the
- file `in' created by the test.
-
- * tests/Makefile.am: Added three lines at the top to get
- esyscmd.1.test working.
-
- * tests/get-them: modified to generate clearer tests who will need
- less maintenance when new test examples are created in
- `doc/m4.texinfo'. All tests are small (nearly stand-alone, they
- need the generic file `defs') shell scripts creating `in', `ok',
- `out' and when apropriate `okerr' and `err' in the directory
- `testSubDir' when executed. The compare of `ok' and `out'
- (and of `okerr' and `err') will be the exit status of the test.
- `out' must match `ok' (and `okerr' must match `err') for the test
- to be succesful.
-
- * tests/[a-b]\{1,8\}.[0-9]+.test: This namespace is reserved for
- the tests generated by tests/get-them getting it input normally
- from doc/m4.texinfo. The namespace tests/[a-b]+[0-9]+.test (no `.'
- (dot) before the numeric part) is reserved for all other (hand
- written) tests. The `+' means one or more times.
-
-1998-08-12 Erick Branderhorst <Erick.Branderhorst@asml.nl>
-
- * doc/Makefile.am (EXTRA_DIST): helptoman.pl and $(MANS) to
- supported short man page to refer to info documentation
- * helptoman.pl: added
- * configure.in: AC_PATH_PROG(PERL,perl)
- * Makefile.am (SUBDIRS): doc after src
-
- * libitized with libit 0.5 from
- ftp://ftp.iro.umontreal.ca/pub/contrib/pinard/maintenance/libit.
-
- * configure.in (AC_REPLACE_FUNCS): added xmalloc xstrdup
- * lib/Makefile.am (libm4_a_SOURCES): removed automakely supported
- replacement functions, (libm4_a_LIBADD): @LIBOBJS@
- * configure.in (AM_WITH_REGEX), acconfig.h (WITH_REGEX): added
- lib/rx.{c,h}: added
- * configure.in (AC_CHECK_FUNC): getopt_long
-
- * src/m4.c (usage): Report bugs to m4-bugs@gnu.org.
-
- * TODO: added entry about dependencies
-
-1998-08-10 René Seindal <rene@seindal.dk>
-
- * Prerelease 1.4f
-
- * doc/m4.texinfo (Changesyntax): Added documentation for the macro
- "changesyntax".
-
- * src/builtin.c (m4_changesyntax): Added builtin macro
- "changesyntax" to modify the syntax table.
-
- * src/input.c, src/m4.h, src/macro.c: Implemented an input syntax
- table. All categories are assigned a syntax code and tokens are
- read according to this table.
-
-1998-08-09 René Seindal <rene@seindal.dk>
-
- * src/numb.{c,h}: New files, implements multiple precision eval
- using GNU gmp. Originally submitted by John Gerard Makecki
- (johnm@vlibs.com), later modified. Tested with GNU gmp 2.0.2.
-
- * doc/m4.texinfo (Eval): Added documentation for multiple
- precision arithmetic library support.
-
- * src/m4.{c,h}, src/eval.c, src/builtin.c, configure.in: Changes
- to accommodate multiple precision eval.
-
-1998-08-07 René Seindal <rene@seindal.dk>
-
- * src/input.c (MATCH, match_input), src/m4.h: changed definition
- of comment and quote strings to `unsigned int' to allow eight bit
- chars (reported by andrewb@zip.com.au (Andrew Bettison)).
-
- * src/builtin.c, doc/m4.texinfo: Builtin `syncoutput' added by
- patch from Mike Howard <mike@clove.com>
-
-1998-08-06 René Seindal <rene@seindal.dk>
-
- * gettext.m4: corrected AM_WITH_NLS to handle use of installed
- -lintl.
-
-1998-08-03 René Seindal <rene@seindal.dk>
-
- * Prerelease 1.4e
-
- * src/m4.h: Added ifdef ENABLE_NLS around include of <libintl.h>
- and _ macro. M4 now builds with --disable-nls.
-
- * src/m4.c (main): reintroduced textdomain(PACKAGE) to get gettext
- to look for right message catalogs. Call indef'ed by ENABLE_NLS.
-
- * configure.in (ALL_LINGUAS): Added complete list of translations:
- de fr it ja nl ru sv.
-
-1998-05-23 Erick Branderhorst <Erick.Branderhorst@asml.nl>
-
- * po/nl.po: Dutch translation by Erick Branderhorst.
-
- * po/fr.po: French translation by Erick Branderhorst, based on the
- translations by François Pinard in fr.msg and m4.cod.
-
-1998-05-22 Erick Branderhorst <Erick.Branderhorst@asml.nl>
-
- * Prerelease 1.4d.
-
- * src/m4.c: #include <signal.h> not <sys/signal.h>.
-
- * src/Makefile.am: CFLAGS = -Wall @CFLAGS@.
-
- * checks/Makefile.am: explicit list tests in CHECKS.
-
- * configure.in, {,src,doc,lib,examples,checks}/Makefile.am,
- src/{ansi2knr.{1,c}} doc/{m4.texinfo,mdate-sh}, missing,
- mkinstalldirs, install-sh: Added automake (1.3) support.
-
- * lib/{alloca.c,error.{c,h},get{date.h,opt.{c,h},opt1.c},
- obstack.{c,h},regex.{c,h},strtol.c,xmalloc.c,xstrdup.c}:
- Used libitize (0.4) to update.
-
- * configure.in, ABOUT-NLS, intl/*, po/*: Added gettextize
- (0.10.25) support. Removed LOCALE, fr.msg, m4.cod and adjusted
- README accordingly.
-
- * src/stackovf.c: #ifdef USE_STACKOVF ... #endif to (de-)activate
- stack overflow functionality.
-
-1994-12-03 François Pinard <pinard@iro.umontreal.ca>
-
- * Prerelease 1.4.1.
-
- * Makefile.in (realclean-local): Delete stamp-h.in.
-
- * configure.in, {,src,lib}/Makefile.in, src/m4.h, src/m4.c:
- Localize, adapting from how it is done in sharutils.
-
- * fr.tt: New file, for French.
-
- * configure.in, {,*/}Makefile.in, acconfig.h, src/m4.c,
- src/freeze.c: Rename PRODUCT to PACKAGE.
-
-1994-11-26 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Check for <libintl.h> and <locale.h>.
- * src/m4.h, src/builtin.c, src/debug.c, src/eval.c, src/macro.c,
- src/stackovf.c: Rename _ to __P.
- * src/m4.h: Declare _ as a macro returning its argument, or else,
- include <libintl.h> and declare _ as gettext.
- * src/m4.c: Possibly include <locale.h> and call setlocale.
- * src/m4.c, src/builtin.c, src/debug.c, src/eval.c, src/freeze.c,
- src/input.c, src/macro.c, src/output.c, src/path.c,
- src/stackovf.c, src/symtab.c: Use _ macro over all localizable
- strings.
-
-1994-11-07 François Pinard <pinard@iro.umontreal.ca>
-
- * doc/Makefile.in (stamp-vti): Use new -r option to date.
-
- * configure.in: Put --with-gmp in place, in prevision for John
- Gerard's work.
- * acconfig.h: Document WITH_GMP.
-
-1994-11-05 François Pinard <pinard@iro.umontreal.ca>
-
- * Release 1.4.
-
- * doc/Makefile.in (realclean): Also remove stamp-vti.
- Reported by Eric Backus.
-
-1994-11-02 François Pinard <pinard@iro.umontreal.ca>
-
- * src/freeze.c (produce_frozen_state): If the frozen file cannot
- be opened, return immediately after producing the error message.
- Reported by Andreas Schwab.
-
- * configure.in: Check for const only after having found possible
- ANSIfying compiler flags, this is of no use to check it before.
- Reported by Alexander Lehmann.
-
-1994-11-01 François Pinard <pinard@iro.umontreal.ca>
-
- * src/macro.c (collect_arguments): Cast obstack arguments to
- (voidstar), so avoiding compiler warnings.
- Reported by Joseph E. Sacco.
-
- * src/freeze.c (produce_frozen_state): Cast printed lengths to
- (int) so they correspond to %d format items.
- Reported by Joseph E. Sacco.
-
- * src/m4.c (main): Cast the argument to xfree to (voidstar).
- * src/symtab.c (free_symbol): Idem.
- Reported by Karl Vogel.
-
-1994-10-31 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (DISTFILES): Distribute BACKLOG.
-
- * configure.in: Define PRODUCT and VERSION.
- * acconfig.h: Document PRODUCT and VERSION.
- * src/m4.c, src/freeze.c: Use PRODUCT and VERSION instead of the
- constant string m4 and variable or parameter named version.
-
-1994-10-30 François Pinard <pinard@iro.umontreal.ca>
-
- * src/m4.h, src/debug.c: Replace all #ifdef __STDC__ by #if
- __STDC__. Alliant FX/2800 Concentrix 2.2 (i860-BSD4.3) compiler
- defines __STDC__ to 0, for indicating it is *not* ANSI!
- Reported by Kaveh R. Ghazi.
-
- * configure.in: Added obsolescent tests for AIX and Minix.
-
- * doc/Makefile.in (mostlyclean): Remove texclean in dependencies,
- which texclean does not exist anymore.
- Reported by Eric Backus, Jim Meyering, John David Anglin and
- Joseph E. Sacco.
-
-1994-10-29 François Pinard <pinard@iro.umontreal.ca>
-
- * aclocal.m4 (fp_C_PROTOTYPES): Force -D_HPUX_SOURCE with -Aa.
- Reported by John David Anglin.
-
- * src/ansi2knr.c: New version, sent by Peter Deutsch.
- * aclocal.m4 (fp_C_PROTOTYPES): Substitute empty or ansi2knr for
- ANSI2KNR, depending on the fact the compiler is ANSI or not.
- * src/Makefile.in: Use -Ovarargs=convert on ansi2knr calls.
- Remove the sed filter after ansi2knr for debug.c. Use $O instead
- of $U, put underline in extensions rather than in basenames. Use
- implicit rules, now that regularity makes this possible.
- Have $(OBJECTS) depend on $(ANSI2KNR), so to trigger compilation
- of ansi2knr whenever it is needed.
- * configure.in: Adjusted for correct STACKOVF substitution.
- * src/debug.c (trace_format): When not __STDC__, use (...) as a
- parameter list, so ansi2knr will convert it to (va_alist) va_dcl.
- Reported by David MacKenzie.
-
- * Makefile.in: Remove binprefix. Use transform_name instead.
- Reported by David MacKenzie.
-
- * doc/Makefile.in: Create version.texi, use it, clean it.
- Reported by Jim Meyering.
-
-1994-10-28 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (all, install, uninstall): Depend on Makefile.
-
- * Makefile.in: For actions invoking $(MAKE) from within compound
- sh statements, exit non-zero if the sub-make fails. Otherwise,
- the top-level make may exit successfully when it should fail.
- Reported by Jim Kingdon.
-
- * {,/*}Makefile.in: Use && after all cd, in case they fail.
-
- * {,*/}Makefile.in: Declare PRODUCT and VERSION macros.
- (dist): Use PRODUCT and VERSION instead of tricks on .fname.
- * configure.in: Substitute PRODUCT and VERSION.
-
- * {,*/}Makefile.in (dist): Always try a hard link before a copy.
-
-1994-10-27 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (mostlyclean-local): Do not remove *~.
- * */Makefile.in (mostlyclean): Idem.
- Reported by Robert E. Brown and Richard Stallman.
-
-1994-10-09 François Pinard <pinard@iro.umontreal.ca>
-
- * src/m4.h: Get rid of CONFIG_BROKETS.
-
-1994-10-02 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Use AC_ARG_PROGRAM.
- * aclocal.m4 (fp_C_PROTOTYPES): Substitute @kr@ by kr or empty.
- Reported by David MacKenzie.
-
-1994-10-01 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Do not add -O to CFLAGS for GNU C, now that
- configure does it automatically.
- Reported by Jim Meyering.
-
-1994-09-23 François Pinard <pinard@iro.umontreal.ca>
-
- * src/stackovf.c: Declare the handler_t typedef earlier in the
- code, use it for stackovf_handler.
- (setup_stackovf_trap): Use RETSIGTYPE instead of void while
- casting sigsegv_handler.
- Reported by Robert Bernstein.
-
- * src/m4.c (main): Initialize program_name to argv[0] without
- basename'ing it.
- Reported by Karl Berry.
-
-1994-09-18 François Pinard <pinard@iro.umontreal.ca>
-
- * src/Makefile.in (TAGS): Include a ../lib/TAGS reference.
- Reported by Karl Berry.
-
-1994-09-14 François Pinard <pinard@iro.umontreal.ca>
-
- * lib/Makefile.in (mostlyclean): Added.
- (TAGS): Make in $(srcdir).
-
- * configure.in: Use `choke me' in test, like everywhere!
-
- * {doc,examples,lib,src}/Makefile.in (check): Deleted, as
- unreacheable and useless.
-
- * doc/Makefile.in (texclean): Deleted, merged in mostlyclean.
-
- * lib/Makefile.in (DISTFILES): Distribute TAGS.
- (distclean): Do not remove TAGS.
- (realclean): Remove it.
- * Makefile.in: Make TAGS in lib also, not just in src.
- Reported by Karl Berry.
-
- * Makefile.in (distclean, realclean): Instead of recursively
- calling $(MAKE) for the -local part, allow parallel execution of
- -recursive and -local, only delay the removal of config.status,
- which is repeated in both goals.
-
-1994-09-13 François Pinard <pinard@iro.umontreal.ca>
-
- * Release 1.3.
-
- * Makefile.in: Group all *clean-recursive goals in one, using sed
- to remove `-recursive' while calling make recursively. Also, use
- a subshell for each recursive $(MAKE).
- Reported by Jim Meyering.
-
- * src/m4.h (memcpy): Define with bcopy for BSD systems.
- Reported by Kaveh R. Ghazi.
-
- * src/Makefile.in (ansi2knr): Use $(LIBS) while linking, for SunOS
- 4.1.3 requires -ldl to link even ansik2nr, and we need a way to
- specify it.
-
- * configure.in: Use date instead of touch for stamp-h.
- * Makefile.in (stamp-h.in): Idem.
-
- * Makefile.in (distclean, realclean): Force serial execution of
- both goals, in case parallel makes are being used.
- Reported by Jim Meyering.
-
- * src/Makefile.in (DISTFILES): Distribute TAGS.
- (distclean): Do not remove TAGS.
- (realclean): Remove it.
- Reported by Karl Berry.
-
-1994-09-10 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Use fp_ to match aclocal.m4. Revert _OS_ macros
- to old names, for following Autoconf.
-
-1994-09-08 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (MDEFINES): Remove INSTALL substitutions, for
- ./install.sh will not be correctly referred to in sub-Makefiles.
- Reported by John David Anglin.
-
- * doc/Makefile.in (texclean): Remove *.cps and *.fns too.
- Reported by Eric Backus.
-
- * Makefile.in, checks/Makefile.in, doc/Makefile.in,
- examples/Makefile.in, lib/Makefile.in, src/Makefile.in: Limit
- config.status into remaking this directory's Makefile only.
- * Makefile.in (stamp-h): Do not check nor touch stamp-h.
- * configure.in (AC_OUTPUT): Touch stamp-h if CONFIG_HEADERS.
- Reported by Jim Meyering.
-
-1994-09-06 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Correct stack overflow detection logic, taking
- care of systems having only incomplete implementations (like for
- Pyramid 9820 OSx 5.0d).
- Reported by Kaveh R. Ghazi.
-
- * src/Makefile.in (TAGS): Remote -t from etags call.
-
-1994-09-02 François Pinard <pinard@iro.umontreal.ca>
-
- * lib/Makefile.in (install): Depend on all.
-
-1994-08-31 François Pinard <pinard@iro.umontreal.ca>
-
- * examples/Makefile.in (mostlyclean): Do not depend on texclean.
- Reported by Jim Meyering and John David Anglin.
-
- * Makefile.in (distclean-local): Delete config.log.
- Reported by Jim Meyering.
-
- Solidify frozen files with respect to -P:
- * src/m4.c: Have -P set prefix_all_buitins variable instead of
- calling a function by that name. Declare the variable.
- * src/m4.h: Adjust declaration for prefix_all_buitins.
- * src/builtin.c (builtin_init): Merge in functionality from
- previous prefix_all_buitins function, while making entries in the
- symbol table, but not modifying the builtin description itself.
-
- * src/freeze.c (reload_frozen_state): Add a useless `break;',
- because *many* compilers do not accept an empty `default:'.
- Reported by Akiko Matsushita, Eric Backus, John David Anglin,
- Joseph E. Sacco, Kaveh R. Ghazi, Tom McConnell and Ulrich Drepper.
-
- * configure.in: Use AC_TYPE_SIGNAL.
- * src/stackovf.c (setup_stackovf_trap): Use RETSIGTYPE.
- Reported by Robert Bernstein.
-
- * checks/Makefile.in (check): Modify PATH so check-them will find
- m4 in the src directory.
- * Makefile.in (check): Don't.
- Reported by Akiko Matsushita and Jim Meyering.
-
- * src/output.c (make_room_for, output_character_helper): New
- functions, for implementing a global MAXIMUM_TOTAL_SIZE instead of
- a per buffer MAXIMUM_BUFFER_SIZE.
-
- * src/output.c (output_text): New function, for optimizing the
- output of strings of characters. Use it.
-
-1994-08-30 François Pinard <pinard@iro.umontreal.ca>
-
- * doc, src: New directories reorganizing the distribution.
- * doc/Makefile.in, src/Makefile.in, examples/Makefile.in: New
- files.
- * Makefile.in: Adjusted.
- * configure.in: Configure new Makefiles.
-
- * m4.h: Declare STRING typedef. Use it for comment and quote
- strings, adjusting all references. (This is the rudiments of a
- beginning for the eventual withdrawal of NUL terminated strings.)
- * output.c (shipout_text): Accept a length parameter, and use it.
- All callers adjusted.
-
-1994-08-29 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Include <unistd.h> if it exists.
- * stackovf.c: Don't.
-
- Clean up for current_diversion variable:
- * output.c: Move current_diversion from builtin.c.
- * m4.h: Declare current_diversion so builtin.c can access it.
- * output.c (output_init, make_diversion): Initialize or update
- current_diversion.
- * builtin.c (builtin_init, m4_divert): Leave current_diversion
- alone.
-
- Remove limit on number of diversions:
- * output.c: Replace ndiversion by diversions, declare it.
- (output_init): Allocate only diversion 0.
- (make_diversion): Allocate new diversions as needed.
- * m4.h, m4.c: Remove NDIVERSIONS and ndiversion related stuff.
- * m4.c: Still accept -N, but do nothing with it.
- Reported by David MacKenzie.
-
- Freeze diversions:
- * output.c (freeze_diversions): New function.
- * m4.h: Declare freeze_diversions.
- * freeze.c: Document frozen file format, revise it, call
- freeze_diversions to add diversions to frozen format, and code to
- reload them properly.
- * m4.c: Do not undivert automatically at end when status being
- frozen. Do not call builtin_init when reloading frozen state.
-
- Speed up diversion processing:
- * output.c: Add INITIAL_BUFFER_SIZE, MAXIMUM_BUFFER_SIZE,
- COPY_BUFFER_SIZE, in-memory diversion buffers, struct diversion
- structure and variables, cached variables out of output_diversion,
- reallocate_diversion_for and OUTPUT_CHARACTER.
- (shipout_text, make_diversion, insert_diversion): Adapted to new
- structures.
- (insert_file): Use better buffering.
- Reported by David MacKenzie.
-
-1994-08-28 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in, lib/Makefile.in, checks/Makefile.in: Arrange so
- dist works from another build directory.
-
-1994-08-27 François Pinard <pinard@iro.umontreal.ca>
-
- * symtab.c (hack_all_symbols): Use hash_table_size instead of
- constant HASHMAX, for -H option to work better.
-
- * builtin.c (DECLARE): Simplify by using _ ().
-
- * freeze.c: New file.
- * Makefile.in: Compile it, distribute it.
- * m4.c: Recognize, document and process --freeze-state (-F) and
- --reload-state (-R) options. Pass a true flag to builtin_init
- only if no reloading some state.
- * builtin.c (define_builtin): Remove static specifier.
- (find_builtin_by_name): Remove static specifier.
- (builtin_init): Accept and obey a flag argument.
- * m4.h: Add declarations for freeze.c, changes for builtin.c.
-
-1994-08-24 François Pinard <pinard@iro.umontreal.ca>
-
- * builtin.c (dumpdef_cmp): Rewrite so the cast protect the const
- specifier.
-
- * configure.in: Implement --with-dmalloc.
- * acconfig.h: Document WITH_DMALLOC.
- * m4.h: Add code for when WITH_DMALLOC.
-
-1994-08-15 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.c (long_options): Use "error-output", the dash was missing.
- Reported by Akiko Matsushita.
-
-1994-08-12 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Include <sys/types.h>.
- * builtin.c, debug.c, m4.c, output.c, stackovf.c: Don't.
- * m4.h: Declare len_lquote and len_rquote as size_t, not int.
- int.
- * input.c: Declare len_lquote, len_rquote, len_bcomm and len_ecomm
- as size_t, not int.
- * builtin.c (dump_args): Declare len as size_t, not int.
-
- * debug.c: Prototype the forward declaration of debug_set_file.
-
- * builtin.c (m4_undivert): Replace div by file, for avoiding the
- shadowing of this variable.
- * output.c (insert_diversion): Idem.
-
- * input.c: Delete def_rquote, def_lquote, def_bcomm and def_ecomm.
- (input_init): Duplicate default quote and comment strings.
- (set_quotes): Free previous quote strings in all cases. Duplicate
- even default quote strings.
- (set_comment): Free previous comment strings in all cases.
- Duplicate even default comment strings.
-
- * configure.in: Updated for Autoconf 2.0.
- * Makefile.in (distclean-local): Also delete config.cache.
-
- * m4.c (usage): Reorganize the --help output by topic. Include a
- description for debugging flags.
-
-1994-07-29 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: If sigaction is available and SA_ONSTACK defined,
- use sigaction. Otherwise, if sigvec is available and SV_ONSTACK
- defined, use sigvec. Else don't compile stackovf.c.
- * stackovf.c (setup_stackovf_trap): Idem.
- Reported by Jim Avera, Karl Berry, Kaveh R. Ghazi, Matthias Rabe
- and Simon Leinen.
-
-1994-07-21 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.c (usage): Replace printf par fputs.
-
-1994-07-18 François Pinard <pinard@iro.umontreal.ca>
-
- * Release 1.2
-
-1994-07-17 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Check for sigaction and sigvec. Add a new delayed
- check for RLIMIT_STACK, combine in the checking for getrlimit.
- All those things are not universally available.
- * stackovf.c: Split setting up the trap handler and catching
- signals, for better taking care of various configure outcomes.
- * examples/stackovf.sh: Correct a typo.
- Reported by Eric Backus, Jim Avera and Jim Meyering.
-
-1994-07-16 François Pinard <pinard@iro.umontreal.ca>
-
- * ansi2knr.c: New version sent by its author, Peter Deutsch.
-
-1994-07-15 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in: Modify so parallel make will not try making
- lib/libm4.a twice simultaneously.
- Reported by Jim Meyering.
-
-1994-07-14 François Pinard <pinard@iro.umontreal.ca>
-
- * stackovf.c (setup_stackovf_trap): Replace "Don't" by "Do not" in
- error message, for when no code possibility exists. Even if this
- line is completely #ifdef'ed out, it brings a syntax error.
- Reported by Andreas Schwab, Jim Meyering and Joseph E. Sacco.
-
- * Makefile.in (install): Have install depend on all too, for lib
- to be remade as needed.
-
- * examples/stackovf.sh: Try ksh, bsh and bash for shells
- providing ulimit, instead of using only ksh.
- Reported by Jim Avera and Joseph E. Sacco.
-
-1994-07-12 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (check): Have it depend on all instead of m4. In
- this way, a change in lib will be detected and processed.
-
- * builtin.c (numeric_arg): Use strtol and verify the conversion,
- instead of using sscanf which stops as soon as there is a
- non-digit in the input. Previously, incr(1xyzzy), eval(1,2xyzzy)
- and divert(1xyzzy) were all accepted without any warning or error
- messages.
- * m4.h: Declare strtol as long if not including stdlib.h.
- * configure.in: Check for limits.h, and replace strtol if missing.
- * lib/Makefile.in: Substitute LIBOBJS. Distribute strtol.c.
- * lib/strtol.c: New file, from elsewhere.
- Reported by Andreas Schwab.
-
-1994-07-07 François Pinard <pinard@iro.umontreal.ca>
-
- * macro.c (expand_macro): Cast value to (boolean) prior to
- assigning it to traced.
- Reported by Tom McConnell.
-
- * Makefile.in (m4): Always make all in lib first.
- Reported by Jim Meyering.
-
-1994-07-06 Jim Avera <jima@netcom.com>
-
- * stackovf.c: Isolated OS-dependent sections; Improved portability,
- adding support for SunOS/BSD (sigvec, sigstack, and 4-parameter signal
- handlers), and a default error message if the fault address is not
- available (when neither siginfo.h nor BSD sigcontext are supported).
- * configure.in: Changes for stackovf.h: Check for sigcontext,
- sigaction, sigstack, and define rlim_t as int if necessary.
- * acconfig.h: Added HAVE_SIGCONTEXT and rlim_t.
- * examples/stackovf.sh: Run m4 -L99999999 to allow stack overflow.
- * ansi2knr.c: Fix for func-ptr args; convert "..." to varargs syntax.
-
-1994-07-05 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Use AC_SET_MAKE.
- * Makefile.in: Use @SET_MAKE@.
- Reported by Jim Meyering.
-
- * checks/check-them: Do not trap on SIGQUIT or SIGALRM.
- Reported by Ian Taylor.
-
-1994-07-02 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Remove dependency of USE_STACKOVF on STDC_HEADERS,
- because siginfo.h is unrelated to standard headers, and siginfo.h
- is already checked for.
- Reported by Joseph E. Sacco.
-
- * acconfig.h, aclocal.m4, m4.h: Replace HAVE_PROTOTYPES by
- PROTOTYPES.
- * aclocal.m4, configure.in: Replace AC_HAVE_PROTOTYPES by
- AC_PROTOTYPES.
-
-1994-06-29 François Pinard <pinard@iro.umontreal.ca>
-
- * builtin.c (substitute): Use \& to represent this part of the
- string which was matched by the whole regexp, instead of
- representing the whole string. Any usage of \0 issues a warning
- and acts like \&, it will disappear in some subsequent release.
-
-1994-06-27 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.c: Complete prototype for forwarded declaration of usage.
-
- * input.c (init_macro_token): Correct own reference in error
- message. Previous name get_macro_func was referred to instead.
- (next_char): Correct own reference in error message. Previous
- name advance_input was referred to instead.
-
- * m4.h: Declare eval_t and unsigned_eval_t typedefs to 32 bits.
- * eval.c (logical_or_term, logical_and_term, or_term, xor_term,
- and_term, not_term, logical_not_term, cmp_term, shift_term,
- add_term, mult_term, exp_term, unary_term, simple_term): Add
- prototype to forwarded declarations. Declare parameter v1 as
- eval_t * instead of int *. Same for local variable v2 in dyadic
- functions. Same for result in exp_term.
- * builtin.c (m4_eval): Declare value as eval_t instead of int.
- (ntoa): Declare value as eval_t instead of int. Declare uvalue as
- unsigned_eval_t instead of unsigned int. Change casts accordingly.
- (shipout_int): Cast first argument of ntoa to eval_t.
- Reported by Thorsten Ohl.
-
- * macro.c: Complete the prototypes of forwarded expand_macro and
- expand_token.
- Reported by Thorsten Ohl.
-
- * m4.h: Define voidstar as void * or char * depending on __STDC__.
- The Ultrix 3.1 compiler cannot do much with void pointers.
-
- * builtin.c (dumpdef_cmp): Replace void * by voidstar.
- * m4.c (xfree): Replace void * by voidstar.
- Reported by Tom McConnell.
-
- * ansi2knr.1: New, from elsewhere.
- * Makefile.in (DISTFILES): Distribute ansi2knr.1
-
- * Makefile.in (stamp-h.in): Avoid running ./config.status if
- stamp-h does not exist yet. This avoids running it a second time
- just after the initial ./configure.
- Reported by David MacKenzie and Tom McConnell.
-
- * m4.h: Replace the enum debug_info declaration with a series of
- #define's. The Ultrix 3.1 compiler would otherwise need casting
- (int) to most references, when used in expressions.
- Reported by Tom McConnell.
-
-1994-06-25 François Pinard <pinard@iro.umontreal.ca>
-
- * aclocal.m4: Replace FP_PROTOTYPES by AC_HAVE_PROTOTYPES,
- following an idea from Brook G. Milligan. AC_HAVE_PROTOTYPES
- calls the compiler. Previously, FP_PROTOTYPES was only calling
- the preprocessor; by not being subject to CFLAGS, this was
- discouraging those flags asking for ANSI compilation.
- * acconfig.h: Document HAVE_PROTOTYPES.
- * configure.in: Use AC_HAVE_PROTOTYPES instead of FP_PROTOTYPES.
- * m4.h: Define _() according to HAVE_PROTOTYPES, not __STDC__.
- Reported by Eric Backus.
-
- * configure.in: Substitute CFLAGS and LDFLAGS, taking their value
- from the environment. Default CFLAGS to -g if not set.
- * Makefile.in: Have CFLAGS and LDFLAGS substituted from configure.
- * lib/Makefile.in: Have CFLAGS substituted from configure.
- Reported by Eric Backus and Tom McConnell.
-
- * configure.in: m4_undefine changeword before using AC_ENABLE.
-
- * m4.h: Declare prototypes for error (for ANSI compilers only),
- prefix_all_builtins and reference_error.
- Reported by Tom McConnell.
-
- * input.c (set_word_regexp): Do not try to initialize the array
- test from a string, this does not work with non-ANSI compilers.
- Reported by Eric Backus.
-
- * Makefile.in (dist): Clean examples/ before saving it.
- (distclean-local): Also remove stamp-h.
- Reported by Eric Backus.
-
- * Makefile.in (_stackovf.c): Goal for compiling stacokovf.c with
- non ANSI compilers.
- Reported by Tom McConnell.
-
- * checks/Makefile.in (clean): Depends on mostlyclean.
- (mostlyclean): New goal.
-
-1994-06-24 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (DISTFILES): Distribute install.sh.
- * install.sh: New file, copied from elsewhere.
- Reported by Assar Westerlund and Kaveh R. Ghazi.
-
-1994-06-23 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Define ENABLE_CHANGEWORD if --enable-changeword.
- * acconfig.h: Explain ENABLE_CHANGEWORD.
-
- [These modifs all depend upon ENABLE_CHANGEWORD and are adapted
- from code provided by Pete Chown]
- * m4.h: Add original_text field to u_t variant of union u.
- Declare TOKEN_DATA_FUNC macro.
- * builtin.c: Declare changeword.
- (m4_changeword): New function.
- * input.c: Include "regex.h", define variables with word regexps.
- (input_init): Initialize the word regexp.
- (set_word_regexp): New.
- (next_token): Declare local variables, use the previous code if
- default_word_regexp is true. Else, match using a new code. Save
- the original text.
- * macro.c (expand_token): Ship out original text if not a macro
- name.
- Reported by Krste Asanovic and Pete Chown.
-
- [These modifs all depend upon ENABLE_CHANGEWORD]
- * m4.h: Declare external user_word_regexp.
- * m4.c: Declare user_word_regexp, and initialize it from
- --word-regexp or -W, or NULL if not specified.
- * input.c: Use user_word_regexp if specified, instead of
- DEFAULT_WORD_REGEXP.
-
- * Makefile.in (m4): Revert Jan 3 1994 change. I'm unable to
- agree with it.
-
- * Makefile.in, lib/Makefile.in: Limit suffixes to .c and .o.
- * checks/Makefile.in: Empty the suffix list.
- Reported by Geoff Russell, Joel Sherrill and Roland McGrath.
-
- * m4.c: Declare nesting_limit and initialize it to 250.
- Implement -LNUMBER or --nesting-limit=NUMBER to change its
- value.
- * m4.h: Declare nesting_limit as external.
- * macro.c (expand_macro): Stop execution whenever nesting limit
- is exceeded.
- Reported by Bengt Mertensson.
-
- * eval.c (evaluate): Diagnose excess characters in eval input.
- Things like `eval(08)' used to return 0 with no diagnostic.
-
- * m4.h: Capitalize first letter of all macro arguments in
- definitions.
-
- * m4.c: Declare warning_status, initialize it to 0. Add new
- option -E, or --fatal-warnings, which sets warning_status to
- EXIT_FAILURE instead.
- * m4.h: Declare external warning_status. Define EXIT_SUCCESS and
- EXIT_FAILURE if not otherwise done by header files.
- * m4.c: Delete declarations for EXIT_SUCCESS and EXIT_FAILURE.
- * m4.c, input.c, output.c, symtab.c, builtin.c, macro.c, debug.c,
- eval.c: Replace 0 by warning_status and 1 by EXIT_FAILURE in first
- argument of all M4ERROR calls.
- Reported by Noah Friedman.
-
- * examples/incl-test.m4: Renamed from incl_test.m4.
- * examples/include.m4: Include incl-test.m4 instead of
- incl_test.m4.
- * examples/multiquotes.m4: Renamed from multi-quotes.m.
-
-1994-06-22 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Avoid USE_STACKOVF if <siginfo.h> not found. Note
- that Jim developped stackovf.c on a 486 running SVR4.0 (ESIX), and
- also tested it on a Sun Sparc workstation running SunOS 4.x.
-
- * format.c (format): When not HAVE_EFGCVT, m4 was failing the
- 49.format check, abusing a `union values' argument with sprintf
- without selecting the proper field. Now, save the formatting type
- first, delaying the fetch of the corresponding argument.
- Reported by Joseph E. Sacco and Tom Quinn.
-
- * format.c (format): Remove const from char *fmt declaration when
- not HAVE_EFGCVT, because a NUL may be forced into it.
-
- * m4.h: Declare atof() when not STDC_HEADERS.
- Reported by Joseph E. Sacco.
-
- * Regenerate configure using Autoconf 1.11, this corrects a
- problem about an incorrect cpp seting on NeXT 3.1.
- Reported by Alexander Lehmann.
-
-1994-06-05 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h (_): Change argument from `x' to `Args'.
-
-1994-04-22 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Rename Args() to _().
- * m4.h: Remove extern specifier from all function declarations.
-
-1994-04-22 Jim Avera <jima@netcom.com>
-
- * stackovf.c: New file implementing stack-overflow detection.
- * configure.in: Check for getrlimit, sigaction. If all of
- standard headers, getrlimit and sigaction, define USE_STACKOVF and
- substitute ${U}stackovf.o for STACKOVF.
- * acconfig.h: Declare USE_STACKOVF.
- * Makefile.in: Distribute stackovf.c, link with $(STACKOVF).
- * m4.h: Declare setup_stackovf_trap().
- * m4.c: Call setup_stackovf_trap().
- * tests/stackovf_test.sh: New file.
-
-1994-04-13 François Pinard <pinard@iro.umontreal.ca>
-
- * checks/Makefile.in: Rename .all-stamp to stamp-checks.
-
- * Makefile.in (Makefile, etc.): Adapt for Autoconf 1.8.
-
-1994-01-30 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Remove definition of volatile, not used anymore.
- Reported by Jim Meyering and Joseph E. Sacco.
-
- * m4.h: Consistently use `do { ... } while (0)' in macros, instead
- of `if ... else /* nothing */' for if macros.
- Reported by Jim Meyering.
-
- * builtin.c (m4_regexp): Reorganize the code for avoiding a
- warning from gcc about `repl' possibly used before defined.
- Reported by Jim Meyering.
-
- * m4.h: Avoid a pre-ANSI <memory.h> together with <string.h>.
- Reported by Jim Meyering.
-
-1994-01-25 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Move the conditional definition of volatile after the
- inclusion of system files, because they may define it first.
-
-1994-01-04 François Pinard <pinard@iro.umontreal.ca>
-
- * checks/Makefile.in (CHECKS): Add a useless `*' before `[', to
- get around a problem with Alpha make seeing a syntax error, there.
- Reported by Vern Paxson.
-
-1994-01-03 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in: Do not define LDFLAGS, use CFLAGS on link calls.
- Reported by Richard Stallman.
-
-1993-12-25 François Pinard <pinard@iro.umontreal.ca>
-
- * configure.in: Correct test for strerror, AC_FUNC_CHECK was used
- instead of AC_HAVE_FUNCS.
- Reported by Noah Friedman.
-
-1993-12-01 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.c: Initialize show_help and show_version to zero.
-
- * m4.c: Ensure EXIT_SUCCESS and EXIT_FAILURE are defined.
- Use them in exit() and usage() calls.
-
-1993-11-27 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Delete extern sys_nerr, sys_errlist declarations, and
- syserr() macro. Delete errref, add reference_error and M4ERROR.
- * m4.c: Replace errref, which was returning an input reference
- string, with reference_error, which prints it on standard error.
- * builtin.c, output.c: Use errno as second parameter to error,
- instead of using syserr() with %s.
- * *.c: Use M4ERROR instead of error: no more errref() with %s.
- Doing so, the program name appears after the input reference
- instead of before, which eases M-x next-error processing.
-
-1993-11-24 François Pinard <pinard@iro.umontreal.ca>
-
- * checks/get-them: Escape braces with backslashes in patterns,
- because HPUX-9.01 awk needs this.
- Reported by Jim Meyering.
-
-1993-11-22 François Pinard <pinard@iro.umontreal.ca>
-
- * builtin.c: Declare "FILE *popen ();".
-
- * m4.h: Remove MESSAGE{,1,2}, WARNING1, FATAL{,1}, INTERNAL_ERROR
- macros, replace error_message_prefix() declaration by errref()'s.
- Declare xrealloc, for use in errref().
- * m4.c: Delete error_message_prefix() function, add errref().
- * *.c: Use error() systematically in place of all error macros,
- now that error() flushes stdout first. Make needed adjustments.
-
- * m4.h: Remove const in sys_errlist[] declaration, it creates
- conflicts on SGI and Alpha.
- Reported by Kaveh R. Ghazi.
-
-1993-11-20 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.c: Include <getopt.h> instead of "getopt.h".
-
- * configure.in: Output to config.h. Use HAVE_FUNCS preferably.
- * acconfig.h: New, for documenting HAVE_EFGCVT.
- * Makefile.in: Distribute acconfig.h, .stamp-h.in and config.h.in,
- use them wherever appropriate. Also use -I. for compilations.
- * lib/Makefile.in: Use -I.. for compilations.
- * *.c: Include <config.h> or "config.h".
-
- * m4.h: Test for HAVE_MEMORY_H instead of NEED_MEMORY_H.
- * configure.in: Use AC_HAVE_HEADERS(memory.h), delete AC_MEMORY_H.
-
-1993-11-17 François Pinard <pinard@iro.umontreal.ca>
-
- * builtin.c (m4_eval): Cast strlen to (int) before comparing.
-
- * input.c (input_init): Initialize quote and comment strings
- explicitely instead of calling set_quotes and set_comment: by
- doing so, we ensure we do not free uninitialized variables.
-
- * checks/check-them: Reverse arguments to both diff, so the
- expected is on the left and the obtained on the right.
-
- * m4.h: Add MESSAGE{,1,2}, WARNING1, FATAL{,1} and INTERNAL_ERROR
- macros. Delete declarations for m4error, warning, fatal and
- internal_error, add declaration for error_message_prefix.
- * m4.c: Delete m4error, warning, fatal and internal_error
- routines, add error_message_prefix routine.
- * *.c: Replace m4error routine calls with MESSAGE* macro calls,
- warning with WARNING*, fatal with FATAL* and internal_error with
- INTERNAL_ERROR*.
- * Makefile.in (_m4.c): Do not adjust ansi2knr output for va_alist,
- this is not needed anymore.
-
- * m4.h: Declare extern FILE *debug. Add DEBUG_PRINT{1,3} and
- DEBUG_MESSAGE{,1,2} macros. Delete declarations for debug_print
- and debug_message, add declaration for debug_message_prefix.
- * debug.c: Remove static specifier for FILE *debug declaration.
- Delete debug_print and debug_message routines, add
- debug_message_prefix routine.
- * builtin.c, debug.c: Replace debug_print routine calls with
- DEBUG_PRINT* macro calls.
- * input.c, path.c: Replace debug_message routine calls with
- DEBUG_MESSAGE* macro calls.
-
- * m4.h: Remove inclusion of <varargs.h>.
- * debug.c: Include <stdarg.h> or <varargs.h>.
- (trace_format): Use stdarg instead of varargs if __STDC__.
-
- * configure.in: Remove checks for vfprintf and _doprnt. These
- implementations use varargs tricks which are not portable enough.
- * lib/vfprintf.c: Deleted.
- * lib/_doprnt.c: Deleted.
- * lib/Makefile.in: Adjusted accordingly. Remove LIBOBJS.
- Reported by Joel Sherrill.
-
- * path.c (add_include_directory): Use xstrdup.
-
- * builtin.c (find_builtin_by_name): Declare static.
-
- * *.[ch]: Add const to a few "char *" declarations.
-
- * configure.in: Remove commented tests for fileno() and fstat().
- * debug.c: Remove comments about HAVE_FILENO and HAVE_FSTAT.
-
- * debug.c (debug_flush_files): New.
- * m4.h: Declares it.
- * builtin.c (m4_syscmd, m4_esyscmd): Use it.
- Reported by Nicolas Pioch.
-
-1993-11-12 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (m4.dvi): Use m4.texinfo instead of m4.texi.
- Reported by Joel Sherrill.
-
- * builtin.c (prefix_all_builtins): Instead of the table size, use
- the null entry at end for stopping the loop. It was overwritten.
- Reported by Andreas Schwab and Jim Meyering.
-
- * builtin.c (prefix_all_builtins): Cast xmalloc to (char *).
- Reported by Kaveh R. Ghazi.
-
- * macro.c (call_macro): Add * in (*SYMBOL_FUNC (sym)) (...).
- Reported by Karl Vogel.
-
-1993-11-09 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Do not define volatile if already defined.
- Reported by René Seindal.
-
- * lib/Makefile.in: Add a forgotten ALLOCA=@ALLOCA@. Grrr!
-
- Reported by Bernhard Daeubler, Eric Backus, Hal Peterson, Hoang
- Uong, Ian Taylor, Kaveh R. Ghazi, Tom McConnell and Walter Wong.
-
-1993-11-08 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Define strchr and strrchr in terms of index and rindex,
- instead of the other way around.
- * builtin.c, m4.c, path.c: Use strchr instead of index.
-
- * input.c (next_char): Remove a "break;" after a "return ...;".
- Reported by Tom McConnell.
-
-1993-11-08 François Pinard <pinard@iro.umontreal.ca>
-
- * Release 1.1
-
- * configure.in: Do not copy check files in the build hierarchy.
- * checks/check-them: Identify the m4 version being checked. For
- finding m4, look in $PATH instead of in the parent directory.
- * Makefile.in (check): Prepend `pwd` to $PATH before checking.
- * checks/Makefile.in (.all-stamp): Always create check files in
- the source hierarchy, not anymore in the build hierarchy.
- (check): cd to the source hierarchy before performing checks.
- Do not copy nor clean COPYING anymore, take it from `..'.
- Reported by Tom McConnell.
-
- * Makefile.in (Makefile): Use $(SHELL).
- (config.status): Use $(SHELL). Use "config.status --recheck"
- instead of "configure --no-create", which is obsolete.
- Reported by Tom McConnell.
-
-1993-11-05 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.c (usage): Use "%s" instead of "m4" in format string.
- Reported by Jim Meyering.
-
- * Makefile.in: Distribute mkinstalldirs.
- Reported by Pierre Gaumond.
- Reported by Jim Meyering.
- Reported by Tom McConnell.
- Reported by Andreas Gustafsson.
-
- * checks/check-them: Renamed from checks/check_them.
- * checks/get-them: Renamed from checks/get_them.
- * checks/.all-stamp: Renamed from checks/.all_stamp.
- * checks/Makefile.in: Changed accordingly.
- Reported by Jim Meyering.
-
-1993-11-04 François Pinard <pinard@iro.umontreal.ca>
-
- * lib/Makefile.in (dist): Correct permissions on files.
-
- * output.c: Declare tmpfile, some systems don't.
-
-1993-11-03 François Pinard <pinard@iro.umontreal.ca>
-
- * checks/Makefile.in (dist): Correct permissions on files.
-
- * Makefile.in (dist): Ensure recursive linking for subdirectory
- `examples', also set read/write permissions on all its files.
-
- * mkinstalldirs: New, from elsewhere.
- * Makefile.in: Use it.
-
- * debug.c: Synchronize debug messages and regular output when
- the debug file and stdout are redirected to the same file.
- * configure.in: Add (commented) checks for fileno and fstat.
- Reported by Jim Avera.
-
- * builtin.c (m4_ifelse): Diagnose excess arguments if 5, 8, 11,
- etc., arguments, then ignore the superfluous one. m4 used to
- diagnose missing arguments and return the empty string.
- Reported by Nick S. Kanakakorn.
-
-1993-11-02 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.c (main): At end of all input, ensure all undiverted text
- goes to the main output stream.
- Reported by Andreas Gustafsson.
-
- * m4.c (main): exit (0), instead of return 0.
-
- * m4.c: Implement -P and --prefix-builtins.
- * builtin.c: Delete const specifier on builtin_tab.
- (prefix_all_builtins): New.
- Reported by Noah Friedman.
- Reported by Scott Bartram.
-
- * c-boxes.el: New, from elsewhere.
- * Makefile.in: Distribute it.
-
- * m4.h: Do not define bcopy if <string.h> defines it.
- Reported by Stephen Perkins.
-
- * builtin.c (define_macro): Allow a missing second argument, in
- which case it is implied empty. Affects define and pushdef.
- Reported by Eric Allman.
-
-1993-11-01 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Add blind_if_no_args in struct builtin, blind_no_args in
- struct symbol adn SYMBOL_BLIND_NO_ARGS macro.
- * builtin.c: Initialize all the blindness fields in builtin_tab.
- (define_builtin): Copy the blindness of a builtin into its symbol.
- * macro.c (expand_token): Avoid processing a blind builtin if the
- next character is not an opening parenthesis.
- Reported by David MacKenzie.
- Reported by Noah Friedman.
-
- * configure.in: Ensure an exit status of 0 on completion.
- Reported by Vivek P. Singhal.
-
- * eval.c (eval_lex): Admit both lower and upper case letters for
- bases greater than 10. Only lower case letters were accepted.
-
- * eval.c (eval_lex): Recognize 0bDIGITS and 0rRADIX:DIGITS syntax.
- Reported by Krste Asanovic.
-
- * eval.c: Rename NOT to LNOT. Add XOR, NOT, LSHIFT and RSHIFT.
- * eval.c (logical_not_term): New name for not_term.
- * eval.c (xor_term): New, between or_term and and_term.
- * eval.c (not_term): New, between and_term and logical_not_term.
- * eval.c (shift_term): New, between cmp_term and add_term.
- Reported by Krste Asanovic: ~, ^, <<, >>.
- Reported by Ben A. Mesander: ** vs ^.
-
- * m4.c: Delete xmalloc.c, xrealloc.c, xstrdup.c.
- * m4.h: Delete xrealloc.c.
- * lib/xmalloc.c: New, from elsewhere.
- * lib/xstrdup.c: New, from elsewhere.
- * lib/Makefile.in: Distribute and compile them.
-
- * m4.c: Change progname to program_name.
- * builtin.c, eval.c, m4.c, m4.h: Rename error to m4error.
- * lib/error.c: New, from elsewhere.
- * lib/Makefile.in: Distribute and compile error.c.
- * configure.in: Check AC_VPRINTF and for strerror.
- * m4.c: Delete cmd_error. Use error instead.
- * m4.c: Change label capitalisation to "ERROR", "Warning", etc.
-
- * m4.h: Delete #define const, let Autoconf takes care of this.
-
- * m4.c: Remove all code conditionalized by IMPLEMENT_M4OPTS.
- Merge parse_args into main. Declare argv to be `char *const *',
- then remove superfluous casts.
-
- * m4.c: Rename --no-gnu-extensions to --traditional.
- Reported by Ben A. Mesander.
-
- * m4.c (usage): Add a status parameter. Supply one in various
- calls. Add --help processing. Remove -V for --version.
-
- * lib/Makefile.in: Put $(CFLAGS) last in .c.o rule.
-
- * lib/Makefile.in: Have an AR=ar declaration.
- Reported by Eric Backus.
- Reported by Bjorn R. Bjornsson.
- Reported by Tom Tromey.
- Reported by Kristine Lund.
- Reported by Marion Hakanson.
-
-1993-10-30 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (m4.info): Use -I$(srcdir) on $(MAKEINFO).
- Reported by Noah Friedman.
-
-1993-10-25 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in: Remove MDEFINES and cleanup.
-
-1993-06-09 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (dist): Replace "echo `pwd`" by a mere "pwd".
- Create a gzip file.
-
-1993-02-06 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in, lib/Makefile.in, check/Makefile.in: In dist goals,
- ensure 777 mode for directories, so older tar's will restore file
- modes properly.
-
-1993-01-17 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in, lib/Makefile.in: Put $(CFLAGS) after $(CPPFLAGS),
- so the installer can override automatically configured choices.
- Reported by Karl Berry.
-
-1993-01-15 François Pinard <pinard@iro.umontreal.ca>
-
- * lib/vfprintf.c: Stolen from Oleo distribution and adapted. The
- previous version was not working properly on m68k-hp-bsd4.3.
- Reported by Roland McGrath.
-
- * lib/_doprnt.c: Stolen from Oleo distribution.
- * configure.in: Check for _doprnt.c if vfprintf.c selected.
- * lib/Makefile.in: Distribute _doprnt.c.
- Do not distribute regex.[ch].old anymore.
-
-1993-01-01 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in, lib/Makefile.in: Reinstate $(CPPFLAGS), use it.
- Richard wants it there.
-
-1992-12-27 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in: Add DEFS to MDEFINES.
- * lib/Makefile.in (.c.o): Remove $(CPPFLAGS).
- (libm4.a): Remove the library before creating it.
- (distclean): Remove tags and TAGS too.
-
-1992-12-23 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (dvi, m4.dvi): New goals.
-
- * builtin.c, eval.c, format.c, input.c, m4.[ch], m4.texinfo,
- macro.c, output.c, path.c, symtab.c: Change Copyright from
- 1989-1992 to the explicit enumeration 1989, 1990, 1991, 1992.
-
- * examples/divert.m4: Deleted, this bug has been corrected.
-
- * Makefile.in (texclean, mostlyclean): New goals.
-
- * Makefile.in (clean): Remove clutter from ansi2knr.
- Reported by Pierre Gaumond.
-
-1992-12-20 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in: Remove $(CPPFLAGS) from the .c.o rule. The user
- might well use CFLAGS is s/he needs it.
-
- * Makefile.in: Allow installation of info files from a separate
- build directory.
- Reported by Jason Merrill.
- Reported by David MacKenzie.
- Reported by Skip Montanaro.
- Reported by Erez Zadok.
- Reported by Assar Westerlund.
-
-1992-12-19 François Pinard <pinard@iro.umontreal.ca>
-
- * Release 1.0.3
- This is still a beta release for the future GNU m4 version 1.1.
-
- * lib/alloca.c: New, from elsewhere.
- * lib/Makefile.in: Distribute it. Define and use $(ALLOCA).
-
- * m4.h: Do not define index/rindex if already defined. If
- FALSE/TRUE are already defined, do not redefine them, but merely
- define boolean typedef to int.
-
- * Makefile.in: Use $(DEFS) while compiling ansi2knr.
- * ansi2knr.c: Rewrite #ifdef HAVE_STRING_H || STDC_HEADERS,
- because some C compilers do not like connectives with #ifdef.
- * m4.h: Define `volatile' only if __GNUC__, instead of once for
- __GNUC__ and once for __STDC__.
- * lib/regex.h: Leave const alone, AC_CONST will take care of it.
-
- * checks/Makefile.in: Use .all_stamp instead of $(CHECKS) for
- Makefile dependencies. Without it, make keeps destroying and
- remaking $(CHECKS) in a loop (why?). Distribute .all_stamp.
-
- * m4.h, m4.c, builtin.c, output.c: Change all divertion/DIVERTION
- to diversion/DIVERSION, this was a spelling error.
-
- * m4.c: Declare version[], remove #include "version.h".
- * version.h: Deleted.
- * Makefile.in: Remove references to version.h.
-
- * output.c (shipout_text): Centralize all `#line NUM ["FILE"]'
- production, by using a simpler and more robust algorithm. This
- solves the problem of synclines sometimes written in the middle of
- an output line. Delete sync_line() and output_lines variable.
- * m4.h: Remove sync_line prototype and output_lines declaration.
- * input.c (next_char), output.c (shipout_text): Remove references
- to output_lines.
- * input.c (push_file, pop_file): Merely put the value -1 in
- output_current_line instead of calling sync_line, for delaying a
- single `#line NUM FILE' before next output line. Do not test
- for sync_output, because this is unnecessary clutter.
- * output.c (make_divertion, insert_divertion): Idem.
- * input.c: Rename must_advance_line to start_of_input_line, for
- consistency.
-
- * debug.c (trace_header): Select a new debug line format, which
- better complies with GNU standards for formatting error messages.
- With option `-dfl', M-x next-error might be used on the output.
- * m4.c (vmesg): Adjust format of error output to GNU standards.
- * m4.texinfo: Adjust examples for `make check' to work.
-
- * m4.h, builtin.c, debug.c, input.c, macro.c, path.c: Use upper
- case for enum debug_info constants, which were all lower case.
-
- * builtin.c (m4_regexp, m4_patsubst): Use re_search instead of
- re_search_2.
- * lib/regex.[ch]: Use new version from textutils 1.3.6, with some
- collected patches. I tried a few times using newer regex.[ch], it
- mysteriously stopped aborting with this one. Insecure feeling...
- * lib/Makefile.in: Distribute regex.[ch].old, just in case!
-
-1992-12-18 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.c: Change `--no-warnings' to `--silent'.
- Reported by David MacKenzie.
-
- * m4.c: Put all M4OPTS code upon IMPLEMENT_M4OPTS control, and
- leave it off for now. See comment in m4.c for justification.
- Reported by David MacKenzie.
-
- * configure.in: Replace AC_USG by AC_HAVE_HEADERS(string.h).
- * m4.h, ansi2knr.c, lib/regex.h: Replace USG by HAVE_STRING_H.
-
- * Makefile.in: Add a new `info' goal. Use macro MAKEINFO.
-
- * Makefile.in: Ensure recursive cleaning is done before local
- cleaning for all clean goals.
-
- * builtin.c (ntoa): Ensure the value is always interpreted as a
- signed quantity, whatever the radix is.
-
-1992-11-18 Jim Meyering <meyering@idefix>
-
- * builtin.c, format.c, input.c: Split long lines.
- * m4.c: Use typedef macro_definition instead of struct
- macro_definition.
- * symtab.c: Use typedef symbol instead of struct symbol.
-
-1992-11-17 François Pinard <pinard@iro.umontreal.ca>
-
- * *.[ch]: Remove all trailing whitespace, in code and comments.
-
- * configure.in: Find some awk.
- * Makefile.in: Add $(AWK) to MDEFINES.
- * checks/Makefile.in: Transmit $(AWK) to get_them.
- * checks/get_them: Use $AWK instead of gawk. Add a close in the
- awk script when switching files, because without this, mawk runs
- out of file descriptors.
-
-1992-11-16 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (realclean): Delete m4.info*.
- Reported by Jim Meyering.
-
- * Makefile.in: Adjust and link with checks/Makefile.
- * checks/Makefile.in: New.
- * configure.in: Output checks/Makefile.
-
- * checks/get_them: Have the dnl header of each test more
- recognizable by next-error, also use a better message.
-
-1992-11-16 Jim Meyering <meyering@idefix>
-
- * m4.h [__GNUC__]: Use __volatile__ instead of `volatile.'
- And use that only if __GNUC__ since we're using it's GCC-specific
- semantics that tell the compiler the associated function doesn't
- return.
-
- * builtin.c (substitute): Don't use character as an array index.
- (dumpdef_cmp): Make formal arguments `const void *' to avoid
- warnings with gcc -W -Wall on systems with qsort prototype.
- (m4_errprint): Cast obstack_finish to `char *' to avoid warnings
- from gcc -W -Wall.
-
- * eval.c (most functions): Add parentheses to assignments used
- as truth values go avoid warnings from gcc -Wall.
-
- * input.c, m4.c, output.c, path.c, symtab.c: Declare static
- any functions that don't need external scope.
-
- * builtin.c, debug.c, format.c, m4.c, m4.h, macro.c, symtab.c
- (many functions and arrays): Declare `const'.
-
-1992-11-15 François Pinard <pinard@iro.umontreal.ca>
-
- * *.[ch]: Rename nil to NULL, using the declaration from <stdio.h>,
- removing the declaration from m4.h. Also rename false to FALSE
- and true to TRUE.
-
- * lib/Makefile.in (Makefile): New goal.
-
- * Makefile.in, lib/Makefile.in: Add a .c.o rule, so CFLAGS is not
- so heavily loaded. It gets more easily overridable, calling make.
- Reported by Jim Meyering.
-
- * Makefile.in (dist): Get .fname from the current directory name,
- instead of from version.h. I need updating many files manually,
- when the version changes, version.h is just one of them.
-
-1992-11-14 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Remove the tag `boolean' on the enum introducing typedef
- `boolean'. This tag conflicts with <sys/types.h> on SVR4.
- Reported by Tom McConnell.
-
-1992-11-13 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.texinfo: Correct the examples for 33.divert, 38.divnum,
- 39.cleardiv, which were describing missing or spurious newlines.
- Modify examples 52.eval, 53.esyscmd and 54.sysval so the results
- do not depend on machine word size, `/bin/false' implementation,
- or `wc' output format. `make check' is more dependable, now.
-
- * checks/check_them: Summarize the failed tests by listing their
- name, at end. If none, issue `All checks successful'. Output
- `Checking' instead of `Input file:'.
-
- * checks/get_them, checks/check_them: Reindented.
-
- * Makefile.in (dist): chmod a+r before making the tar file.
-
-1992-11-12 François Pinard <pinard@iro.umontreal.ca>
-
- * builtin.c (m4_dnl): Diagnose any parameter to `dnl'.
-
- * input.c (next_token): Reinitialize token_buttom just after using
- it as a watermark with obstack_free. Or else, a future token, big
- enough for triggering reallocation of the obstack chunk, could
- void the initialized value of token_buttom, later causing panic in
- obstack_free. Rename token_buttom to token_bottom everywhere.
-
- * m4.h: Before declaring errno, first include <errno.h> and
- ensure that it does not define errno.
- Reported by Richard Stallman.
-
-1992-11-11 François Pinard <pinard@iro.umontreal.ca>
-
- * builtin.c: Define and use DECLARE macro for builtins.
-
- * builtin.c (m4_ifelse): Avoid any diagnostic when exactly one
- argument, this is a common idiom for introducing long comments.
-
- * builtin.c (m4_ifelse): If 3n + 2 arguments, diagnose missing
- arguments. The last argument was silently ignored.
-
- * m4.c (cmd_error): Add a missing semicolon before va_end().
-
-1992-11-10 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in: Now handle protoized sources. Define and use U.
- Compile and use ansi2knr with old compilers. Update DISTFILES.
- Add `aclocal.m4' to `configure' dependencies.
- * ansi2knr.c: New, from Ghostscript distribution.
- * configure.in: Define U through FP_PROTOTYPES for old compilers.
- Add AC_ISC_POSIX, AC_CONST, AC_SIZE_T.
- * aclocal.m4: New, provide FP_PROTOTYPES.
- * m4.h: Conditionnaly protoized through Args, save for varags.
- * builtin.c: Protoized. Then:
- Include <sys/types.h> if size_t is not defined, before "regex.h".
- (m4_ifelse): Fetch built-in name properly for diagnostic.
- (m4_dumpdef): Remove wrong (char *) cast calling dump_symbol.
- (m4_regexp): Add const to `msg' declaration.
- (m4_patsubst): Add const to `msg' declaration.
- * debug.c: Protoized, save for varargs.
- * eval.c: Protoized.
- * format.c: Protoized.
- * input.c: Protoized.
- * m4.c: Protoized, save for varargs. Then:
- (xfree): Accept void * instead of char *.
- (xmalloc): Return void * instead of char *.
- (xrealloc): Accept and return void * instead of char *.
- * macro.c: Protoized.
- * output.c: Protoized.
- * path.c: Protoized. Then cast some (char *) over xmalloc's.
- * symtab.c: Protoized.
-
-1992-11-06 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.texinfo: Remove directory from diagnostics in 30.include,
- 51.eval, 56.errprint and 57.m4exit tests.
-
- * m4.h: Remove declarations for int or void system functions, they
- cause more conflicting trouble than they make good.
-
- * configure.in: Avoid configuration header file. Add some tests.
- * m4.h: Remove #include "config.h".
- * Makefile.in, lib/Makefile.in: Implement Autoconf interface.
- Then, rewritten for better compliance with GNU standards.
-
-1992-11-05 François Pinard <pinard@iro.umontreal.ca>
-
- * format.c (format): Avoid syntax error if not HAVE_EFGCVT,
- because of a misplaced #endif.
-
- * Many *.[hc] files: Correct intra-line spacing here and there,
- according to GNU indent 1.6 advice.
-
- * configure.in: New, using Autoconf 1.2.
- * m4.h: Reverse NO_MEMORY_H to NEED_MEMORY_H.
- * Delete old configure.in, configure, etc/configure.in,
- etc/configure, lib/configure.in, lib/configure and config/*.
- Reported by Jason Merrill.
-
- * symtab.c (hash): Change (char) NULL to '\0'.
- Reported by Jason Merrill.
-
- * Delete .vers, etc/newdist.sh, etc/newvers.sh and
- etc/nextvers.sh. Release numbers will be edited `by hand'.
- * version.h: De-automatize, force value in.
-
- * m4.c: Changes in order to use a newer getopt.h.
- Reported by David MacKenzie.
-
- * checks/: New name for examples/.
- * checks/get_them: New location for etc/get_examples.
- * checks/check_them: New location for etc/check_examples.
- * Makefile.in, checks/get_them, checks/check_them: Adjust.
- * lib/vfprintf.c: New location for etc/vfprintf.c.
- * Delete empty etc/.
- * examples/: New name for test/.
-
-1992-03-10 François Pinard <pinard@iro.umontreal.ca>
-
- * Makefile.in (check): Add m4 as dependency.
-
- * m4.c: Accept --no-warnings instead of --no_warnings, and
- --no-gnu-extensions instead of --no_gnu_extensions. Make the
- usage message more informative.
- Reported by David MacKenzie.
-
-1992-03-09 François Pinard <pinard@iro.umontreal.ca>
-
- * etc/check_examples: New name for check_examples.sh.
- * etc/get_examples: New name for get_examples.sh.
- * Makefile.in, etc/Makefile.in: Use new names.
-
- * Makefile.in: Transmit $(CC) while making in lib.
-
- * Many *.[hc] files: GNU indent'ed, with further fine tuning of
- code disposition by hand.
-
-1992-03-08 François Pinard <pinard@iro.umontreal.ca>
-
- * m4.h: Delete definitions for abort() and exit().
- Reported by Richard Stallman.
-
- * config/hmake-unicos, config/s-unicos.h: New files.
- Reported by Hal Peterson.
-
- * eval.c (exp_term): Have N^0 return 1.
- Reported by Michael Fetterman.
-
- * eval.c, input.c, m4.h: Remove last comma in enums.
- Reported by Mike Lijewski.
-
- * Transfer of maintenance duties from René to François.
-
-1991-10-24 René Seindal <seindal@diku.dk>
-
- * Release 1.0. Many thanks to those, who provided me with bug
- reports and feedback.
-
- * Uses GNU configure, taken from the gdb distribution.
-
- * Uses GNU getopt(), with long option names.
-
- * The -Q/+quiet option is added, which suppresses warnings about
- missing or superflous arguments to built-in macros.
-
- * Added default options via the M4OPTS environment variable.
-
- * The built-in format can now be configured to use sprintf as
- the formatting engine, for systems without [efg]cvt(3).
-
- * GNU library code is moved to the ./lib subdirectory; other
- utility files are now in ./etc.
-
- * Several minor bugs have been fixed.
-
-1991-07-26 René Seindal <seindal@diku.dk>
-
- * Fixed various bugs. Release 0.99, manual 0.09. Many thanks to
- François Pinard and Roland H. Pesch for providing me with reports.
-
- * The builtins incr and decr are now implemented without use of
- eval.
-
- * The builtin indir is added, to allow for indirect macro calls
- (allows use of "illegal" macro names).
-
- * The debugging and tracing facilities has been enhanced
- considerably. See the manual for details.
-
- * The -tMACRO option is added, marks MACRO for tracing as soon
- as it is defined.
-
- * Builtins are traced after renaming iff they were before.
-
- * Named files can now be undiverted.
-
- * The -Nnum option can be used to increase the number of
- divertions available.
-
- * Calling changecom without arguments now disables all comment
- handling.
-
- * The function m4_patsubst() is now consistently declared
- static.
-
- * A bug in dnl is fixed.
-
- * A bug in the multi-character quoting code is fixed.
-
- * Several typos in the manual has been corrected. More probably
- persist.
-
- * The m4.info file is now installed along with the program.
-
-1990-11-15 René Seindal <seindal@diku.dk>
-
- * Updated and enhanced version. Release 0.75, manual 0.07.
-
- * Implemented search path for include files (-I option and
- M4PATH envronment variable).
-
- * Implemented builtin "format" for printf-like formatting.
-
- * Implemented builtin "regexp" for searching for regular
- expressions.
-
- * Implemented builtin "patsubst" for substitution with regular
- expressions.
-
- * Implemented builtin "esyscmd", which expands to a shell
- commands output.
-
- * Implemented "__file__" and "__line__" for use in error
- messages.
-
- * Implemented character ranges in "translit".
-
- * Implemented control over debugging output.
-
- * Implemented multi-character quotes.
-
- * Implemented multi-character comment delimiters.
-
- * Changed predefined macro "gnu" to "__gnu__".
-
- * Changed predefined macro "unix" to "__unix__", when the -G
- option is not used. With -G, "unix" is still defined.
-
- * Changed "shift", "$@" and "$*" to not insert spaces afters
- commas.
-
- * Added program name to error messages.
-
- * Fixed two missing null bytes bugs.
-
-1990-01-22 René Seindal <seindal@diku.dk>
-
- * Initial beta release. Release 0.50, manual 0.05.
-
-
- -----
-
- Local Variables:
- coding: utf-8
- End:
-
- Copyright (C) 1990-1994, 2000-2001, 2003, 2005-2010, 2013-2014,
- 2017 Free Software Foundation, Inc.
-
- Copying and distribution of this file, with or without
- modification, are permitted provided the copyright notice
- and this notice are preserved.
diff --git a/HACKING b/HACKING
deleted file mode 100644
index 0e5cd66b..00000000
--- a/HACKING
+++ /dev/null
@@ -1,334 +0,0 @@
-GNU M4
-******
-
-1. Introduction
-===============
-
-This file attempts to describe the processes we use to maintain M4,
-and is not part of a release distribution.
-
-
-2. Maintenance Notes
-====================
-
-* If you incorporate a change from somebody on the net:
- If it is a large change, you must make sure they have signed the
- appropriate paperwork, and be sure to add their name and email
- address to THANKS. AUTHORS is built from the FSF list of copyright
- assignments, on fencepost.gnu.org.
-
-* If somebody reports a new bug, write a test case, then mention his
- name in the ChangeLog entry.
-
-* The correct response to most actual bugs is to write a new test case
- which demonstrates the bug. Then fix the bug, re-run the test suite,
- and check everything in.
-
-* Changes with user-visible effects must be mentioned in NEWS.
-
-* New macros must be blind, or else prefixed with `m4' or `__', in
- order to minimize backward compatibility issues with previous
- releases of M4 when processing English text.
-
-* GNU Coding Standards should be followed:
- http://www.gnu.org/prep/standards/
- Additionally, while GNU M4 is not yet POSIX compliant, we are trying
- to get closer to it (although some design decisions state that POSIX
- compliance should only happen when POSIXLY_CORRECT is in the
- environment or the -G option was passed on the command line):
- http://www.opengroup.org/onlinepubs/009695399/utilities/m4.html
-
-* Except for third-party files (libtool, gnulib, ...), all .c files
- should #include <config.h> before anything else (since there are some
- #defines in config.h that potentially impact system headers, such as
- when the user does ./configure --disable-assert). This means that no
- .h files need to #include <config.h>. However, users compiling
- external modules should be able to compile without <config.h>, since
- <config.h> is specific to the M4 build and is not installable.
-
-
-3. Bootstrapping
-================
-
-* The master M4 repository is stored in git. You can obtain a read-only
- copy with:
- git clone git://git.sv.gnu.org/m4.git
- or
- cvs -d:pserver:anonymous@pserver.git.sv.gnu.org:/srv/git/m4.git \
- co -d m4 HEAD
-
- If you are a member of the savannah group for M4, a read-write
- copy can be obtained by:
- git clone <savannah-user>@git.sv.gnu.org:/srv/git/m4.git
-
-* Before you can build from git, you need to bootstrap. This requires:
- - A pre-installed version of GNU M4 1.4.5 or later, built from a
- package (recommend 1.4.13 or later)
- - A git checkout of Autoconf (2.63b-41 or later)
- - Automake 1.10b or later
- - Libtool 2.2 or later
- - Gettext 0.16 or later
- - Gperf 3.0 or later
- - Help2man 1.29 or later
- - Xz 4.999.8beta or later (from <http://tukaani.org/xz/>)
- - Texinfo 4.8 or later
- - Any prerequisites of the above (such as perl, tex)
-
- Note that none of these bootstrapping dependencies should be required
- by a distributed release.
-
-* M4 includes gnulib as a git submodule. By default, the bootstrap
- script will attempt to run
- git submodule update --init
- to grab a gnulib clone from the official read-only location of
- git://git.sv.gnu.org/gnulib.git
-
- However, this can be network and disk intensive. If you already have
- another gnulib clone on your disk, you can use the environment
- variable GNULIB_SRCDIR to point to the previous checkout to speed up
- the process. Additionally, both the bootstrap script and gnulib-tool
- require a shell that supports functions, so you can set the
- environment variable CONFIG_SHELL to choose a better shell on systems
- (like Solaris) where /bin/sh is lacking. Thus, you may find it
- convenient to run:
- GNULIB_SRCDIR=path/to/gnulib CONFIG_SHELL=path/to/sh \
- path/to/sh ./bootstrap
-
- A read-only copy of gnulib can be obtained by:
- git clone git://git.sv.gnu.org/gnulib.git
- or
- cvs -d:pserver:anonymous@pserver.git.sv.gnu.org:/srv/git/gnulib.git \
- co -d gnulib HEAD
-
- Using a CVS checkout might work, but it is relatively untested,
- particularly now that we use a git submodule for gnulib.
-
- If you are a member of the savannah group for gnulib, a read-write
- copy can be obtained by:
- git clone <savannah-user>@git.sv.gnu.org:/srv/git/gnulib.git
-
- If you are behind a firewall that blocks the git protocol, you may
- find it useful to do:
- git config --global url.http://git.savannah.gnu.org/r/.insteadof \
- git://git.sv.gnu.org/
- to force git to transparently rewrite all savannah git references to
- instead use http.
-
-* Either add the gnulib directory to your PATH, or run
- GNULIB_TOOL=path/to/gnulib/gnulib-tool ./bootstrap
-
-* When it is time for a release, it is a good idea to bootstrap with
- official releases of the autotools, rather than git builds, to reduce
- the pain of a user re-running bootstrap on the packaged M4. However,
- files installed by Automake should be updated to the latest version
- from their respective upstream source, rather than the version that
- shipped with the automake release.
-
-* Normally, after running bootstrap, 'git status' should not show any
- differences; if things changed, please provide a patch or at least
- report it as a bug. One case where things are changed is if the
- gnulib submodule comes from an older date than the current installed
- libtool, such that libtoolize will replace the symlinks to an older
- version of build-aux files with their newer counterpart; the fix to
- this is updating the submodule to a newer gnulib version.
-
-* If you would like to check that you are not missing out on any useful
- gnulib modules, comment out the gl_ASSERT_NO_GNULIB_POSIXCHECK in
- configure.ac, then run 'make CFLAGS='-DGNULIB_POSIXCHECK=1' with gcc,
- and look at the resulting warnings.
-
-
-4. Test Suite
-=============
-
-* Use
- make check
- liberally, on as many platforms as you can. Use as many compilers and
- linkers you can.
-
-* Some of the testsuite is generated from the documentation.
- All instances of @example in doc/m4.texinfo that are not preceeded by
- "@comment ignore" are turned into tests in the tests directory.
-
-
-5. Editing 'ChangeLog'
-======================
-
-* The ChangeLog is generated from git commit comments. Each commit log
- should start with a one-line summary, a blank line, and then a
- ChangeLog-style entry for all affected files. However, it's fine --
- even recommended -- to write a few lines of prose describing the
- change, when the summary and ChangeLog entries don't give enough of
- the big picture. Omit the leading TABs that you're used to seeing in
- a "real" ChangeLog file, but keep the maximum line length at 72 or
- smaller, so that the generated ChangeLog lines, each with its leading
- TAB, will not exceed 80 columns. As for the ChangeLog-style content,
- please follow these guidelines:
-
- http://www.gnu.org/software/guile/changelogs/guile-changelogs_3.html
-
-* When in doubt, check that emacs can syntax-color properly in
- change-log-mode. And preferably use emacs 'C-x 4 a'
- (add-change-log-entry-other-window) to open ChangeLog with an
- appropriate new template, which you can then paste into your git
- commit editing session.
-
-* See the GNU Coding Standards document for more details on ChangeLog
- formatting.
-
-6. Formatting
-=============
-
-* Use space-only indentation in nearly all files (Makefile inputs being
- the exception).
-
- If you use Emacs and your m4 working directory name matches,
- this code in your ~/.emacs enables the right mode:
-
- ;; In m4, indent with spaces everywhere (not TABs).
- ;; Exceptions: Makefile and ChangeLog modes.
- (add-hook 'find-file-hook '(lambda ()
- (if (and buffer-file-name
- (string-match "/m4\\>" (buffer-file-name))
- (not (string-equal mode-name "Change Log"))
- (not (string-equal mode-name "Makefile")))
- (setq indent-tabs-mode nil))))
-
-* Since the source code was massively converted from tabs in December
- 2009, you may find it helpful to use 'git diff -w' and 'git blame -w'
- helpful for overlooking the whitespace changes.
-
-* Avoid #ifdefs inside function bodies, whenever possible. If you
- encounter a portability issue, it is better to propose a gnulib module
- that works around it, and have m4 use that module.
-
-
-7. Release Procedure
-====================
-
-* If you are an m4 maintainer, but have not yet registered your
- gpg public key and (preferred) email address with the FSF, send an
- email, preferably GPG-signed, to <ftp-upload@gnu.org> that includes
- the following:
-
- (a) name of package(s) that you are the maintainer for, and your
- preferred email address.
-
- (b) an ASCII armored copy of your GnuPG key, as an attachment.
- ("gpg --export -a YOUR_KEY_ID > mykey.asc" should give you
- this.)
-
- When you have received acknowledgement of your message, the proper GPG
- keys will be registered on ftp-upload.gnu.org and only then will you be
- authorized to upload files to the FSF ftp machines.
-
-* If you do not have access to the mailing list administrative interface,
- approach the list owners for the password. Be sure to check the lists
- (esp. bug-m4) for outstanding bug reports also in the list of
- pending moderation requests. This step is not strictly necessary, but
- helps, since by default, m4-announce rejects all posts, so you have to
- get an administrator to allow your announcement through.
-
-* Make sure you have rsync installed.
-
-* Make sure you have GNU make installed.
-
-* Make sure you have an up-to-date version of help2man installed.
-
-* Make sure your locale is sane, e.g. by exporting LC_ALL=C.
-
-* Make sure you are happy with the particular gnulib version recorded as
- the gnulib submodule. If necessary to update to the latest, run:
- git submodule foreach git pull origin master
- git commit -m 'Update gnulib submodule to latest.' gnulib
- In particular, ensure that the gnulib version is at least as new as
- the latest stable libtool release.
-
-* Update the version number in NEWS, and mention in README whether the
- release is stable. See
- http://www.gnu.org/software/libtool/contribute.html for details of the
- numbering scheme (M4 uses a similar scheme to libtool, although
- intra-release versions carry more information thanks to
- git-version-gen).
-
-* Run ./bootstrap, perhaps with environment variables set.
-
-* Run ./configure (a VPATH build should work, but is less tested).
-
-* Run `make'. The file doc/m4.1 needs to exist for a distribution, and
- be up-to-date with m4 --help output, but `make dist' intentionally
- does not depend on running a built binary.
-
-* Run `git commit' from the source tree if there are any changes from
- the previous steps.
-
-* Run `git tag -s -m <version> -u <gpg_key> v<version>' with the desired
- version number. Do not push anything upstream at this point.
-
-* Run `make distcheck'. If there are any problems, fix them, then run
- `git tag -d v<version>' and start again from the `git commit' step.
-
-* Run `make <target>', with target set to `stable', `alpha', or `beta'
- as appropriate. This will run various additional checks.
-
-* Run './build-aux/gnupload --to [dest].gnu.org:m4 [files]' to create
- detached gpg signature and clear signed directive files, and upload
- the combination to the correct location. For an alpha release,
- gnupload will place files in alpha.gnu.org, in /incoming/alpha; for a
- full release, gnupload will place files in ftp.gnu.org, in
- /incoming/ftp. Verify that the files uploaded successfully before
- sending an announcement.
-
-* Send announcement to m4-discuss@gnu.org, m4-announce@gnu.org, and
- autotools-announce@gnu.org. If not an alpha send to info-gnu@gnu.org
- as well. Use gnulib/build-aux/announce-gen to form an initial
- template for the announcement (you may also need to install the perl
- module Digest::SHA1). Contact a list administrator for m4-announce in
- advance to ensure your post will make it through (the list is normally
- set to silently discard all posts, even from subscribers).
-
-* Update version number in configure.ac to next alpha number.
- See http://www.gnu.org/software/libtool/contribute.html for details of
- the numbering scheme.
-
-* Update NEWS and README to start the intra-release changes, and run
- `git commit'. Then run `git push origin refs/tags/v<version>' to push
- the release tag and complete the release.
-
-* For stable releases, update the webpages.
- Run `build-aux/gnu-web-doc-update', which runs `make web-manual' on a
- temporary git branch corresponding to the release, then copies the
- contents of doc/manual into a CVS checkout of the M4 manual
- repository. Follow up with any needed edits to m4.html, using:
- export CVS_RSH=ssh
- cvs -z3 -d:ext:<user>@cvs.savannah.gnu.org:/web/m4 co m4
-
-* Update the Free Software Directory. Browse to:
- http://directory.fsf.org/project/m4/
- and send an email to <bug-directory@gnu.org> mentioning any content
- that needs to be updated.
-
------------
-Copyright (C) 2004-2010, 2013-2014, 2017 Free Software Foundation, Inc.
-
-The canonical source of this file is maintained with the
-GNU M4 package. Report bugs to bug-m4@gnu.org.
-
-GNU M4 is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-GNU M4 is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-Local Variables:
-mode: text
-fill-column: 72
-End:
-vim:tw=72
diff --git a/Makefile.am b/Makefile.am
deleted file mode 100644
index d4326965..00000000
--- a/Makefile.am
+++ /dev/null
@@ -1,453 +0,0 @@
-## Makefile.am - template for generating Makefile via Automake
-##
-## Copyright (C) 2000-2001, 2003-2010, 2013-2014, 2017 Free Software
-## Foundation, Inc.
-##
-## This file is part of GNU M4.
-##
-## GNU M4 is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## GNU M4 is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-## Written by Gary V. Vaughan <gary@gnu.org>
-
-config_aux_dir = build-aux
-config_macro_dir= $(config_aux_dir)/m4
-
-SUBDIRS = po m4/gnu . doc tests/gnu
-
-ACLOCAL_AMFLAGS = -I build-aux/m4
-AUTOMAKE_OPTIONS = nostdinc
-
-gitlog_to_changelog = $(srcdir)/$(config_aux_dir)/gitlog-to-changelog
-git_log_fix = $(srcdir)/$(config_aux_dir)/git-log-fix
-thanks_gen = $(srcdir)/$(config_aux_dir)/thanks-gen
-
-changelog = $(distdir)/ChangeLog
-changelog_old = $(srcdir)/ChangeLog.old
-thanks = $(distdir)/THANKS
-no_thanks = $(srcdir)/NO-THANKS
-
-# Prime the variables that will be augmented by libtool.
-# FIXME - the -export-symbols-regex ".*" is a hack to work around the
-# fact that on cygwin, the convenience library libltdl exports symbols,
-# which effectively disables the auto-exporting of all other symbols.
-# Revisit this if libtool on cygwin improves.
-# See http://lists.gnu.org/archive/html/libtool-patches/2007-02/msg00062.html
-AM_CPPFLAGS = -I$(srcdir) -I.
-AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
-AM_LDFLAGS = -no-undefined -export-dynamic -export-symbols-regex ".*"
-EXTRA_DIST =
-BUILT_SOURCES =
-CLEANFILES =
-DISTCLEANFILES =
-MOSTLYCLEANFILES=
-MAINTAINERCLEANFILES =
-
-include_HEADERS =
-noinst_LTLIBRARIES=
-lib_LTLIBRARIES =
-check_LTLIBRARIES =
-EXTRA_LTLIBRARIES=
-
-# Additional configuration. Version management comes from suggestions
-# given in build-aux/git-version-gen.
-AM_CPPFLAGS += -Im4/gnu -I$(srcdir)/m4/gnu \
- -Im4 -I$(srcdir)/m4
-AM_LDFLAGS += $(OS2_LDFLAGS)
-EXTRA_DIST += bootstrap cfg.mk maint.mk .version .prev-version \
- $(config_macro_dir)/gnulib-cache.m4
-BUILT_SOURCES += .version
-.version:
- $(AM_V_GEN)echo $(VERSION) > $@-t && mv $@-t $@
-dist-hook: dist-tarball-version
-dist-tarball-version:
- $(AM_V_GEN)echo $(VERSION) > $(distdir)/.tarball-version
-
-dist-hook: $(changelog)
-changelog_start_date = 2011-01-01
-$(changelog): FORCE
- $(AM_V_GEN)if test -d '$(top_srcdir)/.git'; then \
- test -e '$(log_fix)' \
- && amend_git_log="--amend=$(log_fix)" \
- || amend_git_log=; \
- $(gitlog_to_changelog) $$amend_git_log \
- --since=$(changelog_start_date) > '$@T' \
- && rm -f '$@' && mv '$@T' '$@'; \
- fi
-
-# Sort in traditional ASCII order, regardless of the current locale;
-# otherwise we may get into trouble with distinct strings that the
-# current locale considers to be equal.
-ASSORT = LC_ALL=C sort
-
-# Extract all lines up to the first one starting with "##".
-prologue = perl -ne '/^\#\#/ and exit; print' $(no_thanks)
-
-# Generate THANKS using git log entries as far as possible, fixing
-# up ommisions and errors from NO-THANKS configuration.
-$(thanks): FORCE
- $(AM_V_GEN)if test -d '$(srcdir)/.git'; then \
- { \
- $(prologue); echo; \
- { perl -ne '/^$$/.../^$$/ and print' $(no_thanks) \
- | grep -v '^$$' | perl -pe 's/ +/\0/'; \
- { sed -e '1,/\#\# /d' -e '/^\#\# /d' \
- -e 's|[ ][ ]*| |' < $(no_thanks) \
- | tr '\t' '\0'; \
- git log --pretty=format:'%aN%x00%aE'; \
- } | $(ASSORT) -u; \
- } | $(thanks_gen) \
- | LC_ALL=en_US.UTF-8 sort -f; \
- echo; \
- printf ';; %s\n' 'Local Variables:' 'coding: utf-8' End:; \
- } > '$@'; \
- fi
-
-MAINTAINERCLEANFILES += \
- ABOUT-NLS INSTALL Makefile.in aclocal.m4 \
- config-h.in configure stamp-h.in \
- po/cat-id-tbl.c po/m4.pot po/stamp-cat-id
-
-
-## ------- ##
-## GNU M4. ##
-## ------- ##
-
-bin_PROGRAMS = src/m4
-src_m4_SOURCES = \
- src/assure.h \
- src/xstrtoul.c \
- src/xstrtol-error.c \
- src/xstrtol.c \
- src/xstrtol.h \
- src/version-etc-fsf.c \
- src/version-etc.c \
- src/version-etc.h \
- src/main.c \
- src/m4.h \
- src/freeze.c
-if GETOPT
-src_m4_SOURCES += \
- src/getopt.c \
- src/getopt1.c
-endif
-if STACKOVF
-src_m4_SOURCES += src/stackovf.c
-endif
-src_m4_CPPFLAGS = $(AM_CPPFLAGS) -Isrc -I$(srcdir)/src
-src_m4_LDADD = m4/libm4.la $(LTLIBICONV) $(LTLIBTHREAD)
-src_m4_DEPENDENCIES = m4/libm4.la
-
-## ##
-## --- PASTED MANUALLY FROM GNULIB --- ##
-## To avoid adding unnecessary objects to libm4.la these gnulib ##
-## modules are not imported by gnulib-tool, but added manually. ##
-## (from: gnulib-tool --extract-automake-snippet getopt-posix) ##
-## ##
-if GETOPT
-BUILT_SOURCES += src/$(GETOPT_H)
-endif
-EXTRA_DIST += src/getopt.c src/getopt1.c src/getopt.in.h src/getopt_int.h
-
-ARG_NONNULL_H = $(srcdir)/$(config_aux_dir)/arg-nonnull.h
-
-# We need the following in order to create an <getopt.h> when the
-# system doesn't have one that works with the given compiler.
-src/getopt.h: src/getopt.in.h $(ARG_NONNULL_H)
- $(AM_V_GEN)rm -f $@-t $@ && \
- { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \
- sed -e 's|@''HAVE_GETOPT_H''@|$(HAVE_GETOPT_H)|g' \
- -e 's|@''INCLUDE_NEXT''@|$(INCLUDE_NEXT)|g' \
- -e 's|@''PRAGMA_SYSTEM_HEADER''@|@PRAGMA_SYSTEM_HEADER@|g' \
- -e 's|@''NEXT_GETOPT_H''@|$(NEXT_GETOPT_H)|g' \
- -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
- < $(srcdir)/src/getopt.in.h; \
- } > $@-t && \
- mv -f $@-t $@
-MOSTLYCLEANFILES += src/getopt.h src/getopt.h-t
-## ##
-## --- END OF PASTED GNULIB --- ##
-## ##
-
-## -------- ##
-## Modules. ##
-## -------- ##
-
-module_ldflags = -avoid-version -module $(AM_LDFLAGS)
-module_libadd = m4/libm4.la
-
-noinst_HEADERS = modules/m4.h
-
-pkglib_LTLIBRARIES =
-
-pkglib_LTLIBRARIES += modules/gnu.la
-EXTRA_modules_gnu_la_SOURCES = modules/format.c
-modules_gnu_la_LDFLAGS = $(module_ldflags)
-modules_gnu_la_LIBADD = $(module_libadd)
-EXTRA_DIST += $(EXTRA_modules_gnu_la_SOURCES)
-
-pkglib_LTLIBRARIES += modules/m4.la
-EXTRA_modules_m4_la_SOURCES = modules/evalparse.c
-modules_m4_la_LDFLAGS = $(module_ldflags)
-modules_m4_la_LIBADD = $(module_libadd)
-EXTRA_DIST += $(EXTRA_modules_m4_la_SOURCES)
-
-if USE_GMP
-pkglib_LTLIBRARIES += modules/mpeval.la
-EXTRA_modules_mpeval_la_SOURCES = modules/evalparse.c
-modules_mpeval_la_LDFLAGS = $(module_ldflags)
-modules_mpeval_la_LIBADD = $(module_libadd) $(LIBADD_GMP)
-endif
-
-pkglib_LTLIBRARIES += modules/stdlib.la
-modules_stdlib_la_LDFLAGS = $(module_ldflags)
-modules_stdlib_la_LIBADD = $(module_libadd)
-
-pkglib_LTLIBRARIES += modules/time.la
-modules_time_la_LDFLAGS = $(module_ldflags)
-modules_time_la_LIBADD = $(module_libadd)
-
-pkglib_LTLIBRARIES += modules/traditional.la
-modules_traditional_la_LDFLAGS = $(module_ldflags)
-modules_traditional_la_LIBADD = $(module_libadd)
-
-
-## ----- ##
-## libm4 ##
-## ----- ##
-
-lib_LTLIBRARIES += m4/libm4.la
-
-nobase_include_HEADERS = \
- m4/m4module.h \
- m4/hash.h \
- m4/system.h
-m4_libm4_la_SOURCES = \
- m4/builtin.c \
- m4/debug.c \
- m4/hash.c \
- m4/input.c \
- m4/m4.c \
- m4/m4private.h \
- m4/macro.c \
- m4/module.c \
- m4/output.c \
- m4/path.c \
- m4/resyntax.c \
- m4/symtab.c \
- m4/syntax.c \
- m4/utility.c
-m4_libm4_la_LIBADD = m4/gnu/libgnu.la \
- $(LTLIBINTL) $(LIBADD_DLOPEN)
-m4_libm4_la_DEPENDENCIES = m4/gnu/libgnu.la
-
-# This file needs to be regenerated at configure time.
-dist-hook:
- rm -f $(distdir)/m4/system.h
-EXTRA_DIST += m4/system_.h
-
-
-## -------------- ##
-## Documentation. ##
-## -------------- ##
-
-TAGS_FILES = $(infos_TEXINFOS)
-TAGS_DEPENDENCIES = $(TAGS_FILES)
-ETAGS_ARGS = --language=none --regex='/@node \([^,]*\)/\1/' $(TAGS_FILES)
-
-MAINTAINERCLEANFILES += $(dist_man_MANS)
-
-## --------- ##
-## Examples. ##
-## --------- ##
-
-EXTRA_DIST += \
- doc/examples/WWW/Makefile \
- doc/examples/WWW/_footer.htm \
- doc/examples/WWW/_header.htm \
- doc/examples/WWW/m4lib/bugs.m4 \
- doc/examples/WWW/m4lib/changelog.m4 \
- doc/examples/WWW/m4lib/download.m4 \
- doc/examples/WWW/m4lib/features.m4 \
- doc/examples/WWW/m4lib/feedback.m4 \
- doc/examples/WWW/m4lib/html.m4 \
- doc/examples/WWW/m4lib/index.m4 \
- doc/examples/WWW/m4lib/layout.m4 \
- doc/examples/WWW/m4lib/lists.m4 \
- doc/examples/WWW/m4lib/menu.m4 \
- doc/examples/WWW/m4lib/modules.m4 \
- doc/examples/WWW/m4lib/news.m4 \
- doc/examples/WWW/m4lib/readme.m4 \
- doc/examples/WWW/m4lib/setup.m4 \
- doc/examples/WWW/m4lib/test.m4 \
- doc/examples/WWW/m4lib/thanks.m4 \
- doc/examples/WWW/m4lib/thissite.m4 \
- doc/examples/WWW/m4lib/tmpl.m4 \
- doc/examples/WWW/m4lib/todo.m4 \
- doc/examples/WWW/m4lib/uses.m4 \
- doc/examples/WWW/m4lib/visions.m4 \
- doc/examples/WWW/m4lib/whatis.m4
-
-dist_pkgdata_DATA = \
- doc/examples/capitalize.m4 \
- doc/examples/capitalize2.m4 \
- doc/examples/comments.m4 \
- doc/examples/curry.m4 \
- doc/examples/ddivert.m4 \
- doc/examples/debug.m4 \
- doc/examples/esyscmd.m4 \
- doc/examples/exp.m4 \
- doc/examples/foreach.m4 \
- doc/examples/foreach2.m4 \
- doc/examples/foreachq.m4 \
- doc/examples/foreachq2.m4 \
- doc/examples/foreachq3.m4 \
- doc/examples/foreachq4.m4 \
- doc/examples/forloop.m4 \
- doc/examples/forloop2.m4 \
- doc/examples/forloop3.m4 \
- doc/examples/fstab.m4 \
- doc/examples/hanoi.m4 \
- doc/examples/incl-test.m4 \
- doc/examples/incl.m4 \
- doc/examples/include.m4 \
- doc/examples/indir.m4 \
- doc/examples/join.m4 \
- doc/examples/loop.m4 \
- doc/examples/misc.m4 \
- doc/examples/multiquotes.m4 \
- doc/examples/patsubst.m4 \
- doc/examples/pushpop.m4 \
- doc/examples/quote.m4 \
- doc/examples/regexp.m4 \
- doc/examples/reverse.m4 \
- doc/examples/stack.m4 \
- doc/examples/stack_sep.m4 \
- doc/examples/sysv-args.m4 \
- doc/examples/trace.m4 \
- doc/examples/translit.m4 \
- doc/examples/undivert.incl \
- doc/examples/undivert.m4 \
- doc/examples/wrap.m4 \
- doc/examples/wrapfifo.m4 \
- doc/examples/wraplifo.m4 \
- doc/examples/wraplifo2.m4
-
-EXTRA_DIST += \
- doc/examples/modtest.m4 \
- doc/examples/shadow.m4 \
- doc/examples/time.m4 \
- doc/examples/time2.m4 \
- doc/examples/stdlib.m4
-
-## ----------- ##
-## Test suite. ##
-## ----------- ##
-
-# Use `$(srcdir)' for the benefit of non-GNU makes: this is
-# how `testsuite' appears in our dependencies.
-TESTSUITE = $(srcdir)/tests/testsuite
-TESTSUITE_AT = \
- tests/builtins.at \
- tests/freeze.at \
- $(srcdir)/tests/generated.at \
- tests/macros.at \
- tests/modules.at \
- tests/options.at \
- tests/others.at \
- tests/testsuite.at
-
-EXTRA_DIST += $(TESTSUITE) $(TESTSUITE_AT) $(OTHER_FILES) \
- tests/atlocal.in \
- tests/generate.awk \
- $(srcdir)/tests/package.m4
-
-module_check = -rpath /dev/null
-
-check_LTLIBRARIES += tests/import.la
-tests_import_la_LDFLAGS = $(module_ldflags) $(module_check)
-tests_import_la_LIBADD = $(module_libadd)
-
-check_LTLIBRARIES += tests/modtest.la
-tests_modtest_la_LDFLAGS = $(module_ldflags) $(module_check)
-tests_modtest_la_LIBADD = $(module_libadd)
-
-check_LTLIBRARIES += tests/shadow.la
-tests_shadow_la_LDFLAGS = $(module_ldflags) $(module_check)
-tests_shadow_la_LIBADD = $(module_libadd)
-
-# Using variables so that this snippet is not too wide and can
-# be used as is in Texinfo @example/@end example.
-m4_texi = $(srcdir)/doc/m4.texi
-
-generate = $(AWK) -f $(srcdir)/tests/generate.awk
-$(srcdir)/tests/generated.at: tests/generate.awk $(m4_texi)
- $(generate) $(m4_texi) >$@t
- mv $@t $@
-
-AUTOM4TE = $(SHELL) $(srcdir)/$(config_aux_dir)/missing --run autom4te
-AUTOTEST = $(AUTOM4TE) --language=autotest
-$(TESTSUITE): $(srcdir)/tests/package.m4 $(TESTSUITE_AT)
- $(AUTOTEST) -I '$(srcdir)/tests' -o $@.tmp $@.at
- mv $@.tmp $@
-
-# The leading :; works around a bug in {}>f in some bash versions.
-$(srcdir)/tests/package.m4: .version
- :; \
- { \
- echo '# Signature of the current package.'; \
- echo 'm4_define([AT_PACKAGE_NAME], [$(PACKAGE_NAME)])'; \
- echo 'm4_define([AT_PACKAGE_TARNAME], [$(PACKAGE_TARNAME)])'; \
- echo 'm4_define([AT_PACKAGE_VERSION], [$(PACKAGE_VERSION)])'; \
- echo 'm4_define([AT_PACKAGE_STRING], [$(PACKAGE_STRING)])'; \
- echo 'm4_define([AT_PACKAGE_BUGREPORT], [$(PACKAGE_BUGREPORT)])'; \
- } > $(srcdir)/tests/package.m4
-
-tests/atconfig: config.status
- $(SHELL) ./config.status tests/atconfig
-DISTCLEANFILES += tests/atconfig
-
-# Hook the test suite into the check rule
-check-local: tests/atconfig tests/atlocal tests/m4 $(TESTSUITE) \
- $(check_LTLIBRARIES)
- $(SHELL) '$(srcdir)/tests/testsuite' -C tests $(TESTSUITEFLAGS)
-
-# Run the test suite on the *installed* tree, including any renames
-# the user requested.
-installcheck-local: tests/atconfig tests/atlocal $(TESTSUITE) \
- $(check_LTLIBRARIES)
- $(SHELL) '$(srcdir)/tests/testsuite' -C tests \
- AUTOTEST_PATH="$(bindir)" \
- M4="`echo m4 | sed '$(program_transform_name)'`" $(TESTSUITEFLAGS)
-
-# Enough users install GNU M4 as gm4 that we make sure 'make installcheck'
-# will handle that, as part of making a release.
-DISTCHECK_CONFIGURE_FLAGS = \
- --disable-assert \
- --program-prefix=g \
- --enable-cxx
-
-# We need to remove any file droppings left behind by testsuite.
-clean-local-tests:
- test ! -f '$(srcdir)/tests/testsuite' || \
- $(SHELL) '$(srcdir)/tests/testsuite' -C tests --clean
-
-OTHER_FILES = tests/iso8859.m4 tests/stackovf.test \
- tests/null.m4 tests/null.out tests/null.err
-
-DISTCLEANFILES += tests/atconfig tests/atlocal tests/m4
-MAINTAINERCLEANFILES += $(srcdir)/tests/generated.at '$(TESTSUITE)'
-
-clean-local: clean-local-tests
-
-FORCE:
diff --git a/NEWS b/NEWS
deleted file mode 100644
index 8c9b9865..00000000
--- a/NEWS
+++ /dev/null
@@ -1,1228 +0,0 @@
-GNU M4 NEWS - History of user-visible changes. -*- outline -*-
-
-* Noteworthy changes in Version 1.9b (201x-??-??) [beta]
- Released by ????, based on git version 1.9a-*
-
-NOTE - there are still a number of FIXMEs to resolve before this can be
-promoted to 2.0.
-
-** Building M4
-
-*** The build environment has been updated to modern GNU practices,
- depending on newer features of Autoconf, Automake, Libtool, Gettext,
- and Gnulib to be more portable to a wide variety of platforms.
-
-** New command line behavior
-
-*** If the POSIXLY_CORRECT environment variable is set, it implies the
- `-G' and `-Q' options, effectively giving a more fully POSIX-compliant
- implementation with only compatible GNU extensions.
-
-*** New `-b'/`--batch' command-line option to force non-interactive mode.
- Also, in addition to `-e'/`--interactive' requesting interactive mode,
- m4 now follows the lead of sh, and automatically enters interactive
- mode when there are no files specified, and when both standard input
- and standard error are terminals.
-
-*** New `-B'/`--prepend-include' command-line option allows prepending to
- the include path, rather than always searching `.' first.
-
-*** New `--debuglen' command-line option matches the spelling of a new
- macro, and the old spelling `--arglength' now issues a warning that it
- might be withdrawn in the future.
-
-*** The `-g'/`--gnu' command-line option is now required to allow all GNU
- extensions when POSIXLY_CORRECT is set.
-
-*** The `-H'/`--hashsize' command-line options, which were made no-ops in
- a previous beta, now issue a deprecation warning.
-
-*** The `-L'/`--nesting-limit' command-line option now performs argument
- validation and accepts an optional multiplier suffix.
-
-*** New `-p'/`--pushdef' and `--popdef' command-line options allow more
- control over macro definitions from the command line between input
- files.
-
-*** New `--posix' command-line option is a synonym for `-G'/`--traditional'.
-
-*** New `-r'/`--regexp-syntax' command-line option changes the default
- regular expression syntax used by M4. Without this option, M4
- continues to use EMACS style expressions. A new section in the info
- docs explains the differences between them, and what builtins are
- affected.
-
-*** New `--safer' command-line option cripples the potentially unsafe
- builtins `debugfile', `esyscmd', `maketemp', `mkdtemp', `mkstemp', and
- `syscmd'.
-
-*** New `--syncoutput' command-line option matches the builtin added in a
- previous beta, and provides more control over sync line generation
- from the command line between input files. The previous options
- `-s'/`--synclines' remain as aliases for `--syncoutput=1'.
-
-*** New `--traceoff' command-line option, and new spelling `--traceon' for
- `--trace', allow more control over macro tracing from the command line
- between input files.
-
-*** New `--warnings' command-line option re-enables warnings, overriding
- `-Q'/`--quiet'/`--silent', allowing warnings even when POSIXLY_CORRECT.
-
-*** When GNU extensions are enabled, any command line arguments that wauld
- have been interpreted as input file names with previous releases are
- still searched for as before, but will first attempt to be loaded as
- compiled modules before falling back on loading as m4 input. In
- POSIXLY_CORRECT mode, only m4 input files in the current directory can
- be loaded.
-
-** POSIX conformance
-
-*** The `defn' builtin now allows any number of arguments, as POSIX requires.
- - FIXME: This still doesn't work with concatenating builtins with text.
-
- - FIXME: POSIX recommends using ${10} instead of $10 for the tenth
- positional argument. We should deprecate $10.
-
-** Removed builtins
-
-*** The experimental `epatsubst' and `eregexp' builtins have been removed
- in favor of a new `changeresyntax' builtin.
-
-*** The `load' builtin, introduced in previous betas has been removed in
- lieu of richer `include' and `sinclude' functionality.
-
-** New builtins
-
-*** New `changeresyntax' builtin allows programmatic setting of the default
- regular expression flavor, to match `-r'/`--regexp-syntax' command-line
- option.
-
-*** New `debuglen' builtin allows runtime setting of debug output length,
- previously controlled only by the `-l' command line argument.
- Additionally, whether using the new macro or the command line argument,
- the length limitation now affects dumpdef output as well as trace
- output, undergoes argument validation, and accepts an optional
- multiplier suffix.
- - FIXME the multiplier suffix isn't reliable yet
-
-*** New `mkdtemp' builtin parallels `mkstemp', but allows the creation of
- temporary directories instead of files.
-
-*** New `refcount' builtin allows tracking how many times a module has
- been loaded.
- - FIXME: consider making m4modules smarter for this purpose
-
-*** New `renamesyms' builtin allows programmatic renaming of all symbols
- according to a regular expression.
- - FIXME: This feature can cause core dumps when renaming multiple
- symbols to the same name.
-
-*** New `__traditional__' builtin identifies when the traditional module
- is loaded instead of the gnu module.
-
-*** The `modules' and `symbols' builtins, introduced in previous betas,
- have been renamed `m4modules' and `m4symbols', in order to minimize
- problems when upgrading from 1.4.x and processing English text. To
- prevent future problems, any future macro added as a GNU extension will
- either be blind (ie. be unrecognized without arguments), or begin with
- the prefix `m4' or `__'.
-
-** Changed behavior of builtins
-
-*** The module identifier builtins, such as `__gnu__', `__m4_version__',
- and `__unix__', now warn if given arguments.
-
-*** The `builtin' builtin now has a special form, where if the first
- argument is exactly the special token representing defn(`builtin'), the
- expansion is the special token representing the builtin named in the
- second argument. This allows regenerating a macro with a more
- efficient mapping directly to a builtin function, rather than through
- textual indirection through further expansions of `builtin'.
-
-*** The `changesyntax' builtin has been improved, to make it easier to add
- and remove characters from a syntax class without having to specify the
- entire set of characters in that class. It also supports new syntax
- categories, `$', `{' and `}', for extended argument handling in macro
- definitions. See the manual for more examples.
-
-*** New `m' flag to `-d'/`--debug' command-line option or `debugmode'
- builtin traces actions related to module loading and unloading, and
- affects `dumpdef' and trace output to show where builtins come from.
- New `s' flag shows the entire stack of `pushdef' definitions during
- `dumpdef'. The `c' flag has been updated to add information to the
- first line to show the definition of the macro being expanded.
-
-*** The `eval' and `mpeval' builtins now support the following new
- operators: `>>>', `\', and `,'.
-
-*** When GNU extensions are enabled, the `include' and `sinclude' builtins
- continue to search directories one at a time, but will first attempt to
- load arguments as compiled modules and then as m4 input before moving
- to the next directory in the search path. In POSIXLY_CORRECT mode,
- only m4 input in the current directory can be loaded.
-
-*** The `maketemp' builtin now always warns that it is obsolete, even in GNU
- mode where it uses the same secure algorithm as `mkstemp', because of
- the recommendation of POSIX to obsolete `maketemp' as inherently
- insecure when obeying POSIX.
-
-*** The `m4symbols' builtin now warns if given a builtin token instead of
- a macro name. It remains silent for undefined macros.
-
-*** The `patsubst' and `regexp' builtins have a new optional 4th argument
- to use a different regular expression syntax for the duration of that
- invocation.
-
-*** The semantics of the `traceon' and `traceoff' builtins now match
- traditional implementations: when called without arguments, they affect
- global state rather than affecting only the macros defined at that
- moment. The manual includes an example of how to recover 1.4.x
- semantics.
-
-** Other changes
-
-*** The syntax of frozen files format V2 has been improved to save
- additional state. This includes the `R' directive for default regular
- expression syntax, the `t' directive for traced macros, and the `d'
- directive for debug mode. Existing directives with consecutive strings
- now require an intermediate newline, for faster parsing. Also, a V2
- file can now be represented completely in ASCII, thanks to escape
- sequences. Unfortunately, files frozen by M4 1.4q cannot be read by
- 1.9b, but since 1.4q was not widely distributed, this is not expected
- to be much of an issue, and comes with the territory of using a beta
- release.
- - FIXME: format 2 still needs to catch more missing state; once 2.0 is
- released, any further changes would introduce format 3.
-
-*** Improvements made in the 1.4.x and 1.6 stable series have been
- incorporated.
-
-
-* Noteworthy changes in Version 1.6 (????-??-??) [stable]
- Released by ????, based on git versions 1.4.10b.x-* and 1.5.*
-
-** Fix regression introduced in 1.4.4b where using `traceon' could delete
- a macro. This was most noticeable with `traceon(`traceon')', but
- would also happen in cases such as `foo(traceon(`foo'))'.
-
-** Fix regressions introduced in 1.4.10b:
-*** Using `builtin' or `indir' to perform nested `shift' calls triggered
- an assertion failure (not present in 1.4.11).
-*** The command-line option -dV, as well as the builtin `debugmode(V)',
- failed to enable `t' and `c' debug options (not present in 1.4.11).
-*** Comments that contain unbalanced quotes were not rescanned correctly
- when passed through $@ (not present in 1.4.11).
-*** Using `defn' on a traced but undefined macro triggered an assertion
- failure (also present in 1.4.11, but not 1.4.12).
-
-** Remove the undocumented command-line option '-N', as no one complained
- about the assertion failure regression that it introduced in 1.4.7.
-
-** The `-o'/`--error-output' command-line options, which were replaced by
- `--debugfile' in 1.4.7, now issue a deprecation warning. This warning
- harmlessly triggers with versions of Autoconf 2.60 and earlier, but can
- be silenced by applying this patch:
- http://git.sv.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=714eeee87
-
-** Fix the `m4wrap' builtin to accumulate wrapped text in FIFO order, as
- required by POSIX. The manual mentions a way to restore the LIFO order
- present in earlier GNU M4 versions. NOTE: this change exposes a bug
- in Autoconf 2.59 and earlier (which was fixed in Autoconf 2.60).
-
- If you want your package to work with pre-installed Autoconf without
- requiring 2.60, then add these lines to your project's configure.ac,
- prior to calling AC_INIT:
-
- # As long as this project is not ready to upgrade to autoconf 2.60
- # or newer, make sure that newer M4 will still use LIFO order:
- m4_define([m4_wrap], [m4_ifdef([_$0_text],
- [m4_define([_$0_text], [$1]m4_defn([_$0_text]))],
- [m4_define([_$0_text], [$1])m4_builtin([m4wrap],
- [m4_default(m4_defn([_$0_text])m4_undefine([_$0_text]))])])])
-
- On the other hand, if you want to install Autoconf 2.59 or earlier,
- then apply this patch:
- http://git.sv.gnu.org/gitweb/?p=autoconf.git;a=commitdiff;h=56d42fa71
-
-** The `changecom' builtin semantics now match traditional
- implementations; if the start-comment string resembles a macro name or
- the start-quote string, comments are effectively disabled.
-
-** The `divert' builtin now accepts an optional second argument of text
- that is immediately placed in the new diversion, regardless of whether
- the current expansion is nested within argument collection of another
- macro. It has also been optimized for faster performance.
-
-** The `substr' builtin now treats negative arguments as indices relative
- to the end of the string, and accepts an optional fourth argument of
- text to supply in place of the selected substring. The manual gives an
- example of how to recover M4 1.4.x behavior, as well as an example of
- simulating the new negative argument semantics with older M4.
-
-** The `index' builtin now takes an optional third argument as the index
- to begin searching from, with a negative argument relative to the end of
- the string.
-
-** The `-d'/`--debug' command-line option now understands `-' and `+'
- modifiers, the way the builtin `debugmode' has always done; this allows
- `-d-V' to disable prior debug settings from the command line, similar to
- using the builtin `debugmode' without arguments. The option
- `--debugmode' is added as an alias for `-d'. The new flag `d' is added
- to control whether dereferencing an undefined macro causes a warning;
- this flag is enabled by default if neither `-d' nor `-E' are specified.
- The new flag `o' is added to control whether `dumpdef' outputs to stderr
- or the current `debugfile' location. When the command line option is
- given the empty string, the mode is treated as `+adeq' instead of `aeq'.
- Also, the position of `-d' with respect to files on the command line is
- now significant.
-
-** A new predefined text macro, `__m4_version__', expands to the unquoted
- version number of M4, if GNU extensions are enabled. While you should
- generally favor feature tests over version number checks, this macro can
- be used, via `defn', to determine whether the version of m4 processing
- your file is adequate.
-
-** The `defn', `popdef', and `undefine' builtins gained a new warning when
- operating on an undefined macro name, to match the warning already
- present in `builtin', `indir', and `dumpdef'. For backwards
- compatibility, the warning can be disabled by using `debugmode(`-d')'
- (or the command line option `--debug=-d'). The flag is also cleared by
- the command line option `-E'/`--fatal-warnings', so that scripts written
- for 1.4.x do not cause the script to fail because of new warnings.
-
-** Enhance the `indir' builtin to trace indirect macros, where the trace
- is requested via `traceon' or the command-line option `-t'. Previously,
- it was impossible to trace macro names such as `foo-bar' which could
- only be invoked indirectly, without relying on global tracing (such as
- with `debugmode(`t')') or the experimental `changeword'.
-
-** Aspects of tracing output that were previously undocumented have been
- slightly altered, and the effect of the builtin `debugmode' on trace
- output is more fully documented. As POSIX does not specify trace output
- format, parsing such output is inherently fragile in the first place.
- The intent is that future M4 versions will not change documented trace
- output without adding additional `debugmode' flags.
-
-** Enhance the `ifdef', `ifelse', and `shift' builtins, as well as all
- user macros, to transparently handle builtin tokens generated by `defn'.
-
-** Allow the concatenation of builtin macros with arbitrary text in
- several contexts, via the `defn' builtin or argument expansion, rather
- than warning and converting the builtin token to an empty string.
- However, it is still not possible to use a concatenated builtin when
- defining a macro.
-
-** Enhance the `defn', `dumpdef', `ifdef', `popdef', `traceon', `traceoff',
- and `undefine' macros to warn when encountering a builtin token in the
- context of a macro name, rather than acting on the empty string. This
- was already done for `define', `pushdef', `builtin', and `indir'.
-
-** Enhance the `eval' builtin to understand the `?:' operator, and
- downgrade a failed parse due to an unknown operator from an error to a
- warning.
-
-** A number of portability improvements inherited from gnulib.
-
-* Noteworthy changes in release 1.4.18 (2016-12-31) [stable]
-
-** Diagnose --word-regexp as unsupported if it was not configured.
-
-** Preliminary support for OS/2.
-
-** A number of portability improvements inherited from gnulib.
-
-
-* Noteworthy changes in release 1.4.17 (2013-09-17) [stable]
-
-** Fix compilation with newer glibc headers.
-
-** Fix a failure with diverting large amounts of text on mingw (does
- not affect platforms that can rename an open file).
-
-** A number of portability improvements inherited from gnulib.
-
-
-* Noteworthy changes in release 1.4.16 (2011-03-01) [stable]
-
-** Fix regressions in the `index' builtin. On glibc platforms, this
- avoids false positives from a strstr bug in glibc 2.9 through 2.12;
- on many other platforms, it fixes two separate regressions, a false
- positive introduced in 1.4.11 and a false negative in 1.4.15.
-
-** A number of portability improvements inherited from gnulib.
-
-
-* Noteworthy changes in release 1.4.15 (2010-08-31) [stable]
-
-** Fix regression introduced in 1.4.9b where the `format' builtin could
- crash on an invalid format string.
-
-** Fix compilation against newer glibc, and on AIX 7.1BETA.
-
-** A number of portability improvements inherited from gnulib.
-
-* Noteworthy changes in Version 1.4.14 (2010-02-24) [stable]
- Released by Eric Blake, based on git version 1.4.13.*
-
-** Fix regression introduced in 1.4.12 where executing with stdout closed
- could crash m4 on exit on some platforms.
-
-** Fix regressions introduced in 1.4.13 in the `esyscmd' builtin, where
- closed file descriptors could interfere with child execution, and where
- a child status of 127 made m4 print a spurious message to stderr.
-
-** A number of portability improvements inherited from gnulib.
-
-* Noteworthy changes in Version 1.4.13 (2009-04-01) [stable]
- Released by Eric Blake, based on git version 1.4.12.*
-
-** The manual is now distributed under the terms of FDL 1.3.
-
-** The `divert' and `undivert' builtins have been made more efficient
- when using temporary files for large diversions.
-
-** The `translit' builtin has been made more efficient when the second
- argument is short.
-
-** The input engine has been optimized for faster processing.
-
-** The command line option `--debugfile', introduced in 1.4.7, now
- treats its argument as optional, in order to allow setting the debug
- output back to stderr when used without an argument; and order is now
- significant with respect to command line files. You must therefore use
- `m4 --debugfile=trace file', not `m4 file --debugfile trace'. This
- change does not affect the deprecated `-o'/`--error-output' option.
-
-** The `syscmd' and `esyscmd' builtins can be configured to use an
- alternate shell, via the new `configure' option `--with-syscmd-shell'.
-
-** A number of portability improvements inherited from gnulib.
-
-* Noteworthy changes in Version 1.4.12 (2008-10-10) [stable]
- Released by Eric Blake, based on git version 1.4.11.*
-
-** Fix regression introduced in 1.4.4b where using `traceon' could delete
- a macro. This was most noticeable with `traceon(`traceon')', but
- would also happen in cases such as `foo(traceon(`foo'))'.
-
-** Fix regression introduced in 1.4.7 where `m4 -N9' died with an assertion
- failure.
-
-** Fix regression introduced in 1.4.11 where `defn' died with an assertion
- failure on a traced but undefined macro.
-
-** New `-g'/`--gnu' command-line option overrides `-G'/`--traditional'.
- For now, the environment variable POSIXLY_CORRECT has no effect on M4
- behavior; but a future release of M4 will behave as though --traditional
- is implied if POSIXLY_CORRECT is set (this future change is necessary,
- because in the current release, there is no way to disable GNU
- extensions that conflict with POSIX without the use of a non-POSIX
- command-line argument). Clients of M4 that want to use GNU extensions,
- even when POSIXLY_CORRECT is set, should start using the -g command-line
- argument, even though it is currently a no-op if -G did not appear
- earlier in the command line, so that the client will not break in the
- face of an upgraded m4 and a POSIXLY_CORRECT execution environment.
-
-** The `-L'/`--nesting-limit' command-line option now defaults to 0 for
- unlimited on platforms that can detect and deal with stack overflow. On
- systems that lack alternate stack support, such as Cygwin, and on
- systems that do not obey the POSIX semantics for distinguishing stack
- overflow from other exceptions, such as Linux, you can optionally
- install the libsigsegv library (version 2.6 or newer recommended) to
- enhance m4's ability to accurately report stack overflow:
- http://www.gnu.org/software/libsigsegv/
-
-** A number of portability improvements inherited from gnulib.
-
-* Noteworthy changes in Version 1.4.11 (2008-04-02) [stable]
- Released by Eric Blake, based on git version 1.4.10a
-
-** Security fixes for the -F option, for bugs present since -F was
- introduced in 1.3: Avoid core dump with 'm4 -F file -t undefined', and
- avoid arbitrary code execution with certain file names.
-
-** Fix regression introduced in 1.4.9b in the `divert' builtin when more
- than 512 kibibytes are saved in diversions on platforms like NetBSD
- or darwin where fopen(name,"a+") seeks to the end of the file.
-
-** The output of the `maketemp' and `mkstemp' builtins is now quoted if a
- file was created. This is a minor security fix, because it was possible
- (although rather unlikely) that an unquoted string could match an
- existing macro name, such that use of the `mkstemp' output would trigger
- inadvertent macro expansion and operate on the wrong file name.
-
-** Enhance the `defn' builtin to support concatenation of multiple text
- arguments, as required by POSIX. However, at this time, it is not
- possible to concatenate a builtin macro with anything else; a warning is
- now issued if this is attempted, although a future version of M4 may
- lift this restriction to match other implementations.
-
-** Enhance the `format' builtin to parse all C99 floating point numbers,
- even on platforms where strtod(3) is buggy, although the replacement
- function does have the known issue of rounding errors when parsing
- some decimal floating point values. This fixes testsuite failures
- introduced in 1.4.9b.
-
-** Enhance the `index' builtin to guarantee linear behavior, in spite of
- the surprisingly large number of systems with a brain-dead quadratic
- strstr(3).
-
-** A number of portability improvements inherited from gnulib.
-
-* Noteworthy changes in Version 1.4.10b (2008-02-25) [beta]
- Released by Eric Blake, based on git version 1.4.10a
-
-Note that M4 1.4.10b was released prior to 1.4.11, and includes all the
-features of 1.4.11 except for C99 parsing in the `format' builtin. It also
-contains the following beta features that were deemed worth deferring until
-1.6:
-
-** Further enhance the `index' builtin to often achieve sublinear results.
-
-** Enhance the `regexp' and `patsubst' builtins to cache frequently used
- regular expressions, which speeds up typical Autoconf usage.
-
-** Enhance the `format' builtin to warn for more suspicious usages, such as
- missing arguments or problems parsing according to the format string.
-
-** Enhance the `ifelse' and `shift' builtins so that tail-recursive
- algorithms based on `$@' operate in linear, rather than quadratic, time
- and memory.
-
-** A number of portability improvements inherited from gnulib.
-
-* Noteworthy changes in Version 1.4.10 (2007-07-09) [stable]
- Released by Eric Blake, based on CVS version 1.4.9c
-
-** Upgrade from GPL version 2 to GPL version 3 or later.
-
-** A number of portability improvements inherited from gnulib.
-
-** Avoid undefined behavior introduced in 1.4.9b in the `format' builtin
- when handling %c. However, this area of code has never been documented,
- and currently does not match the POSIX behavior of printf(1), so it may
- have further changes in the next version.
-
-* Noteworthy changes in Version 1.4.9b (2007-05-29) [beta]
- Released by Eric Blake, based on CVS version 1.4.9a
-
-** Fix regression introduced in 1.4.9 in the `eval' builtin when performing
- division.
-
-** Fix regression introduced in 1.4.8 in the `-F' option that made it
- impossible to freeze more than 512 kibibytes of diverted text.
-
-** The synclines option `-s' no longer generates sync lines in the middle of
- multiline comments or quoted strings.
-
-** Work around a number of corner-case POSIX compliance bugs in various
- broken stdio libraries. In particular, the `syscmd' builtin behaves
- more predictably when stdin is seekable.
-
-** The `format' builtin now understands formats such as %a, %A, and %'hhd,
- and works around a number of platform printf bugs. Furthermore, the
- sequence format(%*.*d,-1,-1,1) no longer outputs random data. However,
- some non-compliant platforms such as mingw still have known bugs in
- strtod that may cause testsuite failures.
-
-** The testsuite is improved to also run gnulib portability tests for the
- features that M4 imports from gnulib.
-
-* Noteworthy changes in Version 1.4.9 (2007-03-23) [stable]
- Released by Eric Blake, based on CVS version 1.4.8c
-
-** Minor documentation and portability cleanups.
-
-* Noteworthy changes in Version 1.4.8b (2007-02-24) [beta]
- Released by Eric Blake, based on CVS version 1.4.8a
-
-** Fix a regression introduced in 1.4.8 that made m4 unable to process
- files larger than 2GiB on some platforms.
-
-** Fix a regression introduced in 1.4.8 that made m4 dump core when
- invoked as 'm4 -- file'.
-
-** The `eval' builtin now follows C precedence rules. Additionally, the
- short-circuit operators correctly short-circuit division by zero. The
- previously undocumented alias of '=' meaning '==' in eval now triggers a
- deprecation warning, so that a future version of M4 can implement a form
- of variable assignment as an extension.
-
-** The `include' builtin now affects exit status on failure, as required by
- POSIX. Use `sinclude' if you need a successful exit status.
-
-** The `-E'/`--fatal-warnings' command-line option now has two levels. When
- specified only once, warnings affect exit status, but execution
- continues, so that you can see all warnings instead of fixing them one
- at a time. To achieve 1.4.8 behavior, where the first warning
- immediately exits, specify -E twice on the command line.
-
-** A new `--warn-macro-sequence' command-line option allows detection of
- sequences in `define' and `pushdef' definitions that match an optional
- regular expression. The default regular expression is
- `\$\({[^}]*}\|[0-9][0-9]+\)', corresponding to the sequences that might
- not behave correctly when upgrading to the eventual M4 2.0. By default,
- M4 2.0 will follow the POSIX requirement that a macro definition
- containing `$11' must expand to the first argument concatenated with 1,
- rather than the eleventh argument; and will take advantage of the POSIX
- wording that allows implementations to treat `${11}' as the eleventh
- argument instead of literal text. Be aware that Autoconf 2.61 will not
- work with this option enabled with the default regular expression; but
- Autoconf 2.62 will be compatible with this option.
-
-** Improved portability to platforms such as BSD/OS and AIX.
-
-* Noteworthy changes in Version 1.4.8 (2006-11-20) [stable]
- Released by Eric Blake, based on CVS version 1.4.7a
-
-** The `divert' macro and `-H'/`--hashsize' command line option no longer
- cause a core dump when handed extra large values. Also, `divert' now
- uses memory proportional to the number of diversions in use, rather than
- to the maximum diversion number encountered, so that large diversion
- numbers are less likely to exhaust system memory; and is no longer
- limited by the maximum number of file descriptors.
-
-** The `--help' and `--version' command line options now consistently
- override all earlier options. For example, `m4 --debugfile=trace
- --help' now no longer accidentally creates an empty file `trace'.
-
-** The `-L'/`--nesting-limit' command line option can now be set to 0
- to remove the default limit of 1024. However, it is still possible that
- heavily nested input can cause abrupt program termination due to stack
- overflow.
-
-** Problems encountered when writing to standard error, such as with the
- `errprint' macro, now always cause a non-zero exit status.
-
-** Warnings and errors issued during macro expansion are now consistently
- reported at the line where the macro name was detected, rather than
- where the close parenthesis resides. Text wrapped by `m4wrap' now
- remembers the location that was in effect when m4wrap was invoked,
- rather than changing to line 0 and the empty string for a file. The
- macros `__line__' and `__file__' now work correctly even as the last
- token in an included file.
-
-** The `builtin' and `indir' macros now transparently handle builtin
- tokens generated by `defn'.
-
-** When diversions created by the `divert' macro collect enough text that
- M4 must use temporary files, the environment variable $TMPDIR is now
- consulted, and a better effort is made to clean up those files in the
- event of a fatal signal.
-
-** The `mkstemp' builtin is added with the same GNU semantics as `maketemp',
- based on the recommendation of POSIX to deprecate the POSIX semantics of
- `maketemp' as inherently insecure. In GNU mode (no -G supplied on the
- command line), `maketemp' silently retains the secure GNU semantics, but
- a future release of M4 will change this to emit a warning. In
- traditional mode (m4 -G), `maketemp' now uses the POSIX-mandated
- insecure semantics, and issues a warning that you should convert your
- script to use `mkstemp' instead. Additionally, `mkstemp' and `maketemp'
- are now well-defined even if the template argument does not end in six
- `X' characters.
-
-** The manual has been improved, including a new section on a composite
- macro `foreach'.
-
-** The `changecom' and `changequote' macros now treat an empty second
- argument the same as if it were missing, rather than using the empty
- string and making it impossible to end a comment or quote.
-
-** The `translit' macro now operates in linear instead of quadratic time,
- and is now eight-bit clean.
-
-** The `-D', `-U', `-s', and `-t' command line options now take effect
- after any files encountered earlier on the command line, rather than up
- front, as is done in traditional implementations and required by POSIX.
-
-* Noteworthy changes in Version 1.4.7 (2006-09-25) [stable]
- Released by Eric Blake, based on CVS version 1.4.6a
-
-** Fix regression from 1.4.5 in handling a file that ends in a macro
- expansion without arguments instead of a newline.
-
-** The define and pushdef macros now warn when the first argument is not
- a string, rather than silently doing nothing.
-
-** Standard input can now be read more than once, as in 'm4 - file -', and
- is not closed until all wrapped text is handled. This makes a
- difference when stdin is not a regular file, and also fixes bugs when
- using the syscmd or esyscmd macros from wrapped text.
-
-** When standard input is a seekable file, the m4exit, syscmd, and esyscmd
- macros now restore the current position to the next unread byte rather
- than discarding an arbitrary amount of buffered data.
-
-** SysV command-line compatibility is no longer a goal of GNU M4; the
- focus will be instead on POSIX compatibility. This release continues to
- support previous usage, but adds warnings in areas which will allow a
- future version of GNU M4 to use its own extensions without being tied to
- the SysV command line interface.
-
-** The no-op compatibility command line options -B, -N, -S, -T, and
- --diversions may be withdrawn or assigned new meanings in future
- releases, so they now issue a warning if used.
-
-** A new command line option -i replaces the compatibility -e as the
- short spelling of --interactive, for consistency with other GNU tools; a
- warning is issued if the old spelling is used, and it may be assigned
- new meaning in future releases.
-
-** A new command line option --debugfile replaces the options -o and
- --error-output as the preferred spelling. The old options were
- misleading in their names and inconsistent with other GNU tools; they
- are still silently accepted, but no longer documented in --help, and may
- be assigned new meanings in future releases.
-
-* Noteworthy changes in Version 1.4.6 (2006-08-25) [stable]
- Released by Eric Blake, based on CVS version 1.4.5a
-
-** Fix buffer overruns in regexp and patsubst macros when handed a trailing
- backslash in the replacement text, or when handling \n substitutions
- beyond the number of \(\) groups.
-
-** Fix memory leak in regexp, patsubst, and changeword macros.
-
-** The format macro now understands %F, %g, and %G.
-
-** When loading frozen files, m4 now exits with status 63 if version
- mismatch is detected.
-
-** Fix bugs that occurred when invoked with stdout or stderr closed,
- and detect write failures to stdout or to the target of the debugfile
- macro. In particular, the syscmd and esyscmd macros can no longer
- interfere with the debug stream or diversions.
-
-** The m4exit macro now converts values outside the range 0-255 to 1.
-
-** It is now an error if a command-line input file ends in the middle of a
- comment, matching the behavior of mid-string and mid-argument
- collection.
-
-** The dnl macro now warns if end of file is encountered instead of a
- newline.
-
-** The error message when end of file is encountered now uses the file and
- line where the dangling construct started, rather than `NONE:0:'.
-
-** The debugmode and __file__ macros, and the -s/--synclines option, now
- show what directory a file was found in when the -I/--include option or
- M4PATH variable had an effect.
-
-** The changequote and changecom macros now work with 8-bit characters, and
- quotes and comments that begin with `(' are properly recognized
- following a word.
-
-** The new macro __program__ is added, which allows the input file to issue
- an error message that resembles messages from m4. Warning and error
- messages have been reformatted to comply with GNU Coding Standards.
-
-** The errprint, m4wrap, and shift macros are now recognized only with
- arguments.
-
-** The index, substr, translit, regexp, and patsubst macros now produce
- output when given only one argument, but still warn about a missing
- second argument.
-
-** The patsubst macro now reliably finds zero-length matches at the end
- of a string.
-
-* Noteworthy changes in Version 1.4.5 (2006-07-15) [stable]
- Released by Eric Blake, based on CVS version 1.4.4c
-
-** Fix sysval on BeOS, OS/2, and other systems that store exit status
- in the low-order byte. Additionally, on Unix platforms, if syscmd was
- terminated by a signal, sysval now displays the signal number shifted
- left by eight bits, to match traditional m4 implementations.
-
-** The maketemp macro is no longer subject to platform limitations (such as
- 26 or 32 max files from a given template).
-
-** Frozen files now require that the first directive be V (version), to
- better diagnose version mismatch. Additionally, if the F directive
- (builtin function) names an unknown builtin that existed in the m4 that
- froze the file but not in the current m4 (for example, changeword), the
- warning is deferred until an attempt is made to actually use the
- builtin. This allows downgrading from beta m4-1.4o to stable m4-1.4.5
- without breaking autoconf.
-
-** The format and indir macros are now recognized only with arguments.
-
-** The eval macro no longer crashes on x86 architectures when dividing the
- minimum integer by -1.
-
-** On systems with ecvt and fcvt, format no longer truncates trailing
- zeroes on integers printed with %.0f. On systems without these
- functions, format is no longer subject to a buffer overflow that
- permitted arbitrary code execution.
-
-** On native Windows builds, the macro __windows__ is provided instead of
- __unix__. Likewise, on OS/2 builds, the macro __os2__ is provided.
- This allows input files to determine when syscmd might behave
- differently.
-
-** Fix bug in 1.4.3 patch to use \n line-endings that did not work for
- cygwin.
-
-** When given the empty string or 0, undivert is now documented as a no-op
- rather than closing stdout, warning about a non-existent file, or trying
- to read a directory as a file.
-
-** Many documentation improvements. Also, the manual is now distributed
- under FDL 1.2, rather than a stricter verbatim-only license.
-
-** Raise the -L (--nesting-limit) command line option limit from 250 to
- 1024.
-
-** The decr, incr, divert, m4exit, and substr macros treat an empty number
- as 0, issue a warning, and expand as normal; rather than issuing an
- error and expanding to the empty string.
-
-** The eval macro now treats an empty radix argument as 10, handles radix 1,
- and treats the width argument as number of digits excluding the sign,
- for compatibility with other m4 implementations.
-
-** The ifdef, divert, m4exit, substr, and translit macros now correctly
- ignore extra arguments.
-
-** The popdef and undefine macros now correctly accept multiple arguments.
-
-** Although changeword is on its last leg, if enabled, it now reverts to the
- default (faster) regexp when passed the empty string.
-
-** The regexp and substr macros now warn and ignore a trailing backslash in
- the replacement, and warn on \n for n larger than the number of
- sub-expressions in the regexp.
-
-* Noteworthy changes in Version 1.4.4b (2006-06-17) [beta]
- Released by Eric Blake, based on CVS version 1.4.4a
-
-** Fix a recursive push_string crashing bug, which affected changequote of
- three or more characters on some compilers.
-
-** Use automake to fix build portability issues.
-
-** Fix a recursive m4wrap crashing bug.
-
-** Fix a 1 in 2**32 hash crashing bug.
-
-** Tracing a macro by name is now persistent, even if the macro is
- subsequently undefined or redefined. The traceon and traceoff macros no
- longer warn about undefined symbols. This solves a crash when using
- indir on an undefined macro traced with the -t option, as well as an
- incorrect result of ifdef. Furthermore, tracing is no longer
- transferred with builtins, solving the bug of "m4 -tm4_eval" failing to
- give trace output on the input
- "define(`m4_eval',defn(`eval'))m4_eval(1)".
-
-** Fix a crash when a macro is undefined while collecting its arguments, by
- always using the definition that was in effect before argument
- collection. This behavior matches the C pre-processor, and means that
- the sequence "define(`f',`1')f(define(`f',`2'))f" is now documented to
- result in "12", rather than the previously undocumented "22".
-
-** Update the regex engine to fix several bugs.
-
-** Fix a potential crash on machines where char is signed.
-
-* Noteworthy changes in Version 1.4.4 (Oct 2005) [stable]
- Released by Gary V. Vaughan
-
-** ./configure --infodir=/usr/share/info now works correctly.
-
-** When any file named on the command line is missing exit with status 1.
-
-* Noteworthy changes in Version 1.4.3 (Mar 2005) [stable]
- Released by Gary V. Vaughan
-
-** DESTDIR installs now work correctly.
-
-** Don't segfault with uncompilable regexps to changeword().
-
-** Always use \n line-endings for frozen files (fixes a Windows bug).
-
-** Portability fix for systems lacking mkstemp(3).
-
-** Approximately 20% speed up in the common case of usage with autoconf.
-
-** Supported on QNX 6.3.
-
-* Noteworthy changes in Version 1.4.2 (Aug 2004) [stable]
- Released by Paul Eggert
-
-** No user visible changes; portability bug fixes only.
-
-* Noteworthy changes in Version 1.4.1 (Jun 2004) [stable]
- Released by Paul Eggert
-
-** The 1.4.x series is intended to be stable; features added in 1.4[a-q]
- were not backported to 1.4.x unless specifically mentioned above.
-
-** maketemp now creates an empty file with the given name, instead of merely
- returning the name of a nonexistent file. This closes a security hole.
-
-
-* Version beta 1.4q - August 2001, by Gary V. Vaughan
-
-** Support for the experimental `changeword' has been dropped.
-
-** `m4 --hashsize' and `-H' are still accepted, but have no effect. M4
- will grow its internal symbol table if the symbol density is having an
- effect on performance.
-
-** `configure --without-modules' will build an m4 binary with no preloaded
- modules. At startup it will search for and load modules `m4' and either
- `gnu' or `traditional'. This mode of operation can be used for
- development and debugging of the base modules without the need to
- recompile all of m4 with each modification.
-
-** `configure --with-modules="gnu m4 traditional load"', for example,
- will build an m4 binary with the named modules preloaded, ready to be
- activated (even on static lib only machines) with the `-m' option or
- using the `load' builtin.
-
-** M4 has no builtins or macros in core, they are all loaded from modules
- at startup. This means that modules are no longer optional, though the
- standard build will statically link the modules `m4', `gnu' and
- `traditional', so even on machines with no ltdl support, all of the
- functionality from previous releases is available.
-
-** New builtin `load' to dynamically load modules which can define new
- builtins and user macros.
-
-** New builtin `unload' to remove loaded modules (and the builtins and user
- macros they define) from the running m4 interpreter.
-
-** New builtins `eregexp' and `epatsubst' to use Extended Regular
- Expressions syntax in lieu of Basic Regular Expressions as used by
- `regexp' and `patsubst'.
-
-** The names of all currently loaded modules are returned by the new
- builtin, ``modules''.
-
-** Loadable modules can define new builtin functions or text expansion
- macros.
-
-** The module code has been rewritten to use libltdl, the libtool dynamic
- loader, which means GNU m4 can now load (and unload) modules just about
- anywhere which it can be built. This includes obscure hosts such as
- cygwin and BeOS, and also on hosts which do not have shared libraries,
- through preloading (see libtool manual) and GNU dld.
-
-** Modules can now be built without the m4 source being available using the
- installed m4module.h header file (and some other headers that it
- includes for you), and the installed libm4.la libtool library. All
- symbols exported from libm4.la have a prefix of `m4_' or `M4_'. See the
- modules directory for examples of usage.
-
-** A new V2 format for frozen files that saves module and syntax information.
-
-* Version beta 1.4o - January 2000, by Rene' Seindal
-
-** Modules can be loaded from the command line with --load-module
-
-** Modules now use libtool's wrapper libltdl.
-
-** New builtin `symbols' allows dynamic queries of all currently defined
- macros.
-
-** Various Bug fixes.
-
-* Version beta 1.4n - November 1998, by Rene' Seindal
-
-** The module code has been reorganised yet again, and now compiles
- correctly on GNU/Linux, HPUX 9 and 10, SunOS 5 and Solaris 5.
-
-** When configured --with-gmp a new builtin `mpeval' is now defined. The
- builtin `eval' retains its normal behaviour.
-
-** m4 --version also shows which options were used for compilation, such as:
- "GNU m4 1.4n (options: modules gmp changeword)"
-
-** New option --import-environment defines all environment variables as
- macros. This is done before -D and -U are handled, so the macros can be
- changed through these options.
-
-** Error messages now always print program name before input file name as
- specified by GNU coding standards. Reported by Akim Demaille.
-
-** Bug fixed: "undivert(0)" could cause m4 to read standard output. A call
- of "undivert(0)" is now silently ignored.
-
-** Bug fixed: when compiling --with-included-gettext, <libintl.h> wasn't
- found in intl/ directory. Reported by Andrew Bettison.
-
-* Version beta 1.4m - November 1998, by Rene' Seindal
-
-** Using libtool for compiling modules and for linking main app.
-
-** Reorganised the dynamic module code to encapsulate system dependencies
- better. The code for HPUX shl_load() still needs testing and debugging.
- A dld interface is also missing. Any volunteers?
-
-** The files from the GNU m4 web-site is now in examples/WWW as a more
- complete example of what GNU m4 can do.
-
-* Version beta 1.4l - November 1998, by Rene' Seindal
-
-** GNU m4 now has an escape syntax category. If a character is marked as
- an escape, words are only recognised as macros if preceded by an escape
- character. It is a bit like -P, but dynamic: it can be turned on and
- off. The GNU m4 web-site on http://www.seindal.dk/rene/gnu/ is
- maintained with this feature - the m4 source is available on the site.
-
-** The module interface is improved, thanks to "Brian J. Fox",
- who has contributed some code from Meta-HTML. The modules now build
- automatically and installs properly, by default in
- /usr/local/libexec/m4. There is a preliminary, untested support for
- shl_load().
-
-** There is now a __m4_version__ macro that expands to the current version
- number.
-
-* Version beta 1.4k - November 1998, by Erick Branderhorst and Rene' Seindal
-
-** GNU m4 now uses gettext to support internationalization.
-
-** GNU m4 now uses automake to control Makefile.in generation. This
- should make it more consistent with the GNU standards.
-
-** GNU m4 will use the gmp library for multiple precision integral and
- rational arithmetic in `eval' if configured with `--with-gmp'. If
- configured without `--with-gmp' or if gmp is not available, and the type
- `long long int' is, GNU m4 will use that for `eval' arithmetic.
-
-** GNU m4 now parses the input according to a syntax table, that can be
- modified through the new builtin `changesyntax'. It is a generalisation
- of the existing builtins `changecom' and `changequote'. The changes are
- completely backwards compatible (except for the existence of
- `changesyntax').
-
-** Sync lines can be turned on and off with the `syncoutput' builtin. The
- builtin `syncoutput' is a GNU extension.
-
-** New experimental feature: dynamically loadable modules. New builtin
- `loadmodules' loads shared libraries, that can define new builtin
- macros, ie, new macros can be written in C. Depends on the dlopen()
- interface, and is currently only tested on Linux. Enabled at configure
- time with `--with-modules'. Documentation is in src/module.c and
- module/README.
-
-** Implement a GNU message catalog for French (Franc,ois Pinard).
-
-** Filenames found through path searches are now correctly reflected in
- error and debug messages and through the `__file__' macro.
-
-** Bugs fixed:
-
-*** All 8-bit characters can now be used for quotes.
-
-* Version 1.4 - October 1994, by Franc,ois Pinard
-
-** (No user visible changes)
-
-* Version 1.3 - September 1994, by Franc,ois Pinard
-
-** Diversions are created as needed. Option `-N' is still accepted, but
- otherwise ignored. Users should use only negative diversion numbers,
- instead of high positive numbers, for diverting to nowhere.
-
-** Diversions should also work faster. No temporary files will be needed
- at all if all diversions taken altogether do not use more than 512K.
-
-** Frozen state files may be produced with the `--freeze-state' (-F)
- option and later brought back through the `--reload-state' (-R) option.
-
-* Version 1.2 - July 1994, by Franc,ois Pinard
-
-** In patsubst(STRING, REGEXP, REPLACEMENT), \& in REPLACEMENT has been
- changed to represent this part of STRING matched by the whole REGEXP,
- instead of the whole STRING as before. \0 does the same, but emits a
- diagnostic saying it will disappear in some subsequent release.
-
-** eval(EXPR) emits a diagnostic if EXPR has suffixed crumb. The same for
- other numeric conversions in incr(), decr(), divert(), etc.
-
-** `--fatal-warnings' (-E) stops execution at first warning.
-
-** `--nesting-limit=LEVEL' (-L LEVEL) sets a limit to macro nesting.
- It is initially fixed at 250.
-
-** `--word-regexp=REGEXP' (-W REGEXP) modifies macro name syntax, like
- does the new `changeword(REGEXP)' macro. This feature is experimental,
- tell me your opinions about it. You do need --enable-changeword at
- configure time to get these things. Do *not* depend on them yet.
-
-** Trace output format is scannable by GNU Emacs' next-error function.
-
-** Stack overflow is detected and diagnosed on some capable systems.
-
-** Various bugs have been corrected, m4 should be more portable. See the
- ChangeLog for details.
-
-* Version 1.1 - November 1993, by Franc,ois Pinard
-
-** Changes which might affect existing GNU m4 scripts:
-
-*** Option `-V' has been removed, use `--version' instead. `--version'
- writes on standard output instead of standard error, and inhibits any
- script execution.
-
-*** `--no-gnu-extensions' has been renamed `--traditional'.
-
-*** In `eval', `^' used to indicate exponentiation, use `**' instead.
-
-*** The automatic undiversion which takes place at end of all input is
- forced into the main output stream.
-
-** Changes which are unlikely to affect existing scripts:
-
-*** `--help' prints an usage summary on standard output. Script execution
- is then inhibited.
-
-*** `--prefix-builtins' (-P) prefixes all builtin macros by `m4_'.
-
-*** Most builtin macros for which arguments are mandatory, called without
- any arguments, are no more recognized as builtin macros: they are
- consequently copied verbatim to the output stream.
-
-*** `define' and `pushdef' are usable with only one argument, they give
- this argument an empty definition.
-
-*** `eval' new operators for binary representation handling: `^' for
- exclusive-or, `~' for the bitwise negation, `<<' and `>>' for shifts.
-
-*** `eval' recognizes the notation 0bDIGITS for binary numbers and the
- notation 0rRADIX:DIGITS for numbers in any radix from 1 to 36.
-
-* Version 1.0.3 - December 1992, by Franc,ois Pinard
-
-** Changes for the user:
-
-*** `dnl' outputs a diagnostic if immediately followed by `('. Usually,
- `dnl' is followed by newline or whitespace.
-
-*** `ifelse' accepts without complaining the common idiom of having only
- one argument. This is useful for introducing long comments.
-
-*** `eval' always expresses values as signed, whatever the radix.
-
-*** M4OPTS environment variable is no longer obeyed.
-
-*** `--no-warnings' option is renamed `--silent'.
-
-*** Debug lines use a new format more compatible with GNU standards.
-
-*** Various bugs have been corrected. See the ChangeLog for details.
-
-** Changes for the installer:
-
-*** GNU m4 now uses an Autoconf-generated configure script, and should be
- more easily portable in many ways. (Cray is not supported yet).
-
-*** `make check' has been made more portable, expect no errors.
-
-** Changes for the programmer:
-
-*** Sources have been fully reindented to comply with GNU standards, and
- cleaned up in many ways.
-
-*** Sources have been protoized. Non-ANSI compilers are automatically
- detected, then sources are unprotoized on the fly before compilation.
-
-*** GNU m4 uses newer versions of obstack, regex, getopt, etc.
-
-* Version 1.0 - October 1991, by Rene' Seindal
-
-** Uses GNU configure, taken from the gdb distribution.
-
-** Uses GNU getopt(), with long option names.
-
-** The -Q/+quiet option is added, which suppresses warnings about missing
- or superflous arguments to builtin macros.
-
-** Added default options via the M4OPTS environment variable.
-
-** Several minor bugs have been fixed.
-
-* Version 0.99 - July 1991, by Rene' Seindal
-
-** The builtins `incr' and `decr' are now implemented without use of
- `eval'.
-
-** The builtin `indir' is added, to allow for indirect macro calls
- (allows use of "illegal" macro names).
-
-** The debugging and tracing facilities has been enhanced considerably.
- See the manual for details.
-
-** The -tMACRO option is added, marks MACRO for tracing as soon as it
- is defined.
-
-** Builtins are traced after renaming iff they were before.
-
-** Named files can now be undiverted.
-
-** The -Nnum option can be used to increase the number of divertions
- available.
-
-** Calling changecom without arguments now disables all comment handling.
-
-** A bug in `dnl' is fixed.
-
-** A bug in the multi-character quoting code is fixed.
-
-** Several typos in the manual has been corrected. More probably persist.
-
-* Version 0.75 - November 1990, by Rene' Seindal
-
-** Implemented search path for include files (-I option and M4PATH
- environment variable).
-
-** Implemented builtin `format' for printf-like formatting.
-
-** Implemented builtin `regexp' for searching for regular expressions.
-
-** Implemented builtin `patsubst' for substitution with regular
- expressions.
-
-** Implemented builtin `esyscmd', which expands to a shell commands output.
-
-** Implemented `__file__' and `__line__' for use in error messages.
-
-** Implemented character ranges in `translit'.
-
-** Implemented control over debugging output.
-
-** Implemented multi-character quotes.
-
-** Implemented multi-character comment delimiters.
-
-** Changed predefined macro `gnu' to `__gnu__'.
-
-** Changed predefined macro `unix' to `__unix__', when the -G option is
- not used. With -G, `unix' is still defined.
-
-** Added program name to error messages.
-
-** Fixed two missing null bytes bugs.
-
-* Version 0.50 - January 1990, by Rene' Seindal
-
-* Initial beta release.
-
-========================================================================
-
-Local Variables:
-fill-column: 75
-End:
-
-Copyright (C) 1992-1994, 2004-2011, 2013-2014, 2017 Free Software
-Foundation, Inc.
-
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
-Texts. A copy of the license is included in the ``GNU Free
-Documentation License'' file as part of this distribution.
diff --git a/NO-THANKS b/NO-THANKS
deleted file mode 100644
index 87d631e6..00000000
--- a/NO-THANKS
+++ /dev/null
@@ -1,186 +0,0 @@
-These people have contributed to GNU M4. Some have reported problems,
-others have contributed improvements to the documentation and actual code.
-The particular contributions are described in the version control logs and
-ChangeLog files. If your name has been left out, if you'd rather not be
-listed, or if you'd prefer a different address be used, please send a
-note to the bug-report mailing list (as seen at end of e.g., m4 --help).
-##
-## There is no need to list here any name that appears as an Author in
-## "git log" output. Those are automatically added when this template
-## is used to generate the THANKS file. You will still need to add
-## contributors who are not a git log Author - e.g. bug reporters.
-##
-## Folks already promoted to AUTHORS:
-##
-!Akim Demaille
-!Alexandre Duret-Lutz
-!Andrew James Bettison
-!David Warme
-!Eric Benjamin Blake
-!François Pinard
-!Gary V. Vaughan
-!James L. Avera
-!Joel E. Denny
-!John Brzustowski
-!John Gatewood Ham
-!John Gerard Makecki
-!Markus Duft
-!Michael Elizabeth Chastain
-!Noah Jeffrey Misch
-!Pete Chown
-!Ralf Wildenhues
-!Raphael Poss
-!René Seindal
-!Thomas Tanner
-!Tim Rice
-!William C. Cox
-!Yuji Minejima
-##
-## Remove duplicates under alternate names, and add preferred email
-## addresses from contributors that don't match git log output here:
-##
-!Andrew Bettison
-!Eric Blake
-!Francois Pinard
-!Noah Misch
-!Rene' Seindal
-##
-## Add bug reporters, patch Authors you forgot to attribute at commit
-## time with 'git commit --author=...' and other non-patch contributers
-## below:
-##
-Akiko Matsushita matusita@sra.co.jp
-Alan Magnuson awm@osc.edu
-Albert Chin m4-discuss@mlists.thewrittenword.com
-Alexander Lehmann alex@hal.rhein-main.de
-Amos Shapira amoss@cs.huji.ac.il
-Andreas BĂ¼ning andreas.buening@nexgo.de
-Andreas Gustafsson gson@niksula.hut.fi
-Andreas Schultz aschultz@warp10.net
-Andreas Schwab schwab@ls5.informatik.uni-dortmund.de
-Andrew Athan athan@morgan.com
-Assar Westerlund assar@nada.kth.se
-Ben A. Mesander ben@piglet.cr.usgs.gov
-Ben Elliston bje@cygnus.com
-Bengt Mertensson bengt@mathematik.uni-bremen.de
-Bernhard Daeubler daeb@physik.uni-ulm.de
-Bill Bumgarner bbum@thoughtport.com
-Bjorn R. Bjornsson brb@falcon.is
-Bob Badour bob@badour.net
-Bob Proulx bob@proulx.com
-Brendan Kehoe brendan@cygnus.com
-Brian J. Fox bfox@datawave.net
-Brian D. Carlstrom bdc@clark.lcs.mit.edu
-Cesar Strauss cestrauss@gmail.com
-Charles Wilson cygwin@cwilson.fastmail.fm
-Chris McGuire chris@wso.net
-Chris Penev xpenev@gmail.com
-Damian Menscher menscher@uiuc.edu
-Dan Jacobson jidanni@jidanni.org
-Daniel Richard G. skunk@iskunk.org
-David J. MacKenzie djm@uunet.uu.net
-David Perlin davep@nanosoft.com
-Elbert Pol elbert.pol@gmail.com
-Elias Benali elptr@users.sourceforge.net
-Erez Zadok ezk@cs.columbia.edu
-Eric Allman eric@cs.berkeley.edu
-Eric Backus ericb@lsid.hp.com
-Eric Fischer enf1@ellis.uchicago.edu
-Erick Branderhorst Erick.Branderhorst@asml.nl
-Fernando Carrijo fcarrijo1980@gmail.com
-Frank Schwidom schwidom@impernet.de
-Gary Affonso Gary_Affonso@iqinc.com
-Geoff Russell grussell@guest.adelaide.edu.au
-Giovanni Toffetti toffettg@lu.unisi.ch
-Greg A. Woods woods@web.apc.org
-Greg McGary gkm@cstone.net
-Hal Peterson hrp@pecan.cray.com
-Hoang Uong hoang@ornews.intel.com
-Hongjiu Lu hjl@nynexst.com
-Ian Taylor ian@cygnus.com
-Ilya N. Golubev gin@mo.msk.ru
-Jan Djarv Jan.Djarv@sa.erisoft.se
-Jason Merrill jason@jarthur.claremont.edu
-Jay Krell jay.krell@cornell.edu
-Jean-Charles Longuet jclonguet@free.fr
-Jens Rehsack rehsack@googlemail.com
-Jim Avera jima@netcom.com
-Jim Kingdom kingdon@cygnus.com
-Jim Meyering meyering@acm.org
-Joel Sherrill jsherril@uahcs2.cs.uah.edu
-John David Anglin dave@hiauly1.hia.nrc.ca
-Josef T. Burger bolo@bolo.com
-Joseph E. Sacco jsacco@ssl.com
-Joseph S. Myers jsm28@cam.ac.uk
-Joshua R. Poulson jrp@plaza.ds.adp.com
-Karl Berry karl@freefriends.org
-Karl Nelson nelson85@llnl.gov
-Karl Vogel vogelke@c-17igp.wpafb.af.mil
-Kaveh R. Ghazi ghazi@noc.rutgers.edu
-Keith Bostic bostic@abyssinian.sleepycat.com
-Konrad Schwarz konrad.schwarz@siemens.com
-Kristine Lund lund@lpnaxp.in2p3.fr
-Krste Asanovic krste@icsi.berkeley.edu
-Lawson Chan Lawson.Chan@tdsecurities.com
-M. Levinson levinsm@users.sourceforge.net
-Marcus Daniels marcus@ee.pdx.edu
-Marion Hakanson hakanson@cse.ogi.edu
-Mark Seiden mis@seiden.com
-Martin Koeppe mkoeppe@gmx.de
-Massimo Dal Zotto dz@cs.unitn.it
-Matt Kraai kraai@debian.org
-Matthew Woehlke mw_triad@users.sourceforge.net
-Matthias Rabe rabe@mathematik.uni-bielefeld.de
-Mehul Sanghvi mehul.sanghvi@gmail.com
-Michael Fetterman mafetter@ichips.intel.com
-Michael L. Welcome welcome@bigbird.llnl.gov
-Mike Andrews kramer@fragile.termfrost.org
-Mike Dupont jamesmikedupont@googlemail.com
-Mike Frysinger vapier@gentoo.org
-Mike Howard mike@clove.com
-Mike Lijewski lijewski@theory.tc.cornell.edu
-Mike R. mroberge@aol.com
-Mike Stump mikestump@comcast.net
-Mikhail Teterin Mikhail.Teterin@murex.com
-Nelson H. F. Beebe beebe@math.utah.edu
-Nick S. Kanakakorn skanan@otl.scu.edu
-Nicolas Lichtmaier nick@technisys.com.ar
-Nicolas Pioch pioch@inf.enst.fr
-Noah Friedman friedman@gnu.org
-Per Bothner per@bothner.com
-Pierre Gaumond gaumondp@ere.umontreal.ca
-Pierre Mathieu mathieu@geod.emr.ca
-Rafael Corvalan rafael@club-internet.fr
-Rainer Tammer tammer@tammer.net
-Richard A Nelson cowboy@vnet.ibm.com
-Richard Ling richard@research.canon.oz.au
-Richard Stallman rms@gnu.org
-Robert Bernstein rocky@panix.com
-Robert Bihlmeyer robbe@orcus.priv.at
-Roderick Koehle Roderick.Koehle@infineon.com
-Roland H. Pesch roland@wrs.com
-Roland McGrath roland@gnu.org
-Ronny Peine RonnyPeine@gmx.de
-Sami Liedes sliedes@cc.hut.fi
-Santiago Vila sanvila@debian.org
-Scott Bartram deneb!scottb
-Sergey Poznyakoff gray@gnu.org.ua
-Simon Leinen simon@lia.di.epfl.ch
-Skip Montanaro skip@automatrix.com
-Stephen Perkins perkins@cps.msu.edu
-Steve Williamson willy@uinpla.npl.uiuc.edu
-Steven Augart saugart@yahoo.com
-Terry Jones terry@cliffs.ucsd.edu
-Thomas Klausner tk@giga.or.at
-Thorsten Ohl ohl@physics.harvard.edu
-Todd Rinaldo toddr@cpanel.net
-Tom G. Christensen tgc@jupiterrise.com
-Tom McConnell tmcconne@sedona.intel.com
-Tom Quinn trq@dionysos.thphys.ox.ac.uk
-Tom Tromey tromey@cns.caltech.edu
-Ulrich Drepper drepper@gnu.org
-Vern Paxson vern@ee.lbl.gov
-Vic Abell abe@cc.purdue.edu
-Vincent Lonngren Vincent.lonngren.759@student.lu.se
-Vivek P. Singhal singhal@cs.utexas.edu
-Walter Wong wcw+@cmu.edu
diff --git a/README b/README
index 69255a21..f228134e 100644
--- a/README
+++ b/README
@@ -9,92 +9,20 @@ GNU `m4' was originally written by Rene' Seindal, from Denmark.
GNU `m4' has a web site at http://www.gnu.org/software/m4/.
-If GNU `m4' is meant to serve GNU `autoconf', beware that `m4'
-should be fully installed *prior to* configuring `autoconf' itself.
-Likewise, if you intend on hacking GNU `m4' from git, the bootstrap
-process requires that you first install a released copy of GNU `m4'.
-
-If you are just trying to build `m4' from a released tarball, you
-should not normally need to run `./bootstrap' or `autoreconf'; just go
-ahead and start with `./configure'. If you are trying to build `m4'
-from git, more information can be found in the version-control-only
-file HACKING.
-
-In the subdirectories `tests' and `doc/examples' you will find various
-m4 files, ranging from trivial test files to rather advanced macros. If
-you intend to use m4 seriously, you might find useful material down
-there.
-
-See file `COPYING' for copying conditions. Note that M4 is distributed
-under the GNU Public License version 3 or later. Some files in the
-distribution are copied from the gnulib project, and hence bear the
-designation version 2 or later because they are unmodified from gnulib;
-however, if you modify these files using M4 rather than gnulib as the
-source, you must update the license to be GPLv3 or later.
-See file `INSTALL' for compilation and installation instructions.
-See file `ABOUT-NLS' for how to customize this program to your language.
-See file `NEWS' for a list of major changes in the current release.
-See file `AUTHORS' for the names of maintainers.
-See file `THANKS' for a list of contributors.
-
-By using `./configure --with-gmp, you get multiple precision integral
-and rational arithmetic using mpeval. The implementation depends on the
-GNU gmp v2 library.
-
-By using `./configure --with-modules=`foo bar baz', you get an m4 with only
-the named modules preloaded. The default modules (preloaded if you do not
-use this option) are sufficient to do the job of GNU m4-1.4. Additional
-modules may be desirable, or necessary if libltdl does not support your
-host architecture. The implementation uses libltdl interface, details of
-which are in the libtool manual. See file `modules/README' for a more
-detailed description.
-
-By default, the `syscmd' and `esyscmd' macros try to use the first
-instance of `sh' found by `command -p getconf PATH' at configure time,
-with a default of `/bin/sh'. If that default is inappropriate, you
-can use `./configure --with-syscmd-shell=location' to specify the
-shell to use.
-
-By using `./configure --with-dmalloc', GNU m4 is linked with Gray
-Watson's dmalloc package. It is a debugging option for finding memory
-management problems. Gray Watson's dmalloc package is available at
-ftp://ftp.letters.com/src/dmalloc/dmalloc.tar.gz.
-
-GNU M4 uses GNU Libtool in order to build shared libraries on a
-variety of systems. While this is very nice for making usable
-binaries, it can be a pain when trying to debug a program. For that
-reason, compilation of shared libraries can be turned off by
-specifying the `--disable-shared' option to `configure'. However,
-without shared libraries, modules that are not preloaded will not be
-available for use.
-
-Send bug reports, comments or ideas to `bug-m4@gnu.org'. A bug report
-is an adequate description of the problem: your input, what you
-expected, what you got, and why this is wrong. Diffs are welcome, but
-they only describe a solution, from which the problem might be uneasy to
-infer. Don't forget all relevant information about your operating
-system, compiler, libraries, ...
-
-The easiest way to remember this information is by using the
-testsuite. Any test failures are automatically logged, along with
-lots of useful information about your setup; simply mailing
-tests/testsuite.log to `bug-m4@gnu.org' is a good start. If you want
-to dive in and debug a failure, you may find it useful to fine-tune
-the execution of the testsuite. For example, running test 12 in
-verbose mode can be done with:
-
-make check TESTSUITEFLAGS='-v -d -x 12'
-
-The testsuite understands --help to tell you more about the current
-set of tests.
+This repository has several branches. The one you have checked out
+does not have any code. Instead, you will want to check out one of:
+- branch-1.4: Latest stable release, most up-to-date
+- branch-1.6: Some improvements to 1.4, but not yet finalized and released
+- branch-2.0: Many new experimental features, hasn't been worked on in years
For any copyright year range specified as YYYY-ZZZZ in this package
-note that the range specifies every single year in that closed interval.
+note that the range includes years in that closed interval; a more
+precise determination of copyrightable changes can be obtained from
+inspecting version control logs.
========================================================================
-Copyright (C) 2000, 2005-2011, 2013-2014, 2017 Free Software Foundation,
-Inc.
+Copyright (C) 2000-2021 Free Software Foundation, Inc.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
diff --git a/TODO b/TODO
deleted file mode 100644
index 9833f034..00000000
--- a/TODO
+++ /dev/null
@@ -1,150 +0,0 @@
-GNU m4 TODO - Tasks that need implementing. -*- outline -*-
-Copyright (C) 2000-2001, 2006-2008, 2010, 2013-2014, 2017 Free Software
-Foundation, Inc.
-
-Tell the maintainers at <bug-m4@gnu.org> if you feel like volunteering
-for any of these ideas or if you have others to add.
-
-* KNOWN BUGS
-
- + The following patch needs to be ported from the branch:
- http://lists.gnu.org/archive/html/m4-patches/2007-03/msg00005.html
- May be a couple of issues in that thread.
-
- + The format builtin needs more power to be like printf(1):
- http://lists.gnu.org/archive/html/m4-discuss/2007-05/msg00015.html
- But be aware of compatibility issues in making too many changes.
-
- + The test case `other-tests/stackovf.test' does not work.
-
- + stack overflow is basically broken
-
- The routines to detect stack overflow throuh segv are basically
- broken. The idea may be fine, but it ends up calling a sigv handler
- that uses gettext, printf, stdout... all of which are definitely NOT
- sig-safe. Pity, because the hardcode routine is basically very careful
- to use write(2), to avoid this.
-
- I haven't checked that translation magic is signal-safe.
- - I doubt it;
- - stdio is not signal-safe in any kind of portable setting anyways.
- --
- Marc Espie
- espie@schutzenberger.liafa.jussieu.fr
-
- Perhaps the gnulib c-stack module or libsigsegv would be useful:
- http://lists.gnu.org/archive/html/bug-gnu-utils/2008-01/msg00042.html
-
-* FEATURES OR PROBLEMS
-
- + m4 should keep an ``execution stack'' of macros, which applications could
- use in their error messages.
-
- + Implement discarding comment delimiters with the syntax table.
-
- + Implement qindir. Like indir, except that the result of the macro call
- is not expanded. Because the input stack might contain a file or a
- string, it is probably best achieved by making note that the TOS input
- should be copied rather than rescanned.
-
- $ echo "a'b" > f
- $ m4
- define(a,z)dnl
- include(f)dnl
- z'b
- indir(`include', f)dnl
- z'b
- qindir(`include', f)dnl
- a'b
- define(b,NONO)dnl
- patsubst(qindir(`include', f), `b', x)
- z'x
-
- + Use the TOS input quoting for qindir to fix this undesirable POSIX
- behavior:
-
- define(`x', -'-)
- define(y, defn(`x'))
- y
- --'
- --
- Stepan Kasal <kasal@ucw.cz>
-
- + If configured --with-gmp for multiple precision arithmetic there are
- some warnings, but it passes the tests.
-
- + Make m4 show include dependencies like gcc so Makefile targets are
- updated when their (included) input files are updated (Erick B).
-
- + Add support for wide character sets.
-
-
-* OPTIMIZATION AND CLEAN UP
-
- + Have NULs go really undisturbed through GNU m4
- GNU m4 is lousy regarding NULs in streams (this would require
- maintaining the string lengths, and avoiding strlen, strcpy,
- etc.). (Almost there, once argv_ref is ported).
-
- + The argument count limits are handled for all tokens passed around by
- the internals: we should enable attaching these values to text macros
- too.
-
- + The context parameter is just a placeholder for formerly global state.
- We should be making the library reentrant so that multiple instances
- of m4 can be run in the same process at the same time.
-
- + The path management stuff (in path.c/m4private.h) is reinventing the
- wheel. There are a bunch of fast path management and search functions
- in ltdl.c: These need to be sanitized, exported through ltdl.h, and
- then wrapped by the m4module.h path api. path.c can probably be removed
- entirely at that point.
-
-* MODULE SPECIFIC ISSUES
-
- + Some way of linking a module statically is needed, for systems
- without support for dynamic loading.
-
- + Some sort of module interface versioning system needs to be implemented
- in the module loader and the freezer so that m4 can tell if it is being
- asked to load a frozen file that requires versions of modules with
- interface versions unsupported by the current release.
-
- + The module API should probably use functions, not data exports:
- http://lists.gnu.org/archive/html/m4-patches/2007-09/msg00012.html
- Actually, there are several good ideas for module in that thread.
-
- + Setting of the module search path within m4 scripts:
-
- append(__modulepath__, `/some/modules/live/here')
-
- + Module autoloader. This would allow an m4 core with no builtins except
- for loadmodule(). A default startup script would mark the recognised
- set of builtins for autoload from the installed module directory on first
- use. A new cli parameter would inhibit initialisation from this script,
- so that customised m4 interpreters could be built on the fly!
-
- + The module loader needs to differentiate between modules that are in
- memory and modules that are loaded (i.e. visible) from various context
- structures.
-
- + The perl module should only be built if a suitable perl interpreter
- is found on the build machine. For that matter, it has been a
- while since the perl module has even been built, and perl has had
- new releases in the meantime.
-
-
-Local Variables:
-mode: outline
-outline-regexp: " *[-+*.] \\| "
-End:
-
-Copyright (C) 2000, 2006, 2007, 2009, 2010 Free Software Foundation,
-Inc.
-
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
-Texts. A copy of the license is included in the ``GNU Free
-Documentation License'' file as part of this distribution.
diff --git a/bootstrap b/bootstrap
deleted file mode 100755
index 8984cfd9..00000000
--- a/bootstrap
+++ /dev/null
@@ -1,5100 +0,0 @@
-#! /bin/sh
-## DO NOT EDIT - This file generated from build-aux/bootstrap.in
-## by inline-source v2014-01-03.01
-
-# Bootstrap an Autotooled package from checked-out sources.
-# Written by Gary V. Vaughan, 2010
-
-# Copyright (C) 2010-2014, 2017 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Originally written by Paul Eggert. The canonical version of this
-# script is maintained as build-aux/bootstrap in gnulib, however, to
-# be useful to your project, you should place a copy of it under
-# version control in the top-level directory of your project. The
-# intent is that all customization can be done with a bootstrap.conf
-# file also maintained in your version control; gnulib comes with a
-# template build-aux/bootstrap.conf to get you started.
-
-# Please report bugs or propose patches to bug-gnulib@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Most GNUish projects do not keep all of the generated Autotool
-# files under version control, but running all of the right tools
-# with the right arguments, in the correct order to regenerate
-# all of those files in readiness for configuration and building
-# can be surprisingly involved! Many projects have a 'bootstrap'
-# script under version control to invoke Autotools and perform
-# other assorted book-keeping with version numbers and the like.
-#
-# This bootstrap script aims to probe the configure.ac and top
-# Makefile.am of your project to automatically determine what
-# the correct ordering and arguments are and then run the tools for
-# you. In order to use it, you can generate an initial standalone
-# script with:
-#
-# gl/build-aux/inline-source gl/build-aux/bootstrap.in > bootstrap
-#
-# You should then store than script in version control for other
-# developers in you project. It will give you instructions about
-# how to keep it up to date if the sources change.
-#
-# See gl/doc/bootstrap.texi for documentation on how to write
-# a bootstrap.conf to customize it for your project's
-# idiosyncracies.
-
-
-## ================================================================== ##
-## ##
-## DO NOT EDIT THIS FILE, CUSTOMIZE IT USING A BOOTSTRAP.CONF ##
-## ##
-## ================================================================== ##
-
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
-
-# All uppercase denotes values stored in the environment. These
-# variables should generally be overridden by the user - however, we do
-# set them to 'true' in some parts of this script to prevent them being
-# called at the wrong time by other tools that we call ('autoreconf',
-# for example).
-#
-# We also allow 'LIBTOOLIZE', 'M4', 'SHA1SUM' and some others to be
-# overridden, and export the result for child processes, but they are
-# handled by the function 'func_find_tool' and not defaulted in this
-# section.
-
-: ${ACLOCAL="aclocal"}
-: ${AUTOCONF="autoconf"}
-: ${AUTOHEADER="autoheader"}
-: ${AUTOM4TE="autom4te"}
-: ${AUTOHEADER="autoheader"}
-: ${AUTOMAKE="automake"}
-: ${AUTOPOINT="autopoint"}
-: ${AUTORECONF="autoreconf"}
-: ${CMP="cmp"}
-: ${CONFIG_SHELL="/bin/sh"}
-: ${DIFF="diff"}
-: ${GIT="git"}
-: ${LN_S="ln -s"}
-: ${RM="rm"}
-
-export ACLOCAL
-export AUTOCONF
-export AUTOHEADER
-export AUTOM4TE
-export AUTOHEADER
-export AUTOMAKE
-export AUTOPOINT
-export AUTORECONF
-export CONFIG_SHELL
-
-
-## -------------- ##
-## Configuration. ##
-## -------------- ##
-
-# A newline delimited list of triples of programs (that respond to
-# --version), the minimum version numbers required (or just '-' in the
-# version field if any version will be sufficient) and homepage URLs
-# to help locate missing packages.
-buildreq=
-
-# Name of a file containing instructions on installing missing packages
-# required in 'buildreq'.
-buildreq_readme=README-hacking
-
-# These are extracted from AC_INIT in configure.ac, though you can
-# override those values in 'bootstrap.conf' if you prefer.
-build_aux=
-macro_dir=
-package=
-package_name=
-package_version=
-package_bugreport=
-
-# These are extracted from 'gnulib-cache.m4', or else fall-back
-# automatically on the gnulib defaults; unless you set the values
-# manually in 'bootstrap.conf'.
-doc_base=
-gnulib_mk=
-gnulib_name=
-local_gl_dir=
-source_base=
-tests_base=
-
-# The list of gnulib modules required at 'gnulib-tool' time. If you
-# check 'gnulib-cache.m4' into your repository, then this list will be
-# extracted automatically.
-gnulib_modules=
-
-# Extra gnulib files that are not in modules, which override files of
-# the same name installed by other bootstrap tools.
-gnulib_non_module_files="
- build-aux/compile
- build-aux/install-sh
- build-aux/mdate-sh
- build-aux/texinfo.tex
- build-aux/depcomp
- build-aux/config.guess
- build-aux/config.sub
- doc/INSTALL
-"
-
-# Relative path to the local gnulib submodule, and url to the upstream
-# git repository. If you have a gnulib entry in your .gitmodules file,
-# these values are ignored.
-gnulib_path=
-gnulib_url=
-
-# Additional gnulib-tool options to use.
-gnulib_tool_options="
- --no-changelog
-"
-
-# bootstrap removes any macro-files that are not included by aclocal.m4,
-# except for files listed in this variable that are always kept.
-gnulib_precious="
- gnulib-tool.m4
-"
-
-# When truncating long commands for display, always allow at least this
-# many characters before truncating.
-min_cmd_len=160
-
-# The command to download all .po files for a specified domain into
-# a specified directory. Fill in the first %s is the domain name, and
-# the second with the destination directory. Use rsync's -L and -r
-# options because the latest/%s directory and the .po files within are
-# all symlinks.
-po_download_command_format=\
-"rsync --delete --exclude '*.s1' -Lrtvz \
-'translationproject.org::tp/latest/%s/' '%s'"
-
-# Other locale categories that need message catalogs.
-extra_locale_categories=
-
-# Additional xgettext options to use. Gnulib might provide you with an
-# extensive list of additional options to append to this, but gettext
-# 0.16.1 and newer appends them automaticaly, so you can safely ignore
-# the complaints from 'gnulib-tool' if your $configure_ac states:
-#
-# AM_GNU_GETTEXT_VERSION([0.16.1])
-xgettext_options="
- --flag=_:1:pass-c-format
- --flag=N_:1:pass-c-format
-"
-
-# Package copyright holder for gettext files. Defaults to FSF if unset.
-copyright_holder=
-
-# File that should exist in the top directory of a checked out hierarchy,
-# but not in a distribution tarball.
-checkout_only_file=
-
-# Whether to use copies instead of symlinks by default (if set to true,
-# the --copy option has no effect).
-copy=false
-
-# Set this to ".cvsignore .gitignore" in 'bootstrap.conf' if you want
-# those files to be generated in directories like 'lib/', 'm4/', and 'po/',
-# or set it to "auto" to make this script select what to use based
-# on what version control system (if any) is used in the source directory.
-# Or set it to "none" to ignore VCS ignore files entirely. Default is
-# "auto".
-vc_ignore=
-
-
-## ------------------- ##
-## External Libraries. ##
-## ------------------- ##
-
-# Source required external libraries:
-# Set a version string for this script.
-scriptversion=2014-01-03.01; # UTC
-
-# General shell script boiler plate, and helper functions.
-# Written by Gary V. Vaughan, 2004
-
-# Copyright (C) 2004-2014, 2017 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-
-# As a special exception to the GNU General Public License, if you distribute
-# this file as part of a program or library that is built using GNU Libtool,
-# you may include this file under the same distribution terms that you use
-# for the rest of that program.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Evaluate this file near the top of your script to gain access to
-# the functions and variables defined here:
-#
-# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
-#
-# If you need to override any of the default environment variable
-# settings, do that before evaluating this file.
-
-
-## -------------------- ##
-## Shell normalisation. ##
-## -------------------- ##
-
-# Some shells need a little help to be as Bourne compatible as possible.
-# Before doing anything else, make sure all that help has been provided!
-
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
-fi
-
-# NLS nuisances: We save the old values in case they are required later.
-_G_user_locale=
-_G_safe_locale=
-for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
-do
- eval "if test set = \"\${$_G_var+set}\"; then
- save_$_G_var=\$$_G_var
- $_G_var=C
- export $_G_var
- _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
- _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
- fi"
-done
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Make sure IFS has a sensible default
-sp=' '
-nl='
-'
-IFS="$sp $nl"
-
-# There are apparently some retarded systems that use ';' as a PATH separator!
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-
-## ------------------------- ##
-## Locate command utilities. ##
-## ------------------------- ##
-
-
-# func_executable_p FILE
-# ----------------------
-# Check that FILE is an executable regular file.
-func_executable_p ()
-{
- test -f "$1" && test -x "$1"
-}
-
-
-# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
-# --------------------------------------------
-# Search for either a program that responds to --version with output
-# containing "GNU", or else returned by CHECK_FUNC otherwise, by
-# trying all the directories in PATH with each of the elements of
-# PROGS_LIST.
-#
-# CHECK_FUNC should accept the path to a candidate program, and
-# set $func_check_prog_result if it truncates its output less than
-# $_G_path_prog_max characters.
-func_path_progs ()
-{
- _G_progs_list=$1
- _G_check_func=$2
- _G_PATH=${3-"$PATH"}
-
- _G_path_prog_max=0
- _G_path_prog_found=false
- _G_save_IFS=$IFS; IFS=$PATH_SEPARATOR
- for _G_dir in $_G_PATH; do
- IFS=$_G_save_IFS
- test -z "$_G_dir" && _G_dir=.
- for _G_prog_name in $_G_progs_list; do
- for _exeext in '' .EXE; do
- _G_path_prog=$_G_dir/$_G_prog_name$_exeext
- func_executable_p "$_G_path_prog" || continue
- case `"$_G_path_prog" --version 2>&1` in
- *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
- *) $_G_check_func $_G_path_prog
- func_path_progs_result=$func_check_prog_result
- ;;
- esac
- $_G_path_prog_found && break 3
- done
- done
- done
- IFS=$_G_save_IFS
- test -z "$func_path_progs_result" && {
- echo "no acceptable sed could be found in \$PATH" >&2
- exit 1
- }
-}
-
-
-# We want to be able to use the functions in this file before configure
-# has figured out where the best binaries are kept, which means we have
-# to search for them ourselves - except when the results are already set
-# where we skip the searches.
-
-# Unless the user overrides by setting SED, search the path for either GNU
-# sed, or the sed that truncates its output the least.
-test -z "$SED" && {
- _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
- for _G_i in 1 2 3 4 5 6 7; do
- _G_sed_script=$_G_sed_script$nl$_G_sed_script
- done
- echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
- _G_sed_script=
-
- func_check_prog_sed ()
- {
- _G_path_prog=$1
-
- _G_count=0
- printf 0123456789 >conftest.in
- while :
- do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo '' >> conftest.nl
- "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
- diff conftest.out conftest.nl >/dev/null 2>&1 || break
- _G_count=`expr $_G_count + 1`
- if test "$_G_count" -gt "$_G_path_prog_max"; then
- # Best one so far, save it but keep looking for a better one
- func_check_prog_result=$_G_path_prog
- _G_path_prog_max=$_G_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test 10 -lt "$_G_count" && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out
- }
-
- func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
- rm -f conftest.sed
- SED=$func_path_progs_result
-}
-
-
-# Unless the user overrides by setting GREP, search the path for either GNU
-# grep, or the grep that truncates its output the least.
-test -z "$GREP" && {
- func_check_prog_grep ()
- {
- _G_path_prog=$1
-
- _G_count=0
- _G_path_prog_max=0
- printf 0123456789 >conftest.in
- while :
- do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo 'GREP' >> conftest.nl
- "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
- diff conftest.out conftest.nl >/dev/null 2>&1 || break
- _G_count=`expr $_G_count + 1`
- if test "$_G_count" -gt "$_G_path_prog_max"; then
- # Best one so far, save it but keep looking for a better one
- func_check_prog_result=$_G_path_prog
- _G_path_prog_max=$_G_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test 10 -lt "$_G_count" && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out
- }
-
- func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
- GREP=$func_path_progs_result
-}
-
-
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
-
-# All uppercase variable names are used for environment variables. These
-# variables can be overridden by the user before calling a script that
-# uses them if a suitable command of that name is not already available
-# in the command search PATH.
-
-: ${CP="cp -f"}
-: ${ECHO="printf %s\n"}
-: ${EGREP="$GREP -E"}
-: ${FGREP="$GREP -F"}
-: ${LN_S="ln -s"}
-: ${MAKE="make"}
-: ${MKDIR="mkdir"}
-: ${MV="mv -f"}
-: ${RM="rm -f"}
-: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
-
-
-## -------------------- ##
-## Useful sed snippets. ##
-## -------------------- ##
-
-sed_dirname='s|/[^/]*$||'
-sed_basename='s|^.*/||'
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
-
-# Same as above, but do not quote variable references.
-sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
-
-# Sed substitution that turns a string into a regex matching for the
-# string literally.
-sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
-
-# Sed substitution that converts a w32 file name or path
-# that contains forward slashes, into one that contains
-# (escaped) backslashes. A very naive implementation.
-sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
-
-# Re-'\' parameter expansions in output of sed_double_quote_subst that
-# were '\'-ed in input to the same. If an odd number of '\' preceded a
-# '$' in input to sed_double_quote_subst, that '$' was protected from
-# expansion. Since each input '\' is now two '\'s, look for any number
-# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'.
-_G_bs='\\'
-_G_bs2='\\\\'
-_G_bs4='\\\\\\\\'
-_G_dollar='\$'
-sed_double_backslash="\
- s/$_G_bs4/&\\
-/g
- s/^$_G_bs2$_G_dollar/$_G_bs&/
- s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
- s/\n//g"
-
-
-## ----------------- ##
-## Global variables. ##
-## ----------------- ##
-
-# Except for the global variables explicitly listed below, the following
-# functions in the '^func_' namespace, and the '^require_' namespace
-# variables initialised in the 'Resource management' section, sourcing
-# this file will not pollute your global namespace with anything
-# else. There's no portable way to scope variables in Bourne shell
-# though, so actually running these functions will sometimes place
-# results into a variable named after the function, and often use
-# temporary variables in the '^_G_' namespace. If you are careful to
-# avoid using those namespaces casually in your sourcing script, things
-# should continue to work as you expect. And, of course, you can freely
-# overwrite any of the functions or variables defined here before
-# calling anything to customize them.
-
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
-EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
-EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
-
-# Allow overriding, eg assuming that you follow the convention of
-# putting '$debug_cmd' at the start of all your functions, you can get
-# bash to show function call trace with:
-#
-# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
-debug_cmd=${debug_cmd-":"}
-exit_cmd=:
-
-# By convention, finish your script with:
-#
-# exit $exit_status
-#
-# so that you can set exit_status to non-zero if you want to indicate
-# something went wrong during execution without actually bailing out at
-# the point of failure.
-exit_status=$EXIT_SUCCESS
-
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath=$0
-
-# The name of this program.
-progname=`$ECHO "$progpath" |$SED "$sed_basename"`
-
-# Make sure we have an absolute progpath for reexecution:
-case $progpath in
- [\\/]*|[A-Za-z]:\\*) ;;
- *[\\/]*)
- progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
- progdir=`cd "$progdir" && pwd`
- progpath=$progdir/$progname
- ;;
- *)
- _G_IFS=$IFS
- IFS=${PATH_SEPARATOR-:}
- for progdir in $PATH; do
- IFS=$_G_IFS
- test -x "$progdir/$progname" && break
- done
- IFS=$_G_IFS
- test -n "$progdir" || progdir=`pwd`
- progpath=$progdir/$progname
- ;;
-esac
-
-
-## ----------------- ##
-## Standard options. ##
-## ----------------- ##
-
-# The following options affect the operation of the functions defined
-# below, and should be set appropriately depending on run-time para-
-# meters passed on the command line.
-
-opt_dry_run=false
-opt_quiet=false
-opt_verbose=false
-
-# Categories 'all' and 'none' are always available. Append any others
-# you will pass as the first argument to func_warning from your own
-# code.
-warning_categories=
-
-# By default, display warnings according to 'opt_warning_types'. Set
-# 'warning_func' to ':' to elide all warnings, or func_fatal_error to
-# treat the next displayed warning as a fatal error.
-warning_func=func_warn_and_continue
-
-# Set to 'all' to display all warnings, 'none' to suppress all
-# warnings, or a space delimited list of some subset of
-# 'warning_categories' to display only the listed warnings.
-opt_warning_types=all
-
-
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
-
-# This section contains definitions for functions that each ensure a
-# particular resource (a file, or a non-empty configuration variable for
-# example) is available, and if appropriate to extract default values
-# from pertinent package files. Call them using their associated
-# 'require_*' variable to ensure that they are executed, at most, once.
-#
-# It's entirely deliberate that calling these functions can set
-# variables that don't obey the namespace limitations obeyed by the rest
-# of this file, in order that that they be as useful as possible to
-# callers.
-
-
-# require_term_colors
-# -------------------
-# Allow display of bold text on terminals that support it.
-require_term_colors=func_require_term_colors
-func_require_term_colors ()
-{
- $debug_cmd
-
- test -t 1 && {
- # COLORTERM and USE_ANSI_COLORS environment variables take
- # precedence, because most terminfo databases neglect to describe
- # whether color sequences are supported.
- test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
-
- if test 1 = "$USE_ANSI_COLORS"; then
- # Standard ANSI escape sequences
- tc_reset=''
- tc_bold=''; tc_standout=''
- tc_red=''; tc_green=''
- tc_blue=''; tc_cyan=''
- else
- # Otherwise trust the terminfo database after all.
- test -n "`tput sgr0 2>/dev/null`" && {
- tc_reset=`tput sgr0`
- test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
- tc_standout=$tc_bold
- test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
- test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
- test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
- test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
- test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
- }
- fi
- }
-
- require_term_colors=:
-}
-
-
-## ----------------- ##
-## Function library. ##
-## ----------------- ##
-
-# This section contains a variety of useful functions to call in your
-# scripts. Take note of the portable wrappers for features provided by
-# some modern shells, which will fall back to slower equivalents on
-# less featureful shells.
-
-
-# func_append VAR VALUE
-# ---------------------
-# Append VALUE onto the existing contents of VAR.
-
- # We should try to minimise forks, especially on Windows where they are
- # unreasonably slow, so skip the feature probes when bash or zsh are
- # being used:
- if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
- : ${_G_HAVE_ARITH_OP="yes"}
- : ${_G_HAVE_XSI_OPS="yes"}
- # The += operator was introduced in bash 3.1
- case $BASH_VERSION in
- [12].* | 3.0 | 3.0*) ;;
- *)
- : ${_G_HAVE_PLUSEQ_OP="yes"}
- ;;
- esac
- fi
-
- # _G_HAVE_PLUSEQ_OP
- # Can be empty, in which case the shell is probed, "yes" if += is
- # useable or anything else if it does not work.
- test -z "$_G_HAVE_PLUSEQ_OP" \
- && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
- && _G_HAVE_PLUSEQ_OP=yes
-
-if test yes = "$_G_HAVE_PLUSEQ_OP"
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_append ()
- {
- $debug_cmd
-
- eval "$1+=\$2"
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_append ()
- {
- $debug_cmd
-
- eval "$1=\$$1\$2"
- }
-fi
-
-
-# func_append_quoted VAR VALUE
-# ----------------------------
-# Quote VALUE and append to the end of shell variable VAR, separated
-# by a space.
-if test yes = "$_G_HAVE_PLUSEQ_OP"; then
- eval 'func_append_quoted ()
- {
- $debug_cmd
-
- func_quote_for_eval "$2"
- eval "$1+=\\ \$func_quote_for_eval_result"
- }'
-else
- func_append_quoted ()
- {
- $debug_cmd
-
- func_quote_for_eval "$2"
- eval "$1=\$$1\\ \$func_quote_for_eval_result"
- }
-fi
-
-
-# func_append_uniq VAR VALUE
-# --------------------------
-# Append unique VALUE onto the existing contents of VAR, assuming
-# entries are delimited by the first character of VALUE. For example:
-#
-# func_append_uniq options " --another-option option-argument"
-#
-# will only append to $options if " --another-option option-argument "
-# is not already present somewhere in $options already (note spaces at
-# each end implied by leading space in second argument).
-func_append_uniq ()
-{
- $debug_cmd
-
- eval _G_current_value='`$ECHO $'$1'`'
- _G_delim=`expr "$2" : '\(.\)'`
-
- case $_G_delim$_G_current_value$_G_delim in
- *"$2$_G_delim"*) ;;
- *) func_append "$@" ;;
- esac
-}
-
-
-# func_arith TERM...
-# ------------------
-# Set func_arith_result to the result of evaluating TERMs.
- test -z "$_G_HAVE_ARITH_OP" \
- && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
- && _G_HAVE_ARITH_OP=yes
-
-if test yes = "$_G_HAVE_ARITH_OP"; then
- eval 'func_arith ()
- {
- $debug_cmd
-
- func_arith_result=$(( $* ))
- }'
-else
- func_arith ()
- {
- $debug_cmd
-
- func_arith_result=`expr "$@"`
- }
-fi
-
-
-# func_basename FILE
-# ------------------
-# Set func_basename_result to FILE with everything up to and including
-# the last / stripped.
-if test yes = "$_G_HAVE_XSI_OPS"; then
- # If this shell supports suffix pattern removal, then use it to avoid
- # forking. Hide the definitions single quotes in case the shell chokes
- # on unsupported syntax...
- _b='func_basename_result=${1##*/}'
- _d='case $1 in
- */*) func_dirname_result=${1%/*}$2 ;;
- * ) func_dirname_result=$3 ;;
- esac'
-
-else
- # ...otherwise fall back to using sed.
- _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
- _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"`
- if test "X$func_dirname_result" = "X$1"; then
- func_dirname_result=$3
- else
- func_append func_dirname_result "$2"
- fi'
-fi
-
-eval 'func_basename ()
-{
- $debug_cmd
-
- '"$_b"'
-}'
-
-
-# func_dirname FILE APPEND NONDIR_REPLACEMENT
-# -------------------------------------------
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-eval 'func_dirname ()
-{
- $debug_cmd
-
- '"$_d"'
-}'
-
-
-# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
-# --------------------------------------------------------
-# Perform func_basename and func_dirname in a single function
-# call:
-# dirname: Compute the dirname of FILE. If nonempty,
-# add APPEND to the result, otherwise set result
-# to NONDIR_REPLACEMENT.
-# value returned in "$func_dirname_result"
-# basename: Compute filename of FILE.
-# value retuned in "$func_basename_result"
-# For efficiency, we do not delegate to the functions above but instead
-# duplicate the functionality here.
-eval 'func_dirname_and_basename ()
-{
- $debug_cmd
-
- '"$_b"'
- '"$_d"'
-}'
-
-
-# func_echo ARG...
-# ----------------
-# Echo program name prefixed message.
-func_echo ()
-{
- $debug_cmd
-
- _G_message=$*
-
- func_echo_IFS=$IFS
- IFS=$nl
- for _G_line in $_G_message; do
- IFS=$func_echo_IFS
- $ECHO "$progname: $_G_line"
- done
- IFS=$func_echo_IFS
-}
-
-
-# func_echo_all ARG...
-# --------------------
-# Invoke $ECHO with all args, space-separated.
-func_echo_all ()
-{
- $ECHO "$*"
-}
-
-
-# func_echo_infix_1 INFIX ARG...
-# ------------------------------
-# Echo program name, followed by INFIX on the first line, with any
-# additional lines not showing INFIX.
-func_echo_infix_1 ()
-{
- $debug_cmd
-
- $require_term_colors
-
- _G_infix=$1; shift
- _G_indent=$_G_infix
- _G_prefix="$progname: $_G_infix: "
- _G_message=$*
-
- # Strip color escape sequences before counting printable length
- for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
- do
- test -n "$_G_tc" && {
- _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
- _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
- }
- done
- _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes
-
- func_echo_infix_1_IFS=$IFS
- IFS=$nl
- for _G_line in $_G_message; do
- IFS=$func_echo_infix_1_IFS
- $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
- _G_prefix=$_G_indent
- done
- IFS=$func_echo_infix_1_IFS
-}
-
-
-# func_error ARG...
-# -----------------
-# Echo program name prefixed message to standard error.
-func_error ()
-{
- $debug_cmd
-
- $require_term_colors
-
- func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2
-}
-
-
-# func_fatal_error ARG...
-# -----------------------
-# Echo program name prefixed message to standard error, and exit.
-func_fatal_error ()
-{
- $debug_cmd
-
- func_error "$*"
- exit $EXIT_FAILURE
-}
-
-
-# func_grep EXPRESSION FILENAME
-# -----------------------------
-# Check whether EXPRESSION matches any line of FILENAME, without output.
-func_grep ()
-{
- $debug_cmd
-
- $GREP "$1" "$2" >/dev/null 2>&1
-}
-
-
-# func_len STRING
-# ---------------
-# Set func_len_result to the length of STRING. STRING may not
-# start with a hyphen.
- test -z "$_G_HAVE_XSI_OPS" \
- && (eval 'x=a/b/c;
- test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
- && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"; then
- eval 'func_len ()
- {
- $debug_cmd
-
- func_len_result=${#1}
- }'
-else
- func_len ()
- {
- $debug_cmd
-
- func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
- }
-fi
-
-
-# func_mkdir_p DIRECTORY-PATH
-# ---------------------------
-# Make sure the entire path to DIRECTORY-PATH is available.
-func_mkdir_p ()
-{
- $debug_cmd
-
- _G_directory_path=$1
- _G_dir_list=
-
- if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
-
- # Protect directory names starting with '-'
- case $_G_directory_path in
- -*) _G_directory_path=./$_G_directory_path ;;
- esac
-
- # While some portion of DIR does not yet exist...
- while test ! -d "$_G_directory_path"; do
- # ...make a list in topmost first order. Use a colon delimited
- # list incase some portion of path contains whitespace.
- _G_dir_list=$_G_directory_path:$_G_dir_list
-
- # If the last portion added has no slash in it, the list is done
- case $_G_directory_path in */*) ;; *) break ;; esac
-
- # ...otherwise throw away the child directory and loop
- _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
- done
- _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
-
- func_mkdir_p_IFS=$IFS; IFS=:
- for _G_dir in $_G_dir_list; do
- IFS=$func_mkdir_p_IFS
- # mkdir can fail with a 'File exist' error if two processes
- # try to create one of the directories concurrently. Don't
- # stop in that case!
- $MKDIR "$_G_dir" 2>/dev/null || :
- done
- IFS=$func_mkdir_p_IFS
-
- # Bail out if we (or some other process) failed to create a directory.
- test -d "$_G_directory_path" || \
- func_fatal_error "Failed to create '$1'"
- fi
-}
-
-
-# func_mktempdir [BASENAME]
-# -------------------------
-# Make a temporary directory that won't clash with other running
-# libtool processes, and avoids race conditions if possible. If
-# given, BASENAME is the basename for that directory.
-func_mktempdir ()
-{
- $debug_cmd
-
- _G_template=${TMPDIR-/tmp}/${1-$progname}
-
- if test : = "$opt_dry_run"; then
- # Return a directory name, but don't create it in dry-run mode
- _G_tmpdir=$_G_template-$$
- else
-
- # If mktemp works, use that first and foremost
- _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
-
- if test ! -d "$_G_tmpdir"; then
- # Failing that, at least try and use $RANDOM to avoid a race
- _G_tmpdir=$_G_template-${RANDOM-0}$$
-
- func_mktempdir_umask=`umask`
- umask 0077
- $MKDIR "$_G_tmpdir"
- umask $func_mktempdir_umask
- fi
-
- # If we're not in dry-run mode, bomb out on failure
- test -d "$_G_tmpdir" || \
- func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
- fi
-
- $ECHO "$_G_tmpdir"
-}
-
-
-# func_normal_abspath PATH
-# ------------------------
-# Remove doubled-up and trailing slashes, "." path components,
-# and cancel out any ".." path components in PATH after making
-# it an absolute path.
-func_normal_abspath ()
-{
- $debug_cmd
-
- # These SED scripts presuppose an absolute path with a trailing slash.
- _G_pathcar='s|^/\([^/]*\).*$|\1|'
- _G_pathcdr='s|^/[^/]*||'
- _G_removedotparts=':dotsl
- s|/\./|/|g
- t dotsl
- s|/\.$|/|'
- _G_collapseslashes='s|/\{1,\}|/|g'
- _G_finalslash='s|/*$|/|'
-
- # Start from root dir and reassemble the path.
- func_normal_abspath_result=
- func_normal_abspath_tpath=$1
- func_normal_abspath_altnamespace=
- case $func_normal_abspath_tpath in
- "")
- # Empty path, that just means $cwd.
- func_stripname '' '/' "`pwd`"
- func_normal_abspath_result=$func_stripname_result
- return
- ;;
- # The next three entries are used to spot a run of precisely
- # two leading slashes without using negated character classes;
- # we take advantage of case's first-match behaviour.
- ///*)
- # Unusual form of absolute path, do nothing.
- ;;
- //*)
- # Not necessarily an ordinary path; POSIX reserves leading '//'
- # and for example Cygwin uses it to access remote file shares
- # over CIFS/SMB, so we conserve a leading double slash if found.
- func_normal_abspath_altnamespace=/
- ;;
- /*)
- # Absolute path, do nothing.
- ;;
- *)
- # Relative path, prepend $cwd.
- func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
- ;;
- esac
-
- # Cancel out all the simple stuff to save iterations. We also want
- # the path to end with a slash for ease of parsing, so make sure
- # there is one (and only one) here.
- func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
- -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
- while :; do
- # Processed it all yet?
- if test / = "$func_normal_abspath_tpath"; then
- # If we ascended to the root using ".." the result may be empty now.
- if test -z "$func_normal_abspath_result"; then
- func_normal_abspath_result=/
- fi
- break
- fi
- func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
- -e "$_G_pathcar"`
- func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
- -e "$_G_pathcdr"`
- # Figure out what to do with it
- case $func_normal_abspath_tcomponent in
- "")
- # Trailing empty path component, ignore it.
- ;;
- ..)
- # Parent dir; strip last assembled component from result.
- func_dirname "$func_normal_abspath_result"
- func_normal_abspath_result=$func_dirname_result
- ;;
- *)
- # Actual path component, append it.
- func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
- ;;
- esac
- done
- # Restore leading double-slash if one was found on entry.
- func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
-}
-
-
-# func_notquiet ARG...
-# --------------------
-# Echo program name prefixed message only when not in quiet mode.
-func_notquiet ()
-{
- $debug_cmd
-
- $opt_quiet || func_echo ${1+"$@"}
-
- # A bug in bash halts the script if the last line of a function
- # fails when set -e is in force, so we need another command to
- # work around that:
- :
-}
-
-
-# func_relative_path SRCDIR DSTDIR
-# --------------------------------
-# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
-func_relative_path ()
-{
- $debug_cmd
-
- func_relative_path_result=
- func_normal_abspath "$1"
- func_relative_path_tlibdir=$func_normal_abspath_result
- func_normal_abspath "$2"
- func_relative_path_tbindir=$func_normal_abspath_result
-
- # Ascend the tree starting from libdir
- while :; do
- # check if we have found a prefix of bindir
- case $func_relative_path_tbindir in
- $func_relative_path_tlibdir)
- # found an exact match
- func_relative_path_tcancelled=
- break
- ;;
- $func_relative_path_tlibdir*)
- # found a matching prefix
- func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
- func_relative_path_tcancelled=$func_stripname_result
- if test -z "$func_relative_path_result"; then
- func_relative_path_result=.
- fi
- break
- ;;
- *)
- func_dirname $func_relative_path_tlibdir
- func_relative_path_tlibdir=$func_dirname_result
- if test -z "$func_relative_path_tlibdir"; then
- # Have to descend all the way to the root!
- func_relative_path_result=../$func_relative_path_result
- func_relative_path_tcancelled=$func_relative_path_tbindir
- break
- fi
- func_relative_path_result=../$func_relative_path_result
- ;;
- esac
- done
-
- # Now calculate path; take care to avoid doubling-up slashes.
- func_stripname '' '/' "$func_relative_path_result"
- func_relative_path_result=$func_stripname_result
- func_stripname '/' '/' "$func_relative_path_tcancelled"
- if test -n "$func_stripname_result"; then
- func_append func_relative_path_result "/$func_stripname_result"
- fi
-
- # Normalisation. If bindir is libdir, return '.' else relative path.
- if test -n "$func_relative_path_result"; then
- func_stripname './' '' "$func_relative_path_result"
- func_relative_path_result=$func_stripname_result
- fi
-
- test -n "$func_relative_path_result" || func_relative_path_result=.
-
- :
-}
-
-
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-# i) func_quote_for_eval_result
-# double-quoted, suitable for a subsequent eval
-# ii) func_quote_for_eval_unquoted_result
-# has all characters that are still active within double
-# quotes backslashified.
-func_quote_for_eval ()
-{
- $debug_cmd
-
- func_quote_for_eval_unquoted_result=
- func_quote_for_eval_result=
- while test 0 -lt $#; do
- case $1 in
- *[\\\`\"\$]*)
- _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
- *)
- _G_unquoted_arg=$1 ;;
- esac
- if test -n "$func_quote_for_eval_unquoted_result"; then
- func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
- else
- func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
- fi
-
- case $_G_unquoted_arg in
- # Double-quote args containing shell metacharacters to delay
- # word splitting, command substitution and variable expansion
- # for a subsequent eval.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- _G_quoted_arg=\"$_G_unquoted_arg\"
- ;;
- *)
- _G_quoted_arg=$_G_unquoted_arg
- ;;
- esac
-
- if test -n "$func_quote_for_eval_result"; then
- func_append func_quote_for_eval_result " $_G_quoted_arg"
- else
- func_append func_quote_for_eval_result "$_G_quoted_arg"
- fi
- shift
- done
-}
-
-
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
-{
- $debug_cmd
-
- case $1 in
- *[\\\`\"]*)
- _G_arg=`$ECHO "$1" | $SED \
- -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
- *)
- _G_arg=$1 ;;
- esac
-
- case $_G_arg in
- # Double-quote args containing shell metacharacters to delay
- # word splitting and command substitution for a subsequent eval.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- _G_arg=\"$_G_arg\"
- ;;
- esac
-
- func_quote_for_expand_result=$_G_arg
-}
-
-
-# func_stripname PREFIX SUFFIX NAME
-# ---------------------------------
-# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-if test yes = "$_G_HAVE_XSI_OPS"; then
- eval 'func_stripname ()
- {
- $debug_cmd
-
- # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
- # positional parameters, so assign one to ordinary variable first.
- func_stripname_result=$3
- func_stripname_result=${func_stripname_result#"$1"}
- func_stripname_result=${func_stripname_result%"$2"}
- }'
-else
- func_stripname ()
- {
- $debug_cmd
-
- case $2 in
- .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
- *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
- esac
- }
-fi
-
-
-# func_show_eval CMD [FAIL_EXP]
-# -----------------------------
-# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
-# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.
-func_show_eval ()
-{
- $debug_cmd
-
- _G_cmd=$1
- _G_fail_exp=${2-':'}
-
- func_quote_for_expand "$_G_cmd"
- eval "func_notquiet $func_quote_for_expand_result"
-
- $opt_dry_run || {
- eval "$_G_cmd"
- _G_status=$?
- if test 0 -ne "$_G_status"; then
- eval "(exit $_G_status); $_G_fail_exp"
- fi
- }
-}
-
-
-# func_show_eval_locale CMD [FAIL_EXP]
-# ------------------------------------
-# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
-# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it. Use the saved locale for evaluation.
-func_show_eval_locale ()
-{
- $debug_cmd
-
- _G_cmd=$1
- _G_fail_exp=${2-':'}
-
- $opt_quiet || {
- func_quote_for_expand "$_G_cmd"
- eval "func_echo $func_quote_for_expand_result"
- }
-
- $opt_dry_run || {
- eval "$_G_user_locale
- $_G_cmd"
- _G_status=$?
- eval "$_G_safe_locale"
- if test 0 -ne "$_G_status"; then
- eval "(exit $_G_status); $_G_fail_exp"
- fi
- }
-}
-
-
-# func_tr_sh
-# ----------
-# Turn $1 into a string suitable for a shell variable name.
-# Result is stored in $func_tr_sh_result. All characters
-# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
-# if $1 begins with a digit, a '_' is prepended as well.
-func_tr_sh ()
-{
- $debug_cmd
-
- case $1 in
- [0-9]* | *[!a-zA-Z0-9_]*)
- func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
- ;;
- * )
- func_tr_sh_result=$1
- ;;
- esac
-}
-
-
-# func_verbose ARG...
-# -------------------
-# Echo program name prefixed message in verbose mode only.
-func_verbose ()
-{
- $debug_cmd
-
- $opt_verbose && func_echo "$*"
-
- :
-}
-
-
-# func_warn_and_continue ARG...
-# -----------------------------
-# Echo program name prefixed warning message to standard error.
-func_warn_and_continue ()
-{
- $debug_cmd
-
- $require_term_colors
-
- func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
-}
-
-
-# func_warning CATEGORY ARG...
-# ----------------------------
-# Echo program name prefixed warning message to standard error. Warning
-# messages can be filtered according to CATEGORY, where this function
-# elides messages where CATEGORY is not listed in the global variable
-# 'opt_warning_types'.
-func_warning ()
-{
- $debug_cmd
-
- # CATEGORY must be in the warning_categories list!
- case " $warning_categories " in
- *" $1 "*) ;;
- *) func_internal_error "invalid warning category '$1'" ;;
- esac
-
- _G_category=$1
- shift
-
- case " $opt_warning_types " in
- *" $_G_category "*) $warning_func ${1+"$@"} ;;
- esac
-}
-
-
-# func_sort_ver VER1 VER2
-# -----------------------
-# 'sort -V' is not generally available.
-# Note this deviates from the version comparison in automake
-# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
-# but this should suffice as we won't be specifying old
-# version formats or redundant trailing .0 in bootstrap.conf.
-# If we did want full compatibility then we should probably
-# use m4_version_compare from autoconf.
-func_sort_ver ()
-{
- $debug_cmd
-
- printf '%s\n%s\n' "$1" "$2" \
- | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
-}
-
-# func_lt_ver PREV CURR
-# ---------------------
-# Return true if PREV and CURR are in the correct order according to
-# func_sort_ver, otherwise false. Use it like this:
-#
-# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
-func_lt_ver ()
-{
- $debug_cmd
-
- test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
-}
-
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
-#! /bin/sh
-
-# Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
-
-# A portable, pluggable option parser for Bourne shell.
-# Written by Gary V. Vaughan, 2010
-
-# Copyright (C) 2010-2014, 2017 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# This file is a library for parsing options in your shell scripts along
-# with assorted other useful supporting features that you can make use
-# of too.
-#
-# For the simplest scripts you might need only:
-#
-# #!/bin/sh
-# . relative/path/to/funclib.sh
-# . relative/path/to/options-parser
-# scriptversion=1.0
-# func_options ${1+"$@"}
-# eval set dummy "$func_options_result"; shift
-# ...rest of your script...
-#
-# In order for the '--version' option to work, you will need to have a
-# suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# warranty; '.
-#
-# For '-h' and '--help' to work, you will also need a one line
-# description of your script's purpose in a comment directly above the
-# '# Written by ' line, like the one at the top of this file.
-#
-# The default options also support '--debug', which will turn on shell
-# execution tracing (see the comment above debug_cmd below for another
-# use), and '--verbose' and the func_verbose function to allow your script
-# to display verbose messages only when your user has specified
-# '--verbose'.
-#
-# After sourcing this file, you can plug processing for additional
-# options by amending the variables from the 'Configuration' section
-# below, and following the instructions in the 'Option parsing'
-# section further down.
-
-## -------------- ##
-## Configuration. ##
-## -------------- ##
-
-# You should override these variables in your script after sourcing this
-# file so that they reflect the customisations you have added to the
-# option parser.
-
-# The usage line for option parsing errors and the start of '-h' and
-# '--help' output messages. You can embed shell variables for delayed
-# expansion at the time the message is displayed, but you will need to
-# quote other shell meta-characters carefully to prevent them being
-# expanded when the contents are evaled.
-usage='$progpath [OPTION]...'
-
-# Short help message in response to '-h' and '--help'. Add to this or
-# override it after sourcing this library to reflect the full set of
-# options your script accepts.
-usage_message="\
- --debug enable verbose shell tracing
- -W, --warnings=CATEGORY
- report the warnings falling in CATEGORY [all]
- -v, --verbose verbosely report processing
- --version print version information and exit
- -h, --help print short or long help message and exit
-"
-
-# Additional text appended to 'usage_message' in response to '--help'.
-long_help_message="
-Warning categories include:
- 'all' show all warnings
- 'none' turn off all the warnings
- 'error' warnings are treated as fatal errors"
-
-# Help message printed before fatal option parsing errors.
-fatal_help="Try '\$progname --help' for more information."
-
-
-
-## ------------------------- ##
-## Hook function management. ##
-## ------------------------- ##
-
-# This section contains functions for adding, removing, and running hooks
-# to the main code. A hook is just a named list of of function, that can
-# be run in order later on.
-
-# func_hookable FUNC_NAME
-# -----------------------
-# Declare that FUNC_NAME will run hooks added with
-# 'func_add_hook FUNC_NAME ...'.
-func_hookable ()
-{
- $debug_cmd
-
- func_append hookable_fns " $1"
-}
-
-
-# func_add_hook FUNC_NAME HOOK_FUNC
-# ---------------------------------
-# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must
-# first have been declared "hookable" by a call to 'func_hookable'.
-func_add_hook ()
-{
- $debug_cmd
-
- case " $hookable_fns " in
- *" $1 "*) ;;
- *) func_fatal_error "'$1' does not accept hook functions." ;;
- esac
-
- eval func_append ${1}_hooks '" $2"'
-}
-
-
-# func_remove_hook FUNC_NAME HOOK_FUNC
-# ------------------------------------
-# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
-func_remove_hook ()
-{
- $debug_cmd
-
- eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
-}
-
-
-# func_run_hooks FUNC_NAME [ARG]...
-# ---------------------------------
-# Run all hook functions registered to FUNC_NAME.
-# It is assumed that the list of hook functions contains nothing more
-# than a whitespace-delimited list of legal shell function names, and
-# no effort is wasted trying to catch shell meta-characters or preserve
-# whitespace.
-func_run_hooks ()
-{
- $debug_cmd
-
- case " $hookable_fns " in
- *" $1 "*) ;;
- *) func_fatal_error "'$1' does not support hook funcions.n" ;;
- esac
-
- eval _G_hook_fns=\$$1_hooks; shift
-
- for _G_hook in $_G_hook_fns; do
- eval $_G_hook '"$@"'
-
- # store returned options list back into positional
- # parameters for next 'cmd' execution.
- eval _G_hook_result=\$${_G_hook}_result
- eval set dummy "$_G_hook_result"; shift
- done
-
- func_quote_for_eval ${1+"$@"}
- func_run_hooks_result=$func_quote_for_eval_result
-}
-
-
-
-## --------------- ##
-## Option parsing. ##
-## --------------- ##
-
-# In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
-# options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'. Like this:
-#
-# my_options_prep ()
-# {
-# $debug_cmd
-#
-# # Extend the existing usage message.
-# usage_message=$usage_message'
-# -s, --silent don'\''t print informational messages
-# '
-#
-# func_quote_for_eval ${1+"$@"}
-# my_options_prep_result=$func_quote_for_eval_result
-# }
-# func_add_hook func_options_prep my_options_prep
-#
-#
-# my_silent_option ()
-# {
-# $debug_cmd
-#
-# # Note that for efficiency, we parse as many options as we can
-# # recognise in a loop before passing the remainder back to the
-# # caller on the first unrecognised argument we encounter.
-# while test $# -gt 0; do
-# opt=$1; shift
-# case $opt in
-# --silent|-s) opt_silent=: ;;
-# # Separate non-argument short options:
-# -s*) func_split_short_opt "$_G_opt"
-# set dummy "$func_split_short_opt_name" \
-# "-$func_split_short_opt_arg" ${1+"$@"}
-# shift
-# ;;
-# *) set dummy "$_G_opt" "$*"; shift; break ;;
-# esac
-# done
-#
-# func_quote_for_eval ${1+"$@"}
-# my_silent_option_result=$func_quote_for_eval_result
-# }
-# func_add_hook func_parse_options my_silent_option
-#
-#
-# my_option_validation ()
-# {
-# $debug_cmd
-#
-# $opt_silent && $opt_verbose && func_fatal_help "\
-# '--silent' and '--verbose' options are mutually exclusive."
-#
-# func_quote_for_eval ${1+"$@"}
-# my_option_validation_result=$func_quote_for_eval_result
-# }
-# func_add_hook func_validate_options my_option_validation
-#
-# You'll alse need to manually amend $usage_message to reflect the extra
-# options you parse. It's preferable to append if you can, so that
-# multiple option parsing hooks can be added safely.
-
-
-# func_options [ARG]...
-# ---------------------
-# All the functions called inside func_options are hookable. See the
-# individual implementations for details.
-func_hookable func_options
-func_options ()
-{
- $debug_cmd
-
- func_options_prep ${1+"$@"}
- eval func_parse_options \
- ${func_options_prep_result+"$func_options_prep_result"}
- eval func_validate_options \
- ${func_parse_options_result+"$func_parse_options_result"}
-
- eval func_run_hooks func_options \
- ${func_validate_options_result+"$func_validate_options_result"}
-
- # save modified positional parameters for caller
- func_options_result=$func_run_hooks_result
-}
-
-
-# func_options_prep [ARG]...
-# --------------------------
-# All initialisations required before starting the option parse loop.
-# Note that when calling hook functions, we pass through the list of
-# positional parameters. If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before
-# returning.
-func_hookable func_options_prep
-func_options_prep ()
-{
- $debug_cmd
-
- # Option defaults:
- opt_verbose=false
- opt_warning_types=
-
- func_run_hooks func_options_prep ${1+"$@"}
-
- # save modified positional parameters for caller
- func_options_prep_result=$func_run_hooks_result
-}
-
-
-# func_parse_options [ARG]...
-# ---------------------------
-# The main option parsing loop.
-func_hookable func_parse_options
-func_parse_options ()
-{
- $debug_cmd
-
- func_parse_options_result=
-
- # this just eases exit handling
- while test $# -gt 0; do
- # Defer to hook functions for initial option parsing, so they
- # get priority in the event of reusing an option name.
- func_run_hooks func_parse_options ${1+"$@"}
-
- # Adjust func_parse_options positional parameters to match
- eval set dummy "$func_run_hooks_result"; shift
-
- # Break out of the loop if we already parsed every option.
- test $# -gt 0 || break
-
- _G_opt=$1
- shift
- case $_G_opt in
- --debug|-x) debug_cmd='set -x'
- func_echo "enabling shell trace mode"
- $debug_cmd
- ;;
-
- --no-warnings|--no-warning|--no-warn)
- set dummy --warnings none ${1+"$@"}
- shift
- ;;
-
- --warnings|--warning|-W)
- test $# = 0 && func_missing_arg $_G_opt && break
- case " $warning_categories $1" in
- *" $1 "*)
- # trailing space prevents matching last $1 above
- func_append_uniq opt_warning_types " $1"
- ;;
- *all)
- opt_warning_types=$warning_categories
- ;;
- *none)
- opt_warning_types=none
- warning_func=:
- ;;
- *error)
- opt_warning_types=$warning_categories
- warning_func=func_fatal_error
- ;;
- *)
- func_fatal_error \
- "unsupported warning category: '$1'"
- ;;
- esac
- shift
- ;;
-
- --verbose|-v) opt_verbose=: ;;
- --version) func_version ;;
- -\?|-h) func_usage ;;
- --help) func_help ;;
-
- # Separate optargs to long options (plugins may need this):
- --*=*) func_split_equals "$_G_opt"
- set dummy "$func_split_equals_lhs" \
- "$func_split_equals_rhs" ${1+"$@"}
- shift
- ;;
-
- # Separate optargs to short options:
- -W*)
- func_split_short_opt "$_G_opt"
- set dummy "$func_split_short_opt_name" \
- "$func_split_short_opt_arg" ${1+"$@"}
- shift
- ;;
-
- # Separate non-argument short options:
- -\?*|-h*|-v*|-x*)
- func_split_short_opt "$_G_opt"
- set dummy "$func_split_short_opt_name" \
- "-$func_split_short_opt_arg" ${1+"$@"}
- shift
- ;;
-
- --) break ;;
- -*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
- *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
- esac
- done
-
- # save modified positional parameters for caller
- func_quote_for_eval ${1+"$@"}
- func_parse_options_result=$func_quote_for_eval_result
-}
-
-
-# func_validate_options [ARG]...
-# ------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-func_hookable func_validate_options
-func_validate_options ()
-{
- $debug_cmd
-
- # Display all warnings if -W was not given.
- test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
-
- func_run_hooks func_validate_options ${1+"$@"}
-
- # Bail if the options were screwed!
- $exit_cmd $EXIT_FAILURE
-
- # save modified positional parameters for caller
- func_validate_options_result=$func_run_hooks_result
-}
-
-
-
-## ----------------- ##
-## Helper functions. ##
-## ----------------- ##
-
-# This section contains the helper functions used by the rest of the
-# hookable option parser framework in ascii-betical order.
-
-
-# func_fatal_help ARG...
-# ----------------------
-# Echo program name prefixed message to standard error, followed by
-# a help hint, and exit.
-func_fatal_help ()
-{
- $debug_cmd
-
- eval \$ECHO \""Usage: $usage"\"
- eval \$ECHO \""$fatal_help"\"
- func_error ${1+"$@"}
- exit $EXIT_FAILURE
-}
-
-
-# func_help
-# ---------
-# Echo long help message to standard output and exit.
-func_help ()
-{
- $debug_cmd
-
- func_usage_message
- $ECHO "$long_help_message"
- exit 0
-}
-
-
-# func_missing_arg ARGNAME
-# ------------------------
-# Echo program name prefixed message to standard error and set global
-# exit_cmd.
-func_missing_arg ()
-{
- $debug_cmd
-
- func_error "Missing argument for '$1'."
- exit_cmd=exit
-}
-
-
-# func_split_equals STRING
-# ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
-# splitting STRING at the '=' sign.
-test -z "$_G_HAVE_XSI_OPS" \
- && (eval 'x=a/b/c;
- test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
- && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_split_equals ()
- {
- $debug_cmd
-
- func_split_equals_lhs=${1%%=*}
- func_split_equals_rhs=${1#*=}
- test "x$func_split_equals_lhs" = "x$1" \
- && func_split_equals_rhs=
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_split_equals ()
- {
- $debug_cmd
-
- func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
- func_split_equals_rhs=
- test "x$func_split_equals_lhs" = "x$1" \
- || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
- }
-fi #func_split_equals
-
-
-# func_split_short_opt SHORTOPT
-# -----------------------------
-# Set func_split_short_opt_name and func_split_short_opt_arg shell
-# variables after splitting SHORTOPT after the 2nd character.
-if test yes = "$_G_HAVE_XSI_OPS"
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_split_short_opt ()
- {
- $debug_cmd
-
- func_split_short_opt_arg=${1#??}
- func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_split_short_opt ()
- {
- $debug_cmd
-
- func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
- func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
- }
-fi #func_split_short_opt
-
-
-# func_usage
-# ----------
-# Echo short help message to standard output and exit.
-func_usage ()
-{
- $debug_cmd
-
- func_usage_message
- $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
- exit 0
-}
-
-
-# func_usage_message
-# ------------------
-# Echo short help message to standard output.
-func_usage_message ()
-{
- $debug_cmd
-
- eval \$ECHO \""Usage: $usage"\"
- echo
- $SED -n 's|^# ||
- /^Written by/{
- x;p;x
- }
- h
- /^Written by/q' < "$progpath"
- echo
- eval \$ECHO \""$usage_message"\"
-}
-
-
-# func_version
-# ------------
-# Echo version message to standard output and exit.
-func_version ()
-{
- $debug_cmd
-
- printf '%s\n' "$progname $scriptversion"
- $SED -n '
- /(C)/!b go
- :more
- /\./!{
- N
- s|\n# | |
- b more
- }
- :go
- /^# Written by /,/# warranty; / {
- s|^# ||
- s|^# *$||
- s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
- p
- }
- /^# Written by / {
- s|^# ||
- p
- }
- /^warranty; /q' < "$progpath"
-
- exit $?
-}
-
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
-#! /bin/sh
-
-# Extract macro arguments from autotools input with GNU M4.
-# Written by Gary V. Vaughan, 2010
-#
-# Copyright (C) 2010-2014, 2017 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# Make sure we've evaluated scripts we depend on.
-test -z "$progpath" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/funclib.sh
-test extract-trace = "$progname" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/options-parser
-
-# Set a version string.
-scriptversion=2014-01-04.01; # UTC
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Run './extract-trace --help' for help with using this script from the
-# command line.
-#
-# Or source first 'options-parser' and then this file into your own
-# scripts in order to make use of the function and variable framework
-# they define, and also to avoid the overhead of forking to run this
-# script in its own process on every call.
-
-
-
-## ----------------- ##
-## Helper functions. ##
-## ----------------- ##
-
-# This section contains the helper functions used by the rest of
-# 'extract-trace'.
-
-
-# func_autoconf_configure MAYBE-CONFIGURE-FILE
-# --------------------------------------------
-# Ensure that MAYBE-CONFIGURE-FILE is the name of a file in the current
-# directory that contains an uncommented call to AC_INIT.
-func_autoconf_configure ()
-{
- $debug_cmd
-
- _G_sed_no_comment='
- s|#.*$||
- s|^dnl .*$||
- s| dnl .*$||'
- _G_ac_init=
-
- # If we were passed a genuine file, make sure it calls AC_INIT.
- test -f "$1" \
- && _G_ac_init=`$SED "$_G_sed_no_comment" "$1" |$GREP AC_INIT`
-
- # Otherwise it is not a genuine Autoconf input file.
- test -n "$_G_ac_init"
- _G_status=$?
-
- test 0 -ne "$_G_status" \
- && func_verbose "'$1' not using Autoconf"
-
- (exit $_G_status)
-}
-
-
-# func_find_tool ENVVAR NAMES...
-# ------------------------------
-# Search for a required program. Use the value of ENVVAR, if set,
-# otherwise find the first of the NAMES that can be run (i.e.,
-# supports --version). If found, set ENVVAR to the program name,
-# die otherwise.
-func_find_tool ()
-{
- $debug_cmd
-
- _G_find_tool_envvar=$1
- shift
- _G_find_tool_names=$@
- eval "_G_find_tool_res=\$$_G_find_tool_envvar"
- if test -n "$_G_find_tool_res"; then
- _G_find_tool_error_prefix="\$$find_tool_envvar: "
- else
- for _G_prog
- do
- if func_tool_version_output $_G_prog >/dev/null; then
- _G_find_tool_res=$_G_prog
- break
- fi
- done
- fi
- if test -n "$_G_find_tool_res"; then
- func_tool_version_output >/dev/null $_G_find_tool_res "\
-${_G_find_tool_error_prefix}Cannot run '$_G_find_tool_res --version'"
-
- # Make sure the result is exported to the environment for children
- # to use.
- eval "$_G_find_tool_envvar=\$_G_find_tool_res"
- eval "export $_G_find_tool_envvar"
- else
- func_error "\
-One of these is required:
- $_G_find_tool_names"
- fi
-}
-
-
-# func_tool_version_output CMD [FATAL-ERROR-MSG]
-# ----------------------------------------------
-# Attempt to run 'CMD --version', discarding errors. The output can be
-# ignored by redirecting stdout, and this function used simply to test
-# whether the command exists and exits normally when passed a
-# '--version' argument.
-# When FATAL-ERROR-MSG is given, then this function will display the
-# message and exit if running 'CMD --version' returns a non-zero exit
-# status.
-func_tool_version_output ()
-{
- $debug_cmd
-
- _G_cmd=$1
- _G_fatal_error_msg=$2
-
- # Some tools, like 'git2cl' produce thousands of lines of output
- # unless stdin is /dev/null - in that case we want to return
- # successfully without saving all of that output. Other tools,
- # such as 'help2man' exit with a non-zero status when stdin comes
- # from /dev/null, so we re-execute without /dev/null if that
- # happens. This means that occasionally, the output from both calls
- # ends up in the result, but the alternative would be to discard the
- # output from one call, and hope the other produces something useful.
- { $_G_cmd --version </dev/null || $_G_cmd --version; } 2>/dev/null
- _G_status=$?
-
- test 0 -ne "$_G_status" && test -n "$_G_fatal_error_msg" \
- && func_fatal_error "$_G_fatal_error_msg"
-
- (exit $_G_status)
-}
-
-
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
-
-# This section contains definitions for functions that each ensure a
-# particular resource (a file, or a non-empty configuration variable for
-# example) is available, and if appropriate to extract default values
-# from pertinent package files. Where a variable already has a non-
-# empty value (as set by the package's 'bootstrap.conf'), that value is
-# used in preference to deriving the default. Call them using their
-# associated 'require_*' variable to ensure that they are executed, at
-# most, once.
-#
-# It's entirely deliberate that calling these functions can set
-# variables that don't obey the namespace limitations obeyed by the rest
-# of this file, in order that that they be as useful as possible to
-# callers.
-
-
-# require_configure_ac
-# --------------------
-# Ensure that there is a 'configure.ac' or 'configure.in' file in the
-# current directory that contains an uncommented call to AC_INIT, and
-# that '$configure_ac' contains its name.
-require_configure_ac=func_require_configure_ac
-func_require_configure_ac ()
-{
- $debug_cmd
-
- test -z "$configure_ac" \
- && func_autoconf_configure configure.ac && configure_ac=configure.ac
- test -z "$configure_ac" \
- && func_autoconf_configure configure.in && configure_ac=configure.in
- test -z "$configure_ac" \
- || func_verbose "found '$configure_ac'"
-
- require_configure_ac=:
-}
-
-
-# require_gnu_m4
-# --------------
-# Search for GNU M4, and export it in $M4.
-require_gnu_m4=func_require_gnu_m4
-func_require_gnu_m4 ()
-{
- $debug_cmd
-
- test -n "$M4" || {
- # Find the first m4 binary that responds to --version.
- func_find_tool M4 gm4 gnum4 m4
- }
-
- test -n "$M4" || func_fatal_error "\
-Please install GNU M4, or 'export M4=/path/to/gnu/m4'."
-
- func_verbose "export M4='$M4'"
-
- # Make sure the search result is visible to subshells
- export M4
-
- require_gnu_m4=:
-}
-
-
-## --------------- ##
-## Core functions. ##
-## --------------- ##
-
-# This section contains the high level functions used when calling this
-# file as a script. 'func_extract_trace' is probably the only one that you
-# won't want to replace if you source this file into your own script.
-
-
-# func_extract_trace MACRO_NAMES [FILENAME]...
-# --------------------------------------------
-# set '$func_extract_trace_result' to a colon delimited list of arguments
-# to any of the comma separated list of MACRO_NAMES in FILENAME. If no
-# FILENAME is given, then '$configure_ac' is assumed.
-func_extract_trace ()
-{
- $debug_cmd
-
- $require_configure_ac
- $require_gnu_m4
-
- _G_m4_traces=`$ECHO "--trace=$1" |$SED 's%,% --trace=%g'`
- _G_re_macros=`$ECHO "($1)" |$SED 's%,%|%g'`
- _G_macros="$1"; shift
- test $# -gt 0 || {
- set dummy $configure_ac
- shift
- }
-
- # Generate an error if the first file is missing
- <"$1"
-
- # Sadly, we can't use 'autom4te' tracing to extract macro arguments,
- # because it complains about things we want to ignore at bootstrap
- # time - like missing m4_include files; AC_PREREQ being newer than
- # the installed autoconf; and returns nothing when tracing
- # 'AM_INIT_AUTOMAKE' when aclocal hasn't been generated yet.
- #
- # The following tries to emulate a less persnickety version of (and
- # due to not having to wait for Perl startup on every invocation,
- # it's probably faster too):
- #
- # autom4te --language=Autoconf --trace=$my_macro:\$% "$@"
- #
- # First we give a minimal set of macro declarations to M4 to prime
- # it for reading Autoconf macros, while still providing some of the
- # functionality generally used at m4-time to supply dynamic
- # arguments to Autocof functions, but without following
- # 'm4_s?include' files.
- _G_mini='
- # Initialisation.
- m4_changequote([,])
- m4_define([m4_copy], [m4_define([$2], m4_defn([$1]))])
- m4_define([m4_rename], [m4_copy([$1], [$2])m4_undefine([$1])])
-
- # Disable these macros.
- m4_undefine([m4_dnl])
- m4_undefine([m4_include])
- m4_undefine([m4_m4exit])
- m4_undefine([m4_m4wrap])
- m4_undefine([m4_maketemp])
-
- # Copy and rename macros not handled by "m4 --prefix".
- m4_define([dnl], [m4_builtin([dnl])])
- m4_copy([m4_define], [m4_defun])
- m4_rename([m4_ifelse], [m4_if])
- m4_ifdef([m4_mkstemp], [m4_undefine([m4_mkstemp])])
- m4_rename([m4_patsubst], [m4_bpatsubst])
- m4_rename([m4_regexp], [m4_bregexp])
-
- # "m4sugar.mini" - useful m4-time macros for dynamic arguments.
- # If we discover packages that need more m4 macros defined in
- # order to bootstrap correctly, add them here:
- m4_define([m4_bmatch],
- [m4_if([$#], 0, [], [$#], 1, [], [$#], 2, [$2],
- [m4_if(m4_bregexp([$1], [$2]), -1,
- [$0([$1], m4_shift3($@))], [$3])])])
- m4_define([m4_ifndef], [m4_ifdef([$1], [$3], [$2])])
- m4_define([m4_ifset],
- [m4_ifdef([$1], [m4_ifval(m4_defn([$1]), [$2], [$3])], [$3])])
- m4_define([m4_require], [$1])
- m4_define([m4_shift3], [m4_shift(m4shift(m4shift($@)))])
-
- # "autoconf.mini" - things from autoconf macros we care about.
- m4_copy([m4_defun], [AC_DEFUN])
-
- # Dummy definitions for the macros we want to trace.
- # AM_INIT_AUTOMAKE at least produces no trace without this.
- '
-
- _G_save=$IFS
- IFS=,
- for _G_macro in $_G_macros; do
- IFS=$_G_save
- func_append _G_mini "AC_DEFUN([$_G_macro])$nl"
- done
- IFS=$_G_save
-
- # We discard M4's stdout, but the M4 trace output from reading our
- # "autoconf.mini" followed by any other files passed to this
- # function is then scanned by sed to transform it into a colon
- # delimited argument list assigned to a shell variable.
- _G_transform='s|#.*$||; s|^dnl .*$||; s| dnl .*$||;'
-
- # Unfortunately, alternation in regexp addresses doesn't work in at
- # least BSD (and hence Mac OS X) sed, so we have to append a capture
- # and print block for each traced macro to the sed transform script.
- _G_save=$IFS
- IFS=,
- for _G_macro in $_G_macros; do
- IFS=$_G_save
- func_append _G_transform '
- /^m4trace: -1- '"$_G_macro"'/ {
- s|^m4trace: -1- '"$_G_macro"'[([]*||
- s|], [[]|:|g
- s|[])]*$|:|
- s|\(.\):$|\1|
- p
- }'
- done
- IFS=$_G_save
-
- # Save the command pipeline results for further use by callers of
- # this function.
- func_extract_trace_result=`$ECHO "$_G_mini" \
- |$M4 -daq --prefix $_G_m4_traces - "$@" 2>&1 1>/dev/null \
- |$SED -n -e "$_G_transform"`
-}
-
-
-# func_extract_trace_first MACRO_NAMES [FILENAME]...
-# --------------------------------------------------
-# Exactly like func_extract_trace, except that only the first argument
-# to the first invocation of one of the comma separated MACRO_NAMES is
-# returned in '$func_extract_trace_first_result'.
-func_extract_trace_first ()
-{
- $debug_cmd
-
- func_extract_trace ${1+"$@"}
- func_extract_trace_first_result=`$ECHO "$func_extract_trace_result" \
- |$SED -e 's|:.*$||g' -e 1q`
-}
-
-
-# func_main [ARG]...
-# ------------------
-func_main ()
-{
- $debug_cmd
-
- # Configuration.
- usage='$progname MACRO_NAME FILE [...]'
-
- long_help_message='
-The first argument to this program is the name of an autotools macro
-whose arguments you want to extract by examining the files listed in the
-remaining arguments using the same tool that Autoconf and Automake use,
-GNU M4.
-
-The arguments are returned separated by colons, with each traced call
-on a separate line.'
-
- # Option processing.
- func_options "$@"
- eval set dummy "$func_options_result"; shift
-
- # Validate remaining non-option arguments.
- test $# -gt 1 \
- || func_fatal_help "not enough arguments"
-
- # Pass non-option arguments to extraction function.
- func_extract_trace "$@"
-
- # Display results.
- test -n "$func_extract_trace_result" \
- && $ECHO "$func_extract_trace_result"
-
- # The End.
- exit $EXIT_SUCCESS
-}
-
-
-## --------------------------- ##
-## Actually perform the trace. ##
-## --------------------------- ##
-
-# Only call 'func_main' if this script was called directly.
-test extract-trace = "$progname" && func_main "$@"
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "20/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
-
-# Set a version string for *this* script.
-scriptversion=2014-11-04.13; # UTC
-
-
-## ------------------- ##
-## Hookable functions. ##
-## ------------------- ##
-
-# After 'bootstrap.conf' has been sourced, execution proceeds by calling
-# 'func_bootstrap'. Wherever a function is decorated with
-# 'func_hookable func_name', you will find a matching 'func_run_hooks
-# func_name', which executes all functions added with 'func_add_hook
-# func_name my_func'.
-#
-# You might notice that many of these functions begin with a series of
-# '$require_foo' lines. See the docu-comments at the start of the
-# 'Resource management' section for a description of what these are.
-
-
-# func_bootstrap [ARG]...
-# -----------------------
-# All the functions called inside func_bootstrap are hookable. See the
-# the individual implementations for details.
-func_bootstrap ()
-{
- $debug_cmd
-
- # Save the current positional parameters to prevent them being
- # corrupted by calls to 'set' in 'func_init'.
- func_quote_for_eval ${1+"$@"}
- _G_saved_positional_parameters=$func_quote_for_eval_result
-
- # Initialisation.
- func_init
-
- # Option processing.
- eval func_options "$_G_saved_positional_parameters"
-
- # Post-option preparation.
- func_prep
-
- # Reconfigure the package.
- func_reconfigure
-
- # Ensure .version is up-to-date.
- func_update_dotversion
-
- # Finalisation.
- func_fini
-}
-
-
-# func_init
-# ---------
-# Any early initialisations can be hooked to this function. Consider
-# whether you can hook onto 'func_prep' instead, because if you hook
-# any slow to execute code in here, it will also add to the time before
-# './bootstrap --version' can respond.
-func_hookable func_init
-func_init ()
-{
- $debug_cmd
-
- func_run_hooks func_init
-}
-
-
-# func_prep
-# ---------
-# Function to perform preparation for remaining bootstrap process. If
-# your hooked code relies on the outcome of 'func_options' hook it here
-# rather than to 'func_init'.
-#
-# All the functions called inside func_prep are hookable. See the
-# individual implementations for details.
-func_hookable func_prep
-func_prep ()
-{
- $debug_cmd
-
- $require_buildtools_uptodate
- $require_checkout_only_file
-
- $require_gnulib_merge_changelog
-
- # Report the results of SED and GREP searches from funclib.sh.
- func_verbose "GREP='$GREP'"
- func_verbose "SED='$SED'"
-
- # fetch update files from the translation project
- func_update_translations
-
- func_run_hooks func_prep
-}
-
-
-# func_update_translations
-# ------------------------
-# Update package po files and translations.
-func_hookable func_update_translations
-func_update_translations ()
-{
- $debug_cmd
-
- $opt_skip_po || {
- test -d po && {
- $require_package
-
- func_update_po_files po $package || exit $?
- }
-
- func_run_hooks func_update_translations
- }
-}
-
-
-# func_reconfigure
-# ----------------
-# Reconfigure the current package by running the appropriate autotools in a
-# suitable order.
-func_hookable func_reconfigure
-func_reconfigure ()
-{
- $debug_cmd
-
- $require_automake_options
-
- # Automake (without 'foreign' option) requires that README exists.
- case " $automake_options " in
- " foreign ") ;;
- *) func_ensure_README ;;
- esac
-
- # Ensure ChangeLog presence.
- if test -n "$gnulib_modules"; then
- func_ifcontains "$gnulib_modules" gitlog-to-changelog \
- func_ensure_changelog
- else
- $require_gnulib_cache
- if $SED -n '/^gl_MODULES(\[/,/^])$/p' $gnulib_cache 2>/dev/null |
- func_grep_q gitlog-to-changelog
- then
- func_ensure_changelog
- fi
- fi
-
- # Released 'autopoint' has the tendency to install macros that have
- # been obsoleted in current 'gnulib', so run this before 'gnulib-tool'.
- func_autopoint
-
- # Autoreconf runs 'aclocal' before 'libtoolize', which causes spurious
- # warnings if the initial 'aclocal' is confused by the libtoolized
- # (or worse: out-of-date) macro directory.
- func_libtoolize
-
- # If you need to do anything after 'gnulib-tool' is done, but before
- # 'autoreconf' runs, you don't need to override this whole function,
- # because 'func_gnulib_tool' is hookable.
- func_gnulib_tool
-
- func_autoreconf
-
- func_run_hooks func_reconfigure
-}
-
-
-# func_gnulib_tool
-# ----------------
-# Run 'gnulib-tool' to fetch gnulib modules into the current package.
-#
-# It's assumed that since you are using gnulib's 'bootstrap' script,
-# you're also using gnulib elsewhere in your package. If not, then
-# you can replace this function in 'bootstrap.conf' with:
-#
-# func_gnulib_tool () { :; }
-#
-# (although the function returns immediately if $gnulib_tool is set to
-# true in any case).
-func_hookable func_gnulib_tool
-func_gnulib_tool ()
-{
- $debug_cmd
-
- $require_gnulib_tool
- $require_libtoolize
-
- test true = "$gnulib_tool" || {
- # bootstrap.conf written for gnulib bootstrap expects
- # gnulib_tool_option_extras to which --no-changelog is appended,
- # but libtool bootstrap expects you to append to gnulib_tool_options
- # so that you can override the --no-changelog default: make sure we
- # support both styles so users can migrate between them easily.
- gnulib_tool_all_options="$gnulib_tool_options $gnulib_tool_option_extras"
-
- if test -n "$gnulib_modules"; then
- $require_gnulib_cache
- $require_gnulib_tool_base_options
-
- gnulib_mode=--import
-
- # Try not to pick up any stale values from 'gnulib-cache.m4'.
- rm -f "$gnulib_cache"
-
- test -n "$gnulib_tool_base_options" \
- && func_append_uniq gnulib_tool_all_options " $gnulib_tool_base_options"
- test -n "$gnulib_mk" \
- && func_append_uniq gnulib_tool_all_options " --makefile-name=$gnulib_mk"
- test -n "$tests_base" && {
- func_append_uniq gnulib_tool_all_options " --tests-base=$tests_base"
- func_append_uniq gnulib_tool_all_options " --with-tests"
- }
- else
-
- # 'gnulib_modules' and others are cached in 'gnulib-cache.m4':
- # Use 'gnulib --update' to fetch gnulib modules.
- gnulib_mode=--update
- fi
-
- # Add a sensible default libtool option to gnulib_tool_options.
- # The embedded echo is to squash whitespace before globbing.
- case `echo " "$gnulib_tool_all_options" "` in
- *" --no-libtool "*|*" --libtool "*) ;;
- *) if test true = "$LIBTOOLIZE"; then
- func_append_uniq gnulib_tool_all_options " --no-libtool"
- else
- func_append_uniq gnulib_tool_all_options " --libtool"
- fi
- ;;
- esac
-
- $opt_copy || func_append_uniq gnulib_tool_all_options " --symlink"
-
- func_append_uniq gnulib_tool_all_options " $gnulib_mode"
- func_append gnulib_tool_all_options " $gnulib_modules"
-
- # The embedded echo is to squash whitespace before display.
- gnulib_cmd=`echo $gnulib_tool $gnulib_tool_all_options`
-
- func_show_eval "$gnulib_cmd" 'exit $?'
-
- # Use 'gnulib-tool --copy-file' to install non-module files.
- func_install_gnulib_non_module_files
- }
-
- func_run_hooks func_gnulib_tool
-}
-
-
-# func_fini
-# ---------
-# Function to perform all finalisation for the bootstrap process.
-func_hookable func_fini
-func_fini ()
-{
- $debug_cmd
-
- func_gettext_configuration
- func_clean_dangling_symlinks
- func_clean_unused_macros
- func_skip_po_recommendation
-
- func_run_hooks func_fini
-
- $require_bootstrap_uptodate
-
- func_echo "Done. Now you can run './configure'."
-}
-
-
-# func_gettext_configuration
-# --------------------------
-# Edit configuration values into po/Makevars.
-func_hookable func_gettext_configuration
-func_gettext_configuration ()
-{
- $debug_cmd
-
- $require_autopoint
-
- test true = "$AUTOPOINT" || {
- $require_copyright_holder
- $require_extra_locale_categories
- $require_package_bugreport
-
- # Escape xgettext options for sed Makevars generation below.
- # We have to delete blank lines in a separate script so that we don't
- # append \\\ to the penultimate line, and then delete the last empty
- # line, which messes up the variable substitution later in this
- # function. Note that adding a literal \\\ requires double escaping
- # here, once for the execution subshell, and again for the assignment,
- # which is why there are actually 12 (!!) backslashes in the script.
- _G_xgettext_options=`echo "$xgettext_options$nl" |$SED '/^$/d' |$SED '
- $b
- s|$| \\\\\\\\\\\\|'`
-
- # Create gettext configuration.
- func_echo "Creating po/Makevars from po/Makevars.template ..."
- $RM -f po/Makevars
- $SED '
- /^EXTRA_LOCALE_CATEGORIES *=/s|=.*|= '"$extra_locale_categories"'|
- /^COPYRIGHT_HOLDER *=/s|=.*|= '"$copyright_holder"'|
- /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$package_bugreport"'|
- /^XGETTEXT_OPTIONS *=/{
- s|$| \\|
- a\
- '"$_G_xgettext_options"' \\\
- $${end_of_xgettext_options+}
- }
- ' po/Makevars.template >po/Makevars || exit 1
- }
-
- func_run_hooks func_gettext_configuration
-}
-
-
-
-## --------------- ##
-## Core functions. ##
-## --------------- ##
-
-# This section contains the main functions called from the 'Hookable
-# functions' (shown above), and are the ones you're most likely
-# to want to replace with your own implementations in 'bootstrap.conf'.
-
-
-# func_autopoint
-# --------------
-# If this package uses gettext, then run 'autopoint'.
-func_autopoint ()
-{
- $debug_cmd
-
- $require_autopoint
-
- test true = "$AUTOPOINT" \
- || func_show_eval "$AUTOPOINT --force" 'exit $?'
-}
-
-
-# func_libtoolize
-# ---------------
-# If this package uses libtool, then run 'libtoolize'.
-func_libtoolize ()
-{
- $debug_cmd
-
- $require_libtoolize
-
- test true = "$LIBTOOLIZE" || {
- _G_libtoolize_options=
- $opt_copy && func_append _G_libtoolize_options " --copy"
- $opt_force && func_append _G_libtoolize_options " --force"
- $opt_verbose || func_append _G_libtoolize_options " --quiet"
- func_show_eval "$LIBTOOLIZE$_G_libtoolize_options" 'exit $?'
- }
-}
-
-
-# func_gnulib_tool_copy_file SRC DEST
-# -----------------------------------
-# Copy SRC, a path relative to the gnulib sub-tree, to DEST, a path
-# relative to the top-level source directory using gnulib-tool so that
-# any patches or replacements in $local_gl_dir are applied.
-func_gnulib_tool_copy_file ()
-{
- $debug_cmd
-
- $require_gnulib_tool
- $require_patch
-
- if test true = "$gnulib_tool"; then
- # If gnulib-tool is not available (e.g. bootstrapping in a
- # distribution tarball), make sure that at least we have some
- # version of the required file already in place.
- test -f "$2" || func_fatal_error "\
-Can't find, copy or download '$2', a required
-gnulib supplied file, please provide the location of a
-complete 'gnulib' tree by setting 'gnulib_path' in your
-'bootstrap.conf' or with the '--gnulib-srcdir' option -
-or else specify the location of your 'git' binary by
-setting 'GIT' in the environment so that a fresh
-'gnulib' submodule can be cloned."
- else
- $require_gnulib_copy_cmd
-
- $gnulib_copy_cmd $1 $2 2>/dev/null || {
- $require_gnulib_path
-
- func_error "'$gnulib_path/$1' does not exist"
- return 1
- }
- fi
-}
-
-
-# func_install_gnulib_non_module_files
-# ------------------------------------
-# Get additional non-module files from gnulib, overriding existing files.
-func_install_gnulib_non_module_files ()
-{
- $debug_cmd
-
- $require_build_aux
- $require_gnulib_tool
-
- test -n "$gnulib_non_module_files" && {
- maybe_exit_cmd=:
-
- for file in $gnulib_non_module_files; do
- case $file in
- */COPYING*) dest=COPYING;;
- */INSTALL) dest=INSTALL;;
- build-aux/missing) dest=
- func_warning settings "\
-Please remove build-aux/missing from gnulib_module_files in
-'bootstrap.conf', as it may clash with Automake's version."
- ;;
- build-aux/*) dest=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;;
- *) dest=$file;;
- esac
-
- # Be sure to show all copying errors before bailing out
- test -z "$dest" \
- || func_gnulib_tool_copy_file "$file" "$dest" \
- || maybe_exit_cmd="exit $EXIT_FAILURE"
- done
-
- $maybe_exit_cmd
- }
-}
-
-
-# func_ensure_changelog
-# ---------------------
-# Even with 'gitlog-to-changelog' generated ChangeLogs, automake
-# will not run to completion with no ChangeLog file.
-func_ensure_changelog ()
-{
- $debug_cmd
-
- test -f ChangeLog && mv -f ChangeLog ChangeLog~
-
- cat >ChangeLog <<'EOT'
-## ---------------------- ##
-## DO NOT EDIT THIS FILE! ##
-## ---------------------- ##
-
-ChangeLog is generated by gitlog-to-changelog.
-EOT
-
- _G_message="creating dummy 'ChangeLog'"
- test -f ChangeLog~ \
- && func_append _G_message ' (backup in ChangeLog~)'
- func_verbose "$_G_message"
-
- return 0
-}
-
-
-# func_ensure_README
-# ------------------
-# Without AM_INIT_AUTOMAKE([foreign]), automake will not run to
-# completion with no README file, even though README.md or README.txt
-# is often preferable.
-func_ensure_README ()
-{
- $debug_cmd
-
- test -f README || {
- _G_README=
- for _G_readme in README.txt README.md README.rst; do
- test -f "$_G_readme" && break
- done
-
- test -f "$_G_readme" && $LN_S $_G_readme README
- func_verbose "$LN_S $_G_readme README"
- }
-
- return 0
-}
-
-
-# func_autoreconf [SUBDIR]
-# ------------------------
-# Being careful not to re-run 'autopoint' or 'libtoolize', and not to
-# try to run 'autopoint', 'libtoolize' or 'autoheader' on packages that
-# don't use them, defer to 'autoreconf' for execution of the remaining
-# autotools to bootstrap this package.
-#
-# Projects with multiple trees to reconfigure can hook another call to
-# this function onto func_reconfigure:
-#
-# my_autoreconf_foo ()
-# {
-# func_autoreconf foo
-# }
-# func_add_hook func_reconfigure my_autoreconf_foo
-func_autoreconf ()
-{
- $debug_cmd
-
- $require_autoheader
- $require_build_aux # automake and others put files in here
- $require_macro_dir # aclocal and others put files in here
-
- # We ran these manually already, and autoreconf won't exec ':'
- save_AUTOPOINT=$AUTOPOINT; AUTOPOINT=true
- save_LIBTOOLIZE=$LIBTOOLIZE; LIBTOOLIZE=true
-
- _G_autoreconf_options=
- $opt_copy || func_append _G_autoreconf_options " --symlink"
- $opt_force && func_append _G_autoreconf_options " --force"
- $opt_verbose && func_append _G_autoreconf_options " --verbose"
- func_show_eval "$AUTORECONF$_G_autoreconf_options --install${1+ $1}" 'exit $?'
-
- AUTOPOINT=$save_AUTOPOINT
- LIBTOOLIZE=$save_LIBTOOLIZE
-}
-
-
-# func_check_configuration VARNAME [CONFIGURE_MACRO]
-# --------------------------------------------------
-# Exit with a suitable diagnostic for an important configuration change
-# that needs to be made before bootstrap can run correctly.
-func_check_configuration ()
-{
- $debug_cmd
-
- $require_configure_ac
-
- eval 'test -n "$'$1'"' || {
- _G_error_msg="please set '$1' in 'bootstrap.conf'"
- if test -n "$configure_ac" && test -n "$2"; then
- func_append _G_error_msg "
-or add the following (or similar) to your '$configure_ac':
-$2"
- fi
-
- func_fatal_error "$_G_error_msg"
- }
-}
-
-
-# func_clean_dangling_symlinks
-# ----------------------------
-# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
-# gnulib-populated directories. Such .m4 files would cause aclocal to
-# fail. The following requires GNU find 4.2.3 or newer. Considering
-# the usual portability constraints of this script, that may seem a very
-# demanding requirement, but it should be ok. Ignore any failure,
-# which is fine, since this is only a convenience to help developers
-# avoid the relatively unusual case where a symlinked-to .m4 file is
-# git-removed from gnulib between successive runs of this script.
-func_clean_dangling_symlinks ()
-{
- $debug_cmd
-
- $require_macro_dir
- $require_source_base
-
- func_verbose "cleaning dangling symlinks"
-
- find "$macro_dir" "$source_base" \
- -depth \( -name '*.m4' -o -name '*.[ch]' \) \
- -type l -xtype l -delete > /dev/null 2>&1
-}
-
-
-# func_clean_unused_macros
-# ------------------------
-# Autopoint can result in over-zealously adding macros into $macro_dir
-# even though they are not actually used, for example tests to help
-# build the 'intl' directory even though you have specified
-# 'AM_GNU_GETTEXT([external])' in your configure.ac. This function
-# looks removes any macro files that can be found in gnulib, but
-# are not 'm4_include'd by 'aclocal.m4'.
-func_clean_unused_macros ()
-{
- $debug_cmd
-
- $require_gnulib_path
- $require_macro_dir
-
- test -n "$gnulib_path" && test -f aclocal.m4 && {
- aclocal_m4s=`find . -name aclocal.m4 -print`
-
- # We use 'ls|grep' instead of 'ls *.m4' to avoid exceeding
- # command line length limits in some shells.
- for file in `cd "$macro_dir" && ls -1 |$GREP '\.m4$'`; do
-
- # Remove a macro file when aclocal.m4 does not m4_include it...
- func_grep_q 'm4_include([[]'$macro_dir/$file'])' $aclocal_m4s \
- || test ! -f "$gnulib_path/m4/$file" || {
-
- # ...and there is an identical file in gnulib...
- if func_cmp_s "$gnulib_path/m4/$file" "$macro_dir/$file"; then
-
- # ...and it's not in the precious list ('echo' is needed
- # here to squash whitespace for the match expression).
- case " "`echo $gnulib_precious`" " in
- *" $file "*) ;;
- *) rm -f "$macro_dir/$file"
- func_verbose \
- "removing unused gnulib file '$macro_dir/$file'"
- esac
- fi
- }
- done
- }
-}
-
-
-# func_skip_po_recommendation
-# ---------------------------
-# If there is a po directory, and '--skip-po' wasn't passed, let the
-# user know that they can use '--skip-po' on subsequent invocations.
-func_skip_po_recommendation ()
-{
- $debug_cmd
-
- test ! -d po \
- || $opt_skip_po \
- || func_warning recommend "\
-If your pofiles are up-to-date, you can rerun bootstrap
-as '$progname --skip-po' to avoid redownloading."
-}
-
-
-# func_update_dotversion
-# ----------------------
-# Even with 'gitlog-to-changelog' generated ChangeLogs, automake
-# will not run to completion with no ChangeLog file.
-func_update_dotversion ()
-{
- $debug_cmd
-
- test -f "$build_aux/git-version-gen" && {
- _G_message="updating .version"
- test -f .version && {
- mv .version .version~
- func_append _G_message " (backup in .version~)"
- }
- func_verbose "updating .version"
-
- $build_aux/git-version-gen dummy-arg > .version
- }
-}
-
-
-
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
-
-# This section contains definitions for functions that each ensure a
-# particular resource (a file, or a non-empty configuration variable for
-# example) is available, and if appropriate to extract default values
-# from pertinent package files. Where a variable already has a non-
-# empty value (as set by the package's 'bootstrap.conf'), that value is
-# used in preference to deriving the default. Call them using their
-# associated 'require_*' variable to ensure that they are executed, at
-# most, once.
-
-
-# require_checkout_only_file
-# --------------------------
-# Bail out if this package only bootstraps properly from a repository
-# checkout.
-require_checkout_only_file=func_require_checkout_only_file
-func_require_checkout_only_file ()
-{
- $debug_cmd
-
- $opt_force || {
- test -n "$checkout_only_file" && test ! -f "$checkout_only_file" \
- && func_fatal_error "\
-Bootstrapping from a non-checked-out distribution is risky.
-If you wish to bootstrap anyway, use the '--force' option."
- }
-
- require_checkout_only_file=:
-}
-
-
-# require_aclocal_amflags
-# -----------------------
-# Ensure '$aclocal_amflags' has a sensible default, extracted from
-# 'Makefile.am' if necessary.
-require_aclocal_amflags=func_require_aclocal_amflags
-func_require_aclocal_amflags ()
-{
- $debug_cmd
-
- $require_makefile_am
-
- _G_sed_extract_aclocal_amflags='s|#.*$||
- /^[ ]*ACLOCAL_AMFLAGS[ ]*=/ {
- s|^.*=[ ]*\(.*\)|aclocal_amflags="\1"|
- p
- }'
-
- _G_aclocal_flags_cmd=`$SED -n "$_G_sed_extract_aclocal_amflags" \
- "$makefile_am"`
- eval "$_G_aclocal_flags_cmd"
-
- func_verbose "ACLOCAL_AMFLAGS='$aclocal_amflags'"
-
- require_aclocal_amflags=:
-}
-
-
-# require_autoheader
-# ------------------
-# Skip autoheader if it's not needed.
-require_autoheader=func_require_autoheader
-func_require_autoheader ()
-{
- $debug_cmd
-
- test true = "$AUTOHEADER" || {
- func_extract_trace AC_CONFIG_HEADERS
- test -n "$func_extract_trace_result" \
- || func_extract_trace AC_CONFIG_HEADER
-
- test -n "$func_extract_trace_result" || {
- AUTOHEADER=true
-
- func_verbose "export AUTOHEADER='$AUTOHEADER'"
-
- # Make sure the search result is visible to subshells
- export AUTOHEADER
- }
- }
-
- require_autoheader=:
-}
-
-
-# require_automake_options
-# ------------------------
-# Extract options from AM_AUTOMAKE_INIT.
-require_automake_options=func_require_automake_options
-func_require_automake_options ()
-{
- $debug_cmd
-
- func_extract_trace AM_INIT_AUTOMAKE
- automake_options=$func_extract_trace_result
-
- require_automake_options=:
-}
-
-
-# require_autopoint
-# -----------------
-# Skip autopoint if it's not needed.
-require_autopoint=func_require_autopoint
-func_require_autopoint ()
-{
- $debug_cmd
-
- test true = "$AUTOPOINT" || {
- func_extract_trace AM_GNU_GETTEXT_VERSION
-
- test -n "$func_extract_trace_result" || {
- AUTOPOINT=true
-
- func_verbose "export AUTOPOINT='$AUTOPOINT'"
-
- # Make sure the search result is visible to subshells
- export AUTOPOINT
- }
- }
-
- require_autopoint=:
-}
-
-
-# require_bootstrap_uptodate
-# --------------------------
-# Complain if the version of bootstrap in the gnulib directory differs
-# from the one we are running.
-require_bootstrap_uptodate=func_require_bootstrap_uptodate
-func_require_bootstrap_uptodate ()
-{
- $debug_cmd
-
- $require_build_aux
-
- _G_bootstrap_sources="
- $build_aux/bootstrap.in
- $build_aux/extract-trace
- $build_aux/funclib.sh
- $build_aux/options-parser
- "
-
- _G_missing_bootstrap_sources=false
- for _G_src in $_G_bootstrap_sources; do
- test -f "$_G_src" || _G_missing_bootstrap_sources=:
- done
-
- if $_G_missing_bootstrap_sources; then
- func_warning upgrade "\
-Please add bootstrap to your gnulib_modules list in
-'bootstrap.conf', so that I can tell you when there are
-updates available."
- else
- rm -f bootstrap.new
- $build_aux/inline-source $build_aux/bootstrap.in > bootstrap.new
-
- if func_cmp_s "$progpath" bootstrap.new; then
- rm -f bootstrap.new
- func_verbose "bootstrap script up to date"
- else
- chmod 555 bootstrap.new
- func_warning upgrade "\
-An updated bootstrap script has been generated for you in
-'bootstrap.new'. After you've verified that you want
-the changes, you can update with:
- mv -f bootstrap.new $progname
- ./$progname
-
-Or you can disable this check permanently by adding the
-following to 'bootstrap.conf':
- require_bootstrap_uptodate=:"
- fi
- fi
-
- require_bootstrap_uptodate=:
-}
-
-
-# require_build_aux
-# -----------------
-# Ensure that '$build_aux' is set, and if it doesn't already point to an
-# existing directory, create one.
-require_build_aux=func_require_build_aux
-func_require_build_aux ()
-{
- $debug_cmd
-
- test -n "$build_aux" || {
- func_extract_trace_first AC_CONFIG_AUX_DIR
- build_aux=$func_extract_trace_first_result
- func_check_configuration build_aux \
- "AC_CONFIG_AUX_DIR([name of a directory for build scripts])"
-
- func_verbose "build_aux='$build_aux'"
- }
-
- $require_vc_ignore_files
-
- # If the build_aux directory doesn't exist, create it now, and mark it
- # as ignored for the VCS.
- if test ! -d "$build_aux"; then
- func_show_eval "mkdir '$build_aux'"
-
- test -n "$vc_ignore_files" \
- || func_insert_if_absent "$build_aux" $vc_ignore_files
- fi
-
- require_build_aux=:
-}
-
-
-# require_buildreq_autobuild
-# --------------------------
-# Try to find whether the bootstrap requires autobuild.
-require_buildreq_autobuild=func_require_buildreq_autobuild
-func_require_buildreq_autobuild ()
-{
- $debug_cmd
-
- $require_macro_dir
-
- test -f "$macro_dir/autobuild.m4" \
- || printf '%s\n' "$buildreq" |func_grep_q '^[ ]*autobuild' \
- || {
- func_extract_trace AB_INIT
- test -n "$func_extract_trace_result" && {
- func_append buildreq 'autobuild - http://josefsson.org/autobuild/
-'
- func_verbose "auto-adding 'autobuild' to build requirements"
- }
- }
-
- require_buildreq_autobuild=:
-}
-
-
-# require_buildreq_autoconf
-# require_buildreq_autopoint
-# require_buildreq_libtoolize
-# ---------------------------
-# Try to find the minimum compatible version of autoconf/libtool
-# required to bootstrap successfully, and add it to '$buildreq'.
-for tool in autoconf libtoolize autopoint; do
- b=$tool
- v=require_buildreq_${tool}
- f=func_$v
- case $tool in
- autoconf) m=AC_PREREQ ;;
- libtoolize) m=LT_PREREQ; b=libtool ;;
- autopoint) m=AM_GNU_GETTEXT_VERSION b=gettext ;;
- esac
-
- eval $v'='$f'
- '$f' ()
- {
- $debug_cmd
-
- # The following is ignored if undefined, but might be necessary
- # in order for `func_find_tool` to run.
- ${require_'$tool'-:}
-
- printf '\''%s\n'\'' "$buildreq" |func_grep_q '\''^[ ]*'$tool\'' || {
- func_extract_trace '$m'
- _G_version=$func_extract_trace_result
- test -n "$_G_version" && {
- func_append buildreq "\
- '$tool' $_G_version http://www.gnu.org/s/'$b'
-"
- func_verbose \
- "auto-adding '\'$tool'-$_G_version'\'' to build requirements"
- }
- }
-
- '$v'=:
- }
-'
-done
-
-
-# require_buildreq_automake
-# -------------------------
-# Try to find the minimum compatible version of automake required to
-# bootstrap successfully, and add it to '$buildreq'.
-require_buildreq_automake=func_require_buildreq_automake
-func_require_buildreq_automake ()
-{
- $debug_cmd
-
- # if automake is not already listed in $buildreq...
- printf '%s\n' "$buildreq" |func_grep_q automake || {
- func_extract_trace AM_INIT_AUTOMAKE
-
- # ...and AM_INIT_AUTOMAKE is declared...
- test -n "$func_extract_trace_result" && {
- automake_version=`$ECHO "$func_extract_trace_result" \
- |$SED -e 's|[^0-9]*||' -e 's| .*$||'`
- test -n "$automake_version" || automake_version=-
-
- func_append buildreq "\
- automake $automake_version http://www.gnu.org/s/automake
-"
- func_verbose \
- "auto-adding 'automake-$automake_version' to build requirements"
- }
- }
-
- require_buildreq_automake=:
-}
-
-
-# require_buildreq_patch
-# ----------------------
-# Automatically add a patch build-requirement if there are diff files
-# in $local_gl_dir.
-require_buildreq_patch=func_require_buildreq_patch
-func_require_buildreq_patch ()
-{
- $debug_cmd
-
- $require_local_gl_dir
-
- # This ensures PATCH is set appropriately by the time
- # func_check_versions enforces $buildreq.
- $require_patch
-
- # If patch is not already listed in $buildreq...
- printf '%s\n' "$buildreq" |func_grep_q '^[ ]*patch' || {
- # The ugly find invocation is necessary to exit with non-zero
- # status for old find binaries that don't support -exec fully.
- if test ! -d "$local_gl_dir" \
- || find "$local_gl_dir" -name "*.diff" -exec false {} \; ; then :
- else
- func_append buildreq 'patch - http://www.gnu.org/s/patch
-'
- fi
- }
-
- require_buildreq_patch=:
-}
-
-
-# require_buildtools_uptodate
-# ---------------------------
-# Ensure all the packages listed in BUILDREQS are available on the build
-# machine at the minimum versions or better.
-require_buildtools_uptodate=func_require_buildtools_uptodate
-func_require_buildtools_uptodate ()
-{
- $debug_cmd
-
- $require_buildreq_autobuild
- $require_buildreq_autoconf
- $require_buildreq_automake
- $require_buildreq_libtoolize
- $require_buildreq_autopoint
- $require_buildreq_patch
-
- test -n "$buildreq" && {
- _G_error_hdr=
-
- func_check_versions $buildreq
- $func_check_versions_result || {
- test -n "$buildreq_readme" \
- && test -f "$buildreq_readme" \
- && _G_error_hdr="\
-$buildreq_readme explains how to obtain these prerequisite programs:
-"
- func_strtable 0 11 12 36 \
- "Program" "Min_version" "Homepage" $buildreq
- func_fatal_error "$_G_error_hdr$func_strtable_result"
- }
- }
-
- require_buildtools_uptodate=:
-}
-
-
-# require_copyright_holder
-# ------------------------
-# Ensure there is a sensible non-empty default value in '$copyright_holder'.
-require_copyright_holder=func_require_copyright_holder
-func_require_copyright_holder ()
-{
- $debug_cmd
-
- test -n "$copyright_holder" || {
- copyright_holder='Free Software Foundation, Inc.'
- func_warning settings "\
-Please set copyright_holder explicitly in 'bootstrap.conf';
-defaulting to '$copyright_holder'."
- }
-
- require_copyright_holder=:
-}
-
-
-# require_doc_base
-# ----------------
-# Ensure doc_base has a sensible value, extracted from 'gnulib-cache.m4'
-# if possible, otherwise letting 'gnulib-tool' pick a default.
-require_doc_base=func_require_doc_base
-func_require_doc_base ()
-{
- $debug_cmd
-
- $require_gnulib_cache
-
- test -f "$gnulib_cache" && test -z "$doc_base" && {
- func_extract_trace_first "gl_DOC_BASE" "$gnulib_cache"
- doc_base=$func_extract_trace_first_result
-
- test -n "$doc_base" && func_verbose "doc_base='$doc_base'"
- }
-
- require_doc_base=:
-}
-
-
-# require_dotgitmodules
-# ---------------------
-# Ensure we have a '.gitmodules' file, with appropriate 'gnulib' settings.
-require_dotgitmodules=func_require_dotgitmodules
-func_require_dotgitmodules ()
-{
- $debug_cmd
-
- $require_git
-
- test true = "$GIT" || {
- # A gnulib entry in .gitmodules always takes precedence.
- _G_path=`$GIT config --file .gitmodules submodule.gnulib.path 2>/dev/null`
-
- test -n "$_G_path" || {
- $require_vc_ignore_files
-
- func_verbose "creating '.gitmodules'"
-
- # If the .gitmodules file doesn't exist, create it now, and mark
- # it as ignored for the VCS.
- test -n "$gnulib_path" || gnulib_path=gnulib
- test -n "$gnulib_url" || gnulib_url=git://git.sv.gnu.org/gnulib
-
- {
- echo '[submodule "gnulib"]'
- echo " path = $gnulib_path"
- echo " url = $gnulib_url"
- } >> .gitmodules
-
- test -n "$vc_ignore_files" \
- || func_insert_if_absent ".gitmodules" $vc_ignore_files
- }
- }
-
- require_dotgitmodules=:
-}
-
-
-# require_extra_locale_categories
-# -------------------------------
-# Ensure there is a default value in '$extra_locale_categories'
-require_extra_locale_categories=func_require_extra_locale_categories
-func_require_extra_locale_categories ()
-{
- $debug_cmd
-
- # Defaults to empty, so run with whatever value may have been set in
- # 'bootstrap.conf'.
- require_extra_locale_categories=:
-}
-
-
-# require_git
-# -----------
-# Ignore git if it's not available, or we're not in a git checkout tree.
-require_git=func_require_git
-func_require_git ()
-{
- $debug_cmd
-
- $opt_skip_git && GIT=true
-
- test true = "$GIT" || {
- if test -d .git/.; then
- ($GIT --version) >/dev/null 2>&1 || GIT=true
- fi
- }
-
- func_verbose "GIT='$GIT'"
-
- require_git=:
-}
-
-
-# require_gnulib_cache
-# --------------------
-# Ensure there is a non-empty default for '$gnulib_cache', and that it
-# names an existing file.
-require_gnulib_cache=func_require_gnulib_cache
-func_require_gnulib_cache ()
-{
- $debug_cmd
-
- $require_macro_dir
-
- test -n "$gnulib_cache" \
- || gnulib_cache=$macro_dir/gnulib-cache.m4
-
- func_verbose "found '$gnulib_cache'"
-
- require_gnulib_cache=:
-}
-
-
-# require_gnulib_copy_cmd
-# -----------------------
-# Only calculate the options for copying files with gnulib once.
-require_gnulib_copy_cmd=func_require_gnulib_copy_cmd
-func_require_gnulib_copy_cmd ()
-{
- $debug_cmd
-
- $require_gnulib_tool
- $require_gnulib_tool_base_options
-
- gnulib_copy_cmd="$gnulib_tool $gnulib_tool_base_options --copy-file"
- $opt_copy || func_append gnulib_copy_cmd " --symlink"
- $opt_quiet || func_append gnulib_copy_cmd " --verbose"
-
- require_gnulib_copy_cmd=:
-}
-
-
-# require_gnulib_merge_changelog
-# ------------------------------
-# See if we can use gnulib's git-merge-changelog merge driver.
-require_gnulib_merge_changelog=func_require_gnulib_merge_changelog
-func_require_gnulib_merge_changelog ()
-{
- $debug_cmd
-
- test -f ChangeLog && {
- $require_git
-
- func_grep_q '^\(/\|\)ChangeLog$' .gitignore || test true = "$GIT" || {
- if $GIT config merge.merge-changelog.driver >/dev/null; then
- :
- elif (git-merge-changelog --version) >/dev/null 2>&1; then
- func_echo "initializing git-merge-changelog driver"
- $GIT config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
- $GIT config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
- else
- func_warning recommend \
- "Consider installing git-merge-changelog from gnulib."
- fi
- }
- }
-
- require_gnulib_merge_changelog=:
-}
-
-
-# require_gnulib_mk
-# -----------------
-# Ensure gnulib_mk has a sensible value, extracted from 'gnulib-cache.m4'
-# if possible, otherwise letting 'gnulib-tool' pick a default.
-require_gnulib_mk=func_require_gnulib_mk
-func_require_gnulib_mk ()
-{
- $debug_cmd
-
- $require_gnulib_cache
-
- test -f "$gnulib_cache" && test -z "$gnulib_mk" && {
- func_extract_trace_first "gl_MAKEFILE_NAME" "$gnulib_cache"
- gnulib_mk=$func_extract_trace_first_result
-
- test -n "$gnulib_mk" && func_verbose "gnulib_mk='$gnulib_mk'"
- }
-
- require_gnulib_mk=:
-}
-
-
-# require_gnulib_name
-# -------------------
-# Ensure gnulib_name has a sensible value, extracted from 'gnulib-cache.m4'
-# if possible, otherwise letting 'gnulib-tool' pick a default.
-require_gnulib_name=func_require_gnulib_name
-func_require_gnulib_name ()
-{
- $debug_cmd
-
- $require_gnulib_cache
-
- test -f "$gnulib_cache" && test -z "$gnulib_name" && {
- func_extract_trace_first "gl_LIB" "$gnulib_cache"
- gnulib_name=$func_extract_trace_first_result
-
- test -n "$gnulib_name" && func_verbose "gnulib_name='$gnulib_name'"
- }
-
- require_gnulib_name=:
-}
-
-
-# require_gnulib_path
-# require_gnulib_url
-# -------------------
-# Ensure 'gnulib_path' and 'gnulib_url' are set.
-require_gnulib_path=func_require_dotgitmodules_parameters
-require_gnulib_url=func_require_dotgitmodules_parameters
-func_require_dotgitmodules_parameters ()
-{
- $debug_cmd
-
- $require_git
-
- test true = "$GIT" && {
- # If we can't find git (or if the user specified '--skip-git'),
- # then use an existing gnulib directory specified with
- # '--gnulib-srcdir' if possible.
- test -n "$gnulib_path" \
- || test ! -x "$opt_gnulib_srcdir/gnulib-tool" \
- || gnulib_path=$opt_gnulib_srcdir
- }
-
-
- $require_dotgitmodules
-
- test -f .gitmodules && {
- # Extract the parameters with sed, since git may be missing
- test -n "$gnulib_path" \
- || gnulib_path=`$SED -e '/^.submodule "gnulib".$/,${
- /[ ]*path *= */{
- s|[ ]*||g;s|^[^=]*=||;p
- }
- }
- d' .gitmodules |$SED 1q`
- test -n "$gnulib_url" \
- || gnulib_url=`$SED -e '/^.submodule "gnulib".$/,${
- /[ ]*url *= */{
- s|[ ]*||g;s|^[^=]*=||;p
- }
- }
- d' .gitmodules |$SED 1q`
-
- func_verbose "gnulib_path='$gnulib_path'"
- func_verbose "gnulib_url='$gnulib_url'"
- }
-
- require_gnulib_path=:
- require_gnulib_url=:
-}
-
-
-# require_gnulib_submodule
-# ------------------------
-# Ensure that there is a current gnulib submodule at '$gnulib_path'.
-require_gnulib_submodule=func_require_gnulib_submodule
-func_require_gnulib_submodule ()
-{
- $debug_cmd
-
- $require_git
-
- if test true = "$GIT"; then
- func_warning recommend \
- "No 'git' found; imported gnulib modules may be outdated."
- else
- $require_gnulib_path
- $require_gnulib_url
-
- if test -f .gitmodules && test -f "$gnulib_path/gnulib-tool"; then
- : All present and correct.
-
- elif test -n "$opt_gnulib_srcdir"; then
- # Older git can't clone into an empty directory.
- rmdir "$gnulib_path" 2>/dev/null
- func_show_eval "$GIT clone --reference '$opt_gnulib_srcdir' \
- '$gnulib_url' '$gnulib_path'" \
- || func_fatal_error "Unable to fetch gnulib submodule."
-
- # Without --gnulib-srcdir, and no existing checked out submodule, we
- # create a new shallow clone of the remote gnulib repository.
- else
- trap func_cleanup_gnulib 1 2 13 15
-
- shallow=
- $GIT clone -h 2>&1 |func_grep_q -- --depth \
- && shallow='--depth 365'
-
- func_show_eval "$GIT clone $shallow '$gnulib_url' '$gnulib_path'" \
- func_cleanup_gnulib
-
- # FIXME: Solaris /bin/sh will try to execute '-' if any of
- # these signals are caught after this.
- trap - 1 2 13 15
- fi
-
- # Make sure we've checked out the correct revision of gnulib.
- func_show_eval "$GIT submodule init -- $gnulib_path" \
- && func_show_eval "$GIT submodule update -- $gnulib_path" \
- || func_fatal_error "Unable to update gnulib submodule."
- fi
-
- require_gnulib_submodule=:
-}
-
-
-# require_gnulib_tool
-# -------------------
-# Ensure that '$gnulib_tool' is set, and points to an executable file,
-# or else fall back to using the binary 'true' if the main gnulib
-# files appear to have been imported already.
-require_gnulib_tool=func_require_gnulib_tool
-func_require_gnulib_tool ()
-{
- $debug_cmd
-
- test true = "$gnulib_tool" || {
- $require_gnulib_submodule
- $require_gnulib_path
-
- test -n "$gnulib_tool" \
- || gnulib_tool=$gnulib_path/gnulib-tool
-
- test -x "$gnulib_tool" || {
- gnulib_tool=true
- func_warning recommend \
- "No 'gnulib-tool' found; gnulib modules may be missing."
- }
-
- test true = "$gnulib_tool" \
- || func_verbose "found '$gnulib_tool'"
- }
-
- require_gnulib_tool=:
-}
-
-
-# require_gnulib_tool_base_options
-# --------------------------------
-# Ensure that '$gnulib_tool_base_options' contains all the base options
-# required according to user configuration from bootstrap.conf.
-require_gnulib_tool_base_options=func_require_gnulib_tool_base_options
-func_require_gnulib_tool_base_options ()
-{
- $debug_cmd
-
- $require_gnulib_tool
-
- gnulib_tool_base_options=
-
- test true = "$gnulib_tool" || {
- # 'gnulib_modules' and others are maintained in 'bootstrap.conf':
- # Use 'gnulib --import' to fetch gnulib modules.
- $require_build_aux
- test -n "$build_aux" \
- && func_append_uniq gnulib_tool_base_options " --aux-dir=$build_aux"
- $require_macro_dir
- test -n "$macro_dir" \
- && func_append_uniq gnulib_tool_base_options " --m4-base=$macro_dir"
- $require_doc_base
- test -n "$doc_base" \
- && func_append_uniq gnulib_tool_base_options " --doc-base=$doc_base"
- $require_gnulib_name
- test -n "$gnulib_name" \
- && func_append_uniq gnulib_tool_base_options " --lib=$gnulib_name"
- $require_local_gl_dir
- test -n "$local_gl_dir" \
- && func_append_uniq gnulib_tool_base_options " --local-dir=$local_gl_dir"
- $require_source_base
- test -n "$source_base" \
- && func_append_uniq gnulib_tool_base_options " --source-base=$source_base"
- }
-
- require_gnulib_tool_base_options=:
-}
-
-
-# require_libtoolize
-# ------------------
-# Skip libtoolize if it's not needed.
-require_libtoolize=func_require_libtoolize
-func_require_libtoolize ()
-{
- $debug_cmd
-
- # Unless we're not searching for libtool use by this package, set
- # LIBTOOLIZE to true if none of 'LT_INIT', 'AC_PROG_LIBTOOL' and
- # 'AM_PROG_LIBTOOL' are used in configure.
- test true = "$LIBTOOLIZE" || {
- func_extract_trace LT_INIT
- test -n "$func_extract_trace_result" || func_extract_trace AC_PROG_LIBTOOL
- test -n "$func_extract_trace_result" || func_extract_trace AM_PROG_LIBTOOL
- test -n "$func_extract_trace_result" || LIBTOOLIZE=true
- }
-
- test -n "$LIBTOOLIZE" || {
- # Find libtoolize, named glibtoolize in Mac Ports, but prefer
- # user-installed libtoolize to ancient glibtoolize shipped by
- # Apple with Mac OS X when Mac Ports is not installed.
- func_find_tool LIBTOOLIZE libtoolize glibtoolize
- }
-
- test -n "$LIBTOOLIZE" || func_fatal_error "\
-Please install GNU Libtool, or 'export LIBTOOLIZE=/path/to/libtoolize'."
-
- func_verbose "export LIBTOOLIZE='$LIBTOOLIZE'"
-
- # Make sure the search result is visible to subshells
- export LIBTOOLIZE
-
- require_libtoolize=:
-}
-
-
-# require_local_gl_dir
-# --------------------
-# Ensure local_gl_dir has a sensible value, extracted from 'gnulib-cache.m4'
-# if possible, otherwise letting 'gnulib-tool' pick a default.
-require_local_gl_dir=func_require_local_gl_dir
-func_require_local_gl_dir ()
-{
- $debug_cmd
-
- $require_gnulib_cache
-
- test -f "$gnulib_cache" && test -z "$local_gl_dir" && {
- func_extract_trace_first "gl_LOCAL_DIR" "$gnulib_cache"
- local_gl_dir=$func_extract_trace_first_result
-
- test -n "$local_gl_dir" && func_verbose "local_gl_dir='$local_gl_dir'"
- }
-
- require_local_gl_dir=:
-}
-
-
-# require_macro_dir
-# -----------------
-# Ensure that '$macro_dir' is set, and if it doesn't already point to an
-# existing directory, create one.
-require_macro_dir=func_require_macro_dir
-func_require_macro_dir ()
-{
- $debug_cmd
-
- # Sometimes this is stored in 'configure.ac'.
- test -n "$macro_dir" || {
- # AC_CONFIG_MACRO_DIRS takes a space delimited list of directories,
- # but we only care about the first one in bootstrap.
- func_extract_trace_first AC_CONFIG_MACRO_DIRS
- macro_dir=`expr "x$func_extract_trace_first_result" : 'x\([^ ]*\)'`
- }
- test -n "$macro_dir" || {
- func_extract_trace_first AC_CONFIG_MACRO_DIR
- macro_dir=$func_extract_trace_first_result
- }
-
- # Otherwise we might find it in 'Makefile.am'.
- test -n "$macro_dir" || {
- $require_aclocal_amflags
-
- # Take the argument following the first '-I', if any.
- _G_minus_I_seen=false
- for _G_arg in $aclocal_amflags; do
- case $_G_minus_I_seen,$_G_arg in
- :,*) macro_dir=$_G_arg; break ;;
- *,-I) _G_minus_I_seen=: ;;
- *,-I*) macro_dir=`expr x$_G_arg : 'x-I\(.*\)$'`; break ;;
- esac
- done
- }
-
- func_verbose "macro_dir='$macro_dir'"
-
- func_check_configuration macro_dir \
- "AC_CONFIG_MACRO_DIRS([name of a directory for configure m4 files])"
-
- $require_vc_ignore_files
-
- # If the macro_dir directory doesn't exist, create it now, and mark it
- # as ignored for the VCS.
- if test ! -d "$macro_dir"; then
- mkdir "$macro_dir" || func_permissions_error "$macro_dir"
-
- test -n "$vc_ignore_files" \
- || func_insert_if_absent "$macro_dir" $vc_ignore_files
- fi
-
- require_macro_dir=:
-}
-
-
-# require_makefile_am
-# -------------------
-# Ensure there is a 'Makefile.am' in the current directory.
-require_makefile_am=func_require_makefile_am
-func_require_makefile_am ()
-{
- $debug_cmd
-
- test -n "$makefile_am" \
- || makefile_am=Makefile.am
-
- <"$makefile_am"
-
- func_verbose "found '$makefile_am'"
-
- require_makefile_am=:
-}
-
-
-# require_package
-# ---------------
-# Ensure that '$package' contains a sensible default value.
-require_package=func_require_package
-func_require_package ()
-{
- $debug_cmd
-
- test -n "$package" || {
- $require_package_name
-
- package=`echo "$package_name" \
- |$SED -e 's/GNU //' \
- -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- }
-
- func_verbose "package='$package'"
-
- require_package=:
-}
-
-
-# require_package_bugreport
-# -------------------------
-# Ensure that this has a sensible value, extracted from 'configure.ac'
-# if appropriate (and possible!).
-require_package_bugreport=func_require_package_bugreport
-func_require_package_bugreport ()
-{
- $debug_cmd
-
- func_extract_trace AC_INIT
-
- save_ifs=$IFS
- IFS=:
- set dummy $func_extract_trace_result
- IFS=$save_ifs
- shift
-
- test -n "$package_bugreport" || package_bugreport=$3
- func_check_configuration package_bugreport \
- "AC_INIT([$package_name], [$package_version], [bug-$package@gnu.org])"
- func_verbose "package_bugreport='$package_bugreport'"
-
- require_package_bugreport=:
-}
-
-
-# require_package_name
-# --------------------
-# Ensure that this has a sensible value, extracted from 'configure.ac'
-# if appropriate (and possible!).
-require_package_name=func_require_package_name
-func_require_package_name ()
-{
- $debug_cmd
-
- func_extract_trace AC_INIT
-
- save_ifs=$IFS
- IFS=:
- set dummy $func_extract_trace_result
- IFS=$save_ifs
- shift
-
- test -n "$package_name" || package_name=$1
- func_check_configuration package_name \
- "AC_INIT([name of your package], [package version number])"
- func_verbose "package_name='$package_name'"
-
- require_package_name=:
-}
-
-
-# require_package_version
-# -----------------------
-# Ensure that this has a sensible value, extracted from 'configure.ac'
-# if appropriate (and possible!). While we might have set all the
-# parameters extracted from AC_INIT at once, 'package_version' in
-# particular is not necessarily available as early as the others, since
-# 'git-version-gen' is often involved, and until then we can't rely on
-# getting a correct version number from an AC_INIT extraction.
-require_package_version=func_require_package_version
-func_require_package_version ()
-{
- $debug_cmd
-
- func_extract_trace AC_INIT
-
- save_ifs=$IFS
- IFS=:
- set dummy $func_extract_trace_result
- IFS=$save_ifs
- shift
-
- test -n "$package_version" || package_version=$2
- test -n "$package_version" || {
- # The embedded echo is to squash whitespace before globbing.
- case " "`echo $gnulib_modules`" " in
- *" git-version-gen "*)
- func_fatal_error "\
-cannot \$require_package_version in bootstrap.conf before
-func_gnulib_tool has installed the 'git-version-gen' script."
- ;;
- *)
- func_check_configuration package_version \
- "AC_INIT([name of your package], [package version number])"
- ;;
- esac
- }
- func_verbose "package_version='$package_version'"
-
- require_package_version=:
-}
-
-
-# require_patch
-# -------------
-# Find patch, according to the PATCH environment variable, or else
-# searching the user's PATH.
-require_patch=func_require_patch
-func_require_patch ()
-{
- $debug_cmd
-
- test -n "$PATCH" || {
- # Find a patch program, preferring gpatch, which is usually better
- # than the vendor patch.
- func_find_tool PATCH gpatch patch
- }
-
- test -n "$PATCH" || func_fatal_error "\
-Please install GNU Patch, or 'export PATCH=/path/to/gnu/patch'."
-
- func_verbose "export PATCH='$PATCH'"
-
- # Make sure the search result is visible to subshells
- export PATCH
-
- require_patch=:
-}
-
-
-# require_source_base
-# -------------------
-# Ensure that source_base has a sensible value, extracted from
-# 'gnulib-cache.m4' if possible.
-require_source_base=func_require_source_base
-func_require_source_base ()
-{
- $debug_cmd
-
- $require_gnulib_cache
-
- test -f "$gnulib_cache" && test -z "$source_base" && {
- func_extract_trace_first "gl_SOURCE_BASE" "$gnulib_cache"
-
- source_base=$func_extract_trace_first_result
-
- func_verbose "source_base='$source_base'"
- }
-
- require_source_base=:
-}
-
-
-# require_vc_ignore_files
-# -----------------------
-# Ensure that '$vc_ignore' has been processed to list VCS ignore files
-# in '$vc_ignore_files'
-require_vc_ignore_files=func_require_vc_ignore_files
-func_require_vc_ignore_files ()
-{
- $debug_cmd
-
- test -n "$vc_ignore" || vc_ignore=auto
-
- if test auto = "$vc_ignore" && test -z "$vc_ignore_files"; then
- vc_ignore_files=
- test -d .git && vc_ignore_files=.gitignore
- test -d CVS && vc_ignore_files="$vc_ignore_files .cvsignore"
- else
- vc_ignore_files=$vc_ignore
- fi
-
- func_verbose "vc_ignore_files='$vc_ignore_files'"
-
- require_vc_ignore_files=:
-}
-
-
-## ----------------- ##
-## Helper functions. ##
-## ----------------- ##
-
-# This section contains the helper functions used by the rest of 'bootstrap'.
-
-# func_len STRING
-# ---------------
-# STRING may not start with a hyphen.
-if (eval 'x=123; test x${#x} = "x3"') 2>/dev/null
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_len ()
- {
- $debug_cmd
-
- func_len_result=${#1}
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_len ()
- {
- $debug_cmd
-
- func_len_result=`expr "$1" : ".*" 2>/dev/null || echo 0`
- }
-fi
-
-
-# func_unset VAR
-# --------------
-# Portably unset VAR.
-# In some shells, an 'unset VAR' statement leaves a non-zero return
-# status if VAR is already unset, which might be problematic if the
-# statement is used at the end of a function (thus poisoning its return
-# value) or when 'set -e' is active (causing even a spurious abort of
-# the script in this case).
-func_unset ()
-{
- { eval $1=; unset $1; }
-}
-unset=func_unset
-
-
-# func_cmp_s FILE1 FILE2
-# ----------------------
-# Return non-zero exit status unless FILE1 and FILE2 are identical, without
-# any output at all, even error messages.
-func_cmp_s ()
-{
- $debug_cmd
-
- # This function relies on non-zero exit status, which will cause the
- # program to exit when running in 'set -e' mode.
- $CMP "$@" >/dev/null 2>&1
-}
-
-
-# func_grep_q EXPRESSION [FILENAME..]
-# -----------------------------------
-# Check whether EXPRESSION matches any line of any listed FILENAME,
-# without any output at all, even error messages.
-func_grep_q ()
-{
- $debug_cmd
-
- # This function relies on non-zero exit status, which will cause the
- # program to exit when running in 'set -e' mode.
- $GREP "$@" >/dev/null 2>&1
-}
-
-
-# func_ifcontains LIST MEMBER YES-CMD [NO-CMD]
-# --------------------------------------------
-# If whitespace-separated LIST contains MEMBER then execute YES-CMD,
-# otherwise if NO-CMD was given, execute that.
-func_ifcontains ()
-{
- $debug_cmd
-
- _G_wslist=$1
- _G_member=$2
- _G_yes_cmd=$3
- _G_no_cmd=${4-":"}
-
- _G_found=false
- for _G_item in $_G_wslist; do
- test "x$_G_item" = "x$_G_member" && {
- _G_found=:
- break
- }
- done
- if $_G_found; then
- eval "$_G_yes_cmd"
- _G_status=$?
- else
- eval "$_G_no_cmd"
- _G_status=$?
- fi
-
- test 0 -eq "$_G_status" || exit $_G_status
-}
-
-
-# func_strpad STR WIDTH CHAR
-# --------------------------
-# Trim STR, or pad with CHAR to force a total length of WIDTH.
-func_strpad ()
-{
- $debug_cmd
-
- _G_width=`expr "$2" - 1`
- func_strpad_result=`$ECHO "$1" |$SED '
- :a
- s|^.\{0,'"$_G_width"'\}$|&'"$3"'|
- ta
- '`
-}
-
-
-# func_strrpad STR WIDTH CHAR
-# ---------------------------
-# Trim STR, or right-justify-pad with CHAR to force a total length of
-# WIDTH.
-func_strrpad ()
-{
- $debug_cmd
-
- _G_width=`expr "$2" - 1`
- func_strrpad_result=`$ECHO "$1" |$SED '
- :a
- s|^.\{0,'"$_G_width"'\}$|'"$3"'&|
- ta
- '`
-}
-
-
-# func_strrow INDENT FIELD WIDTH [FIELDn WIDTHn]...
-# -------------------------------------------------
-# Return a string containing each FIELD left justified to WIDTH, with
-# the whole thing indented by INDENT spaces. This function is used to
-# render one row of aligned columns for a table by func_strtable().
-func_strrow ()
-{
- $debug_cmd
-
- func_strrow_linelen=$1; shift
-
- _G_row=
- while test $# -gt 0; do
- func_strrow_linelen=`expr $func_strrow_linelen + $2`
- func_strpad "$1" $2 " "
- func_append _G_row "$func_strpad_result"
- shift; shift
- done
-
- func_strrpad "$_G_row" $func_strrow_linelen " "
- func_strrow_result=$func_strrpad_result
-}
-
-
-# func_strtable INDENT WIDTH1...WIDTHn HEADER1...HEADERn FIELD1...FIELDn
-# ----------------------------------------------------------------------
-# Generate a string of newline-separated rows arranged in lined-up
-# columns of the given WIDTHs, with the entire table indented by INDENT
-# spaces. The number of columns is determined by the number of integer
-# valued WIDTH arguments following INDENT. The next set (i.e. a number
-# of arguments equal to the number of WIDTH arguments) of fields are
-# treated as the table's column HEADERs, and are separated from the
-# remainder of the table by an indented row of '-' characters. Remaining
-# arguments are each aligned below the next available header, wrapping
-# to a new row as necessary. Finally another row of '-' characters is
-# added to mark the end of the table.
-#
-# For example an unindented 3 column table with 2 rows of data would be
-# generated by this call:
-#
-# func_strtable 3 20 10 25 \
-# Header1 Header2 Header3 \
-# Row1Col1 Row1Col2 Row1Col3 \
-# Row2Col1 Row2Col2 Row2Col3
-#
-# returning the following string:
-#
-# " Header1 Header2 Header3
-# -------------------------------------------------------
-# Row1Col1 Row1Col2 Row1Col3
-# Row2Col1 Row2Col2 Row2Col3
-# -------------------------------------------------------"
-func_strtable ()
-{
- $debug_cmd
-
- # Save the indent value, we'll need it for each row we render.
- _G_indent=$1; shift
-
- # Collect remaining numeric args into a list for reuse between
- # members of each row when we call func_strrow later.
- _G_widths=$1; shift
- while test 0 -lt `expr "$1" : '[1-9][0-9]*$'`; do
- func_append _G_widths " $1"; shift
- done
-
- # Extract the same number of positional parameters as there are
- # width elements - we'll do the header rows separately so that
- # we can insert a divider line.
- _G_header=$_G_indent
- for _G_width in $_G_widths; do
- func_append _G_header " $1 $_G_width"; shift
- done
- func_strrow $_G_header
-
- # Strip off the indent, and make a divider with '-' chars, then
- # reindent.
- _G_divider=`$ECHO "$func_strrow_result" \
- |$SED 's|[^ ]|-|g
- :a
- s|- |--|g
- ta
- '`
-
- # Append the header and divider to the running result.
- func_append func_strtable_result "\
-$func_strrow_result
-$_G_divider
-"
-
- # The remaining rows are zipped between the width values we
- # unwound earlier just like the header row above.
- while test $# -gt 0; do
- _G_row=$_G_indent
- for _G_width in $_G_widths; do
- func_append _G_row " $1 $_G_width"; shift
- done
- func_strrow $_G_row
- func_append func_strtable_result "\
-$func_strrow_result
-"
- done
-
- # Mark the end of the table with a final divider line.
- func_append func_strtable_result "$_G_divider"
-}
-
-
-# func_internal_error ARG...
-# --------------------------
-# Echo program name prefixed message to standard error, and exit.
-func_internal_error ()
-{
- func_fatal_error "\
-INTERNAL: " ${1+"$@"} "
- Please report this bug to 'bug-gnulib@gnu.org'
- in as much detail as possible."
-}
-
-
-# func_permissions_error FILE-OR-DIRECTORY
-# ----------------------------------------
-# Echo program name prefixed permissions error message to standard
-# error, and exit.
-func_permissions_error ()
-{
- $debug_cmd
-
- func_fatal_error "Failed to create '$1', check permissions."
-}
-
-
-# func_show_eval CMD [FAIL_EXP]
-# -----------------------------
-# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
-# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.
-func_show_eval ()
-{
- $debug_cmd
-
- $require_term_colors
-
- _G_cmd=$1
- _G_fail_exp=${2-':'}
-
- ${opt_silent-'false'} || {
- func_quote_for_eval $_G_cmd
- eval func_truncate_cmd $func_quote_for_eval_result
- func_echo "running: $tc_bold$func_truncate_cmd_result$tc_reset"
- }
-
- ${opt_dry_run-'false'} || {
- eval "$_G_cmd"
- _G_status=$?
- test 0 -eq "$_G_status" || eval "(exit $_G_status); $_G_fail_exp"
- }
-}
-
-
-# func_truncate_cmd CMD [ARG]...
-# ------------------------------
-# For unreasonably long commands (such as a gnulib-tool invocation with
-# the full module list for import), truncate CMD after the second non-
-# option ARG.
-func_truncate_cmd ()
-{
- $debug_cmd
-
- _G_last_arg_opt_p=false
- func_truncate_cmd_result=
-
- set dummy "$@"; shift
-
- while test $# -gt 0; do
- _G_opt=$1; shift
-
- test -n "$func_truncate_cmd_result" \
- && func_append func_truncate_cmd_result ' '
- func_append func_truncate_cmd_result "$_G_opt"
-
- func_len "x$func_truncate_cmd_result"
-
- case $_G_opt in
- -*) _G_last_arg_opt_p=: ;;
- *) $_G_last_arg_opt_p \
- || test "$min_cmd_len" -gt "$func_len_result" \
- || break
- _G_last_arg_opt_p=false
- ;;
- esac
- done
-
- test $# -gt 0 && func_append func_truncate_cmd_result "..."
-}
-
-
-# func_gitignore_entries FILE...
-# ------------------------------
-# Strip blank and comment lines to leave significant entries.
-func_gitignore_entries ()
-{
- $debug_cmd
-
- $SED -e '/^#/d' -e '/^$/d' "$@"
-}
-
-
-# func_insert_if_absent STR FILE...
-# ---------------------------------
-# If $STR is not already on a line by itself in $FILE, insert it, at the
-# start. Entries are inserted at the start of the ignore list to ensure
-# existing entries starting with ! are not overridden. Such entries
-# support whilelisting exceptions after a more generic blacklist pattern.
-# sorting the new contents of the file and replacing $FILE with the result.
-func_insert_if_absent ()
-{
- $debug_cmd
-
- str=$1
- shift
-
- for file
- do
- test -f "$file" || touch "$file"
-
- duplicate_entries=`func_gitignore_entries "$file" |sort |uniq -d`
- test -n "$duplicate_entries" \
- && func_error "duplicate entries in $file: " $duplicate_entries
-
- func_grep_q "^$str\$" "$file" \
- || func_verbose "inserting '$str' into '$file'"
-
- linesold=`func_gitignore_entries "$file" |wc -l`
- linesnew=`{ $ECHO "$str"; cat "$file"; } \
- |func_gitignore_entries |sort -u |wc -l`
- test "$linesold" -eq "$linesnew" \
- || { $SED "1i\\$nl$str$nl" "$file" >"$file"T && mv "$file"T "$file"; } \
- || func_permissions_error "$file"
- done
-}
-
-
-# func_get_version APP
-# --------------------
-# echo the version number (if any) of APP, which is looked up along your
-# PATH.
-func_get_version ()
-{
- $debug_cmd
-
- _G_app=$1
-
- # Rather than uncomment the sed script in-situ, strip the comments
- # programatically before passing the result to $SED for evaluation.
- sed_get_version=`$ECHO '# extract version within line
- s|.*[v ]\{1,\}\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1|
- t done
-
- # extract version at start of line
- s|^\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1|
- t done
-
- d
-
- :done
- # the following essentially does s|5.005|5.5|
- s|\.0*\([1-9]\)|.\1|g
- p
- q' \
- |$SED '/^[ ]*#.*$/d'`
-
- func_tool_version_output $_G_app >/dev/null
- _G_status=$?
-
- test 0 -ne "$_G_status" \
- || $_G_app --version 2>&1 |$SED -n "$sed_get_version"
-
- (exit $_G_status)
-}
-
-
-# func_check_tool APP
-# -------------------
-# Search PATH for an executable at APP.
-func_check_tool ()
-{
- $debug_cmd
-
- func_check_tool_result=
-
- case $1 in
- *[\\/]*)
- test -x "$1" && func_check_tool_result=$1
- ;;
- *)
- save_IFS=$IFS
- IFS=${PATH_SEPARATOR-:}
- for _G_check_tool_path in $PATH; do
- IFS=$save_IFS
- if test -x "$_G_check_tool_path/$1"; then
- func_check_tool_result=$_G_check_tool_path/$1
- break
- fi
- done
- IFS=$save_IFS
- ;;
- esac
-}
-
-
-# func_check_versions APP1 VER1 URL1 ...[APPN VERN URLN]
-# ------------------------------------------------------
-func_check_versions ()
-{
- $debug_cmd
-
- func_check_versions_result=:
-
- while test $# -gt 0; do
- _G_app=$1; shift
- _G_reqver=$1; shift
- _G_url=$1; shift
-
- # Diagnose bad buildreq formatting.
- case $_G_url in
- [a-z]*://*) ;; # looks like a url
- *) func_fatal_error "\
-'$_G_url' from the buildreq table in
-'bootstrap.conf' does not look like the URL for downloading
-$_G_app. Please ensure that buildreq is a strict newline
-delimited list of triples; 'program min-version url'."
- ;;
- esac
-
- # Honor $APP variables ($TAR, $AUTOCONF, etc.)
- _G_appvar=`echo $_G_app |tr '[a-z]' '[A-Z]'`
- test TAR = "$_G_appvar" && _G_appvar=AMTAR
- eval "_G_app=\${$_G_appvar-$_G_app}"
-
- # Fail if no version specified, but the program can't be found.
- if test x- = "x$_G_reqver"; then
- func_check_tool $_G_app
- if test -z "$func_check_tool_result"; then
- func_error "Prerequisite '$_G_app' not not found. Please install it, or
-'export $_G_appvar=/path/to/$_G_app'."
- func_check_versions_result=false
- else
- func_verbose "found '$func_check_tool_result' for $_G_appvar."
- fi
- else
- _G_instver=`func_get_version $_G_app`
-
- # Fail if --version didn't work.
- if test -z "$_G_instver"; then
- func_error "Prerequisite '$_G_app' not found. Please install it, or
-'export $_G_appvar=/path/to/$_G_app'."
- func_check_versions_result=false
-
- # Fail if a newer version than what we have is required.
- else
- func_verbose "found '$_G_app' version $_G_instver."
-
- case $_G_reqver in
- =*)
- # If $buildreq version starts with '=', version must
- # match the installed program exactly.
- test "x$_G_reqver" = "x=$_G_instver" || {
- func_error "\
- '$_G_app' version == $_G_instver is too old
- 'exactly $_G_app-$_G_reqver is required"
- func_check_versions_result=false
- }
- ;;
- *)
- # Otherwise, anything that is not older is a match.
- func_lt_ver "$_G_reqver" "$_G_instver" || {
- func_error "\
- '$_G_app' version == $_G_instver is too old
- '$_G_app' version >= $_G_reqver is required"
- func_check_versions_result=false
- }
- ;;
- esac
- fi
- fi
- done
-}
-
-
-# func_cleanup_gnulib
-# -------------------
-# Recursively delete everything below the path in the global variable
-# GNULIB_PATH.
-func_cleanup_gnulib ()
-{
- $debug_cmd
-
- _G_status=$?
- $RM -fr "$gnulib_path"
- exit $_G_status
-}
-
-
-# func_download_po_files SUBDIR DOMAIN
-# ------------------------------------
-func_download_po_files ()
-{
- $debug_cmd
-
- func_echo "getting translations into $1 for $2..."
- _G_cmd=`printf "$po_download_command_format" "$2" "$1"`
- eval "$_G_cmd"
-}
-
-
-# func_update_po_files PO_DIR DOMAIN
-# ----------------------------------
-# Mirror .po files to $po_dir/.reference and copy only the new
-# or modified ones into $po_dir. Also update $po_dir/LINGUAS.
-# Note po files that exist locally only are left in $po_dir but will
-# not be included in LINGUAS and hence will not be distributed.
-func_update_po_files ()
-{
- $debug_cmd
-
- # Directory containing primary .po files.
- # Overwrite them only when we're sure a .po file is new.
- _G_po_dir=$1
- _G_domain=$2
-
- # Mirror *.po files into this dir.
- # Usually contains *.s1 checksum files.
- _G_ref_po_dir=$_G_po_dir/.reference
-
- test -d "$_G_ref_po_dir" || mkdir $_G_ref_po_dir || return
- func_download_po_files $_G_ref_po_dir $_G_domain \
- && ls "$_G_ref_po_dir"/*.po 2>/dev/null \
- |$SED -e 's|.*/||' -e 's|\.po$||' > "$_G_po_dir/LINGUAS" || return
-
- # Find sha1sum, named gsha1sum on MacPorts, and shasum on MacOS 10.6+.
- func_find_tool SHA1SUM sha1sum gsha1sum shasum sha1
-
- test -n "$SHA1SUM" || func_fatal_error "\
-Please install GNU Coreutils, or 'export SHA1SUM=/path/to/sha1sum'."
-
- _G_langs=`cd $_G_ref_po_dir && echo *.po|$SED 's|\.po||g'`
- test '*' = "$_G_langs" && _G_langs=x
- for _G_po in $_G_langs; do
- case $_G_po in x) continue;; esac
- _G_new_po=$_G_ref_po_dir/$_G_po.po
- _G_cksum_file=$_G_ref_po_dir/$_G_po.s1
- if ! test -f "$_G_cksum_file" ||
- ! test -f "$_G_po_dir/$_G_po.po" ||
- ! $SHA1SUM -c "$_G_cksum_file" \
- < "$_G_new_po" > /dev/null; then
- echo "updated $_G_po_dir/$_G_po.po..."
- cp "$_G_new_po" "$_G_po_dir/$_G_po.po" \
- && $SHA1SUM < "$_G_new_po" > "$_G_cksum_file" || return
- fi
- done
-}
-
-
-
-## --------------- ##
-## Option parsing. ##
-## --------------- ##
-
-# Hook in the functions to make sure our own options are parsed during
-# the option parsing loop.
-
-usage='$progpath [OPTION]...'
-
-# Short help message in response to '-h'. Add to this in 'bootstrap.conf'
-# if you accept any additional options.
-usage_message="Common Bootstrap Options:
- -c, --copy copy files instead of creating symbolic links.
- --debug enable verbose shell tracing
- -n, --dry-run print commands rather than running them
- -f, --force attempt to bootstrap even if the sources seem not
- to have been checked out.
- --gnulib-srcdir=DIRNAME
- specify a local directory where gnulib sources
- reside. Use this if you already have the gnulib
- sources on your machine, and don't want to waste
- your bandwidth downloading them again. Defaults to
- \$GNULIB_SRCDIR.
- --no-warnings equivalent to '-Wnone'
- --skip-git do not fetch files from remote repositories
- --skip-po do not download po files.
- -v, --verbose verbosely report processing
- --version print version information and exit
- -W, --warnings=CATEGORY
- report the warnings falling in CATEGORY [all]
- -h, --help print short or long help message and exit
-"
-
-# Additional text appended to 'usage_message' in response to '--help'.
-long_help_message=$long_help_message"
- 'recommend' show warnings about missing recommended packages
- 'settings' show warnings about missing '$progname.conf' settings
- 'upgrade' show warnings about out-dated files
-
-If the file '$progname.conf' exists in the same directory as this
-script, its contents are read as shell variables to configure the
-bootstrap.
-
-For build prerequisites, environment variables like \$AUTOCONF and
-\$AMTAR are honored.
-
-Running without arguments will suffice in most cases.
-"
-
-# Warning categories used by 'bootstrap', append others if you use them
-# in your 'bootstrap.conf'.
-warning_categories='recommend settings upgrade'
-
-
-# bootstrap_options_prep [ARG]...
-# -------------------------------
-# Preparation for options parsed by Bootstrap.
-bootstrap_options_prep ()
-{
- $debug_cmd
-
- # Option defaults:
- opt_copy=${copy-'false'}
- opt_dry_run=false
- opt_force=false
- opt_gnulib_srcdir=$GNULIB_SRCDIR
- opt_skip_git=false
- opt_skip_po=false
-
- # Pass back the list of options we consumed.
- func_quote_for_eval ${1+"$@"}
- bootstrap_options_prep_result=$func_quote_for_eval_result
-}
-func_add_hook func_options_prep bootstrap_options_prep
-
-
-# bootstrap_parse_options [ARG]...
-# --------------------------------
-# Provide handling for Bootstrap specific options.
-bootstrap_parse_options ()
-{
- $debug_cmd
-
- # Perform our own loop to consume as many options as possible in
- # each iteration.
- while test $# -gt 0; do
- _G_opt=$1
- shift
- case $_G_opt in
- --dry-run|--dryrun|-n)
- opt_dry_run=: ;;
- --copy|-c) opt_copy=: ;;
- --force|-f) opt_force=: ;;
-
- --gnulib-srcdir)
- test $# = 0 && func_missing_arg $_G_opt && break
- opt_gnulib_srcdir=$1
- shift
- ;;
-
- --skip-git|--no-git)
- opt_skip_git=:
- ;;
-
- --skip-po|--no-po)
- opt_skip_po=:
- ;;
-
- # Separate non-argument short options:
- -c*|-f*|-n*)
- func_split_short_opt "$_G_opt"
- set dummy "$func_split_short_opt_name" \
- "-$func_split_short_opt_arg" ${1+"$@"}
- shift
- ;;
-
- *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
- esac
- done
-
- # save modified positional parameters for caller
- func_quote_for_eval ${1+"$@"}
- bootstrap_parse_options_result=$func_quote_for_eval_result
-}
-func_add_hook func_parse_options bootstrap_parse_options
-
-
-# bootstrap_validate_options [ARG]...
-# -----------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-bootstrap_validate_options ()
-{
- $debug_cmd
-
- # Validate options.
- test $# -gt 0 \
- && func_fatal_help "too many arguments"
-
- # Pass back the (empty) list of unconsumed options.
- func_quote_for_eval ${1+"$@"}
- bootstrap_validate_options_result=$func_quote_for_eval_result
-}
-func_add_hook func_validate_options bootstrap_validate_options
-
-
-## -------------------------------------------------- ##
-## Source package customisations in 'bootstrap.conf'. ##
-## -------------------------------------------------- ##
-
-# Override the default configuration, if necessary.
-# Make sure that bootstrap.conf is sourced from the current directory
-# if we were invoked as "sh bootstrap".
-case $0 in
- */*) test -r "$0.conf" && . "$0.conf" ;;
- *) test -r "$0.conf" && . ./"$0.conf" ;;
-esac
-
-
-## ------------------------------- ##
-## Actually perform the bootstrap. ##
-## ------------------------------- ##
-
-func_bootstrap ${1+"$@"}
-
-# The End.
-exit ${exit_status-$EXIT_SUCCESS}
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "500/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
diff --git a/bootstrap.conf b/bootstrap.conf
deleted file mode 100644
index b2326348..00000000
--- a/bootstrap.conf
+++ /dev/null
@@ -1,160 +0,0 @@
-# bootstrap.conf (GNU M4) version 2017-01-03
-# Written by Gary V. Vaughan, 2010
-
-# Copyright (C) 2010, 2013-2014, 2017 Free Software Foundation, Inc.
-
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-## -------------- ##
-## Configuration. ##
-## -------------- ##
-
-copyright_holder="Free Software Foundation, Inc."
-
-# List of programs (and minimum versions) required to bootstrap, maintain
-# and release Libtool.
-buildreq='
- help2man 1.29 http://www.gnu.org/s/help2man
- makeinfo 4.13 http://www.gnu.org/s/texinfo
- xz - http://tukaani.org/xz
-'
-
-# Instructions on how to install packages in $buildreq.
-buildreq_readme=HACKING
-
-# A file only visible in a vcs working directory.
-checkout_only_file=HACKING
-
-# Local gnulib submodule path.
-gnulib_path=build-aux/gnulib
-
-# Additional gnulib-tool options to use.
-gnulib_tool_options=$gnulib_tool_options'
- --libtool
-'
-
-# gnulib_modules must remain empty in order to get --update style
-# gnulib-tool invocations, so we add the bootstrap components here.
-gnulib_non_module_files=$gnulib_non_module_files"
- build-aux/bootstrap.in
- build-aux/extract-trace
- build-aux/funclib.sh
- build-aux/inline-source
- build-aux/options-parser"
-
-# List dependencies here too; we don't extract them, otherwise dependent
-# modules could end up being imported to src/ *and* gnu/!
-src_modules='
-assure
-getopt-gnu
-getopt-posix
-version-etc-fsf
-version-etc
-xstrtol
-'
-
-# What ignore files to maintain.
-vc_ignore=".gitignore"
-
-
-## --------------- ##
-## Hook functions. ##
-## --------------- ##
-
-
-# m4_precopy_git_version_gen
-# --------------------------
-# Autopoint gets confused if git-version-gen is missing.
-m4_precopy_git_version_gen ()
-{
- $debug_cmd
-
- $require_build_aux
-
- func_gnulib_tool_copy_file build-aux/git-version-gen $build_aux/git-version-gen
-}
-func_add_hook func_prep m4_precopy_git_version_gen
-
-
-# m4_install_texinfo_diff_driver
-# ------------------------------
-# Help git to do a better job of merging texinfo files.
-m4_install_texinfo_diff_driver ()
-{
- $debug_cmd
-
- $require_git
-
- test true = "$GIT" || {
- if $GIT config diff.texinfo.funcname >/dev/null ; then
- :
- else
- func_echo "initializing git texinfo diff driver"
- git config diff.texinfo.funcname '^@node[ \t][ \t]*\\([^,][^,]*\\)'
- fi
- }
-}
-func_add_hook func_prep m4_install_texinfo_diff_driver
-
-
-# m4_copy_src_modules
-# -------------------
-# Copy $src_modules from gnulib to src directory.
-m4_copy_src_modules ()
-{
- $debug_cmd
-
- $require_gnulib_tool
-
- test true = "$gnulib_tool" || {
- $require_macro_dir
-
- for file in `$gnulib_tool --extract-filelist $src_modules | sort -u`
- do
- maybe_exit_cmd=:
-
- func_basename $file
- dest=$func_basename_result
-
- case $file in
- lib/*) dest=src/$dest ;;
- m4/*) dest=$macro_dir/$dest ;;
- *) func_error "$file: unknown file"
- maybe_exit_cmd="exit $EXIT_FAILURE"
- dest= ;;
- esac
-
- # Be sure to show all copying errors before bailing out
- if test -n "$dest"; then
- func_gnulib_tool_copy_file "$file" "$dest"
- fi
- done
-
- $maybe_exit_cmd
- }
-}
-func_add_hook func_gnulib_tool m4_copy_src_modules
-
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "# bootstrap.conf (GNU M4) version "
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "$"
-# End:
diff --git a/build-aux/gl/build-aux/bootstrap.in b/build-aux/gl/build-aux/bootstrap.in
deleted file mode 100755
index 4cc7362b..00000000
--- a/build-aux/gl/build-aux/bootstrap.in
+++ /dev/null
@@ -1,2769 +0,0 @@
-#! /bin/sh
-
-# Bootstrap an Autotooled package from checked-out sources.
-# Written by Gary V. Vaughan, 2010
-
-# Copyright (C) 2010-2014, 2017 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Originally written by Paul Eggert. The canonical version of this
-# script is maintained as build-aux/bootstrap in gnulib, however, to
-# be useful to your project, you should place a copy of it under
-# version control in the top-level directory of your project. The
-# intent is that all customization can be done with a bootstrap.conf
-# file also maintained in your version control; gnulib comes with a
-# template build-aux/bootstrap.conf to get you started.
-
-# Please report bugs or propose patches to bug-gnulib@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Most GNUish projects do not keep all of the generated Autotool
-# files under version control, but running all of the right tools
-# with the right arguments, in the correct order to regenerate
-# all of those files in readiness for configuration and building
-# can be surprisingly involved! Many projects have a 'bootstrap'
-# script under version control to invoke Autotools and perform
-# other assorted book-keeping with version numbers and the like.
-#
-# This bootstrap script aims to probe the configure.ac and top
-# Makefile.am of your project to automatically determine what
-# the correct ordering and arguments are and then run the tools for
-# you. In order to use it, you can generate an initial standalone
-# script with:
-#
-# gl/build-aux/inline-source gl/build-aux/bootstrap.in > bootstrap
-#
-# You should then store than script in version control for other
-# developers in you project. It will give you instructions about
-# how to keep it up to date if the sources change.
-#
-# See gl/doc/bootstrap.texi for documentation on how to write
-# a bootstrap.conf to customize it for your project's
-# idiosyncracies.
-
-
-## ================================================================== ##
-## ##
-## DO NOT EDIT THIS FILE, CUSTOMIZE IT USING A BOOTSTRAP.CONF ##
-## ##
-## ================================================================== ##
-
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
-
-# All uppercase denotes values stored in the environment. These
-# variables should generally be overridden by the user - however, we do
-# set them to 'true' in some parts of this script to prevent them being
-# called at the wrong time by other tools that we call ('autoreconf',
-# for example).
-#
-# We also allow 'LIBTOOLIZE', 'M4', 'SHA1SUM' and some others to be
-# overridden, and export the result for child processes, but they are
-# handled by the function 'func_find_tool' and not defaulted in this
-# section.
-
-: ${ACLOCAL="aclocal"}
-: ${AUTOCONF="autoconf"}
-: ${AUTOHEADER="autoheader"}
-: ${AUTOM4TE="autom4te"}
-: ${AUTOHEADER="autoheader"}
-: ${AUTOMAKE="automake"}
-: ${AUTOPOINT="autopoint"}
-: ${AUTORECONF="autoreconf"}
-: ${CMP="cmp"}
-: ${CONFIG_SHELL="/bin/sh"}
-: ${DIFF="diff"}
-: ${GIT="git"}
-: ${LN_S="ln -s"}
-: ${RM="rm"}
-
-export ACLOCAL
-export AUTOCONF
-export AUTOHEADER
-export AUTOM4TE
-export AUTOHEADER
-export AUTOMAKE
-export AUTOPOINT
-export AUTORECONF
-export CONFIG_SHELL
-
-
-## -------------- ##
-## Configuration. ##
-## -------------- ##
-
-# A newline delimited list of triples of programs (that respond to
-# --version), the minimum version numbers required (or just '-' in the
-# version field if any version will be sufficient) and homepage URLs
-# to help locate missing packages.
-buildreq=
-
-# Name of a file containing instructions on installing missing packages
-# required in 'buildreq'.
-buildreq_readme=README-hacking
-
-# These are extracted from AC_INIT in configure.ac, though you can
-# override those values in 'bootstrap.conf' if you prefer.
-build_aux=
-macro_dir=
-package=
-package_name=
-package_version=
-package_bugreport=
-
-# These are extracted from 'gnulib-cache.m4', or else fall-back
-# automatically on the gnulib defaults; unless you set the values
-# manually in 'bootstrap.conf'.
-doc_base=
-gnulib_mk=
-gnulib_name=
-local_gl_dir=
-source_base=
-tests_base=
-
-# The list of gnulib modules required at 'gnulib-tool' time. If you
-# check 'gnulib-cache.m4' into your repository, then this list will be
-# extracted automatically.
-gnulib_modules=
-
-# Extra gnulib files that are not in modules, which override files of
-# the same name installed by other bootstrap tools.
-gnulib_non_module_files="
- build-aux/compile
- build-aux/install-sh
- build-aux/mdate-sh
- build-aux/texinfo.tex
- build-aux/depcomp
- build-aux/config.guess
- build-aux/config.sub
- doc/INSTALL
-"
-
-# Relative path to the local gnulib submodule, and url to the upstream
-# git repository. If you have a gnulib entry in your .gitmodules file,
-# these values are ignored.
-gnulib_path=
-gnulib_url=
-
-# Additional gnulib-tool options to use.
-gnulib_tool_options="
- --no-changelog
-"
-
-# bootstrap removes any macro-files that are not included by aclocal.m4,
-# except for files listed in this variable that are always kept.
-gnulib_precious="
- gnulib-tool.m4
-"
-
-# When truncating long commands for display, always allow at least this
-# many characters before truncating.
-min_cmd_len=160
-
-# The command to download all .po files for a specified domain into
-# a specified directory. Fill in the first %s is the domain name, and
-# the second with the destination directory. Use rsync's -L and -r
-# options because the latest/%s directory and the .po files within are
-# all symlinks.
-po_download_command_format=\
-"rsync --delete --exclude '*.s1' -Lrtvz \
-'translationproject.org::tp/latest/%s/' '%s'"
-
-# Other locale categories that need message catalogs.
-extra_locale_categories=
-
-# Additional xgettext options to use. Gnulib might provide you with an
-# extensive list of additional options to append to this, but gettext
-# 0.16.1 and newer appends them automaticaly, so you can safely ignore
-# the complaints from 'gnulib-tool' if your $configure_ac states:
-#
-# AM_GNU_GETTEXT_VERSION([0.16.1])
-xgettext_options="
- --flag=_:1:pass-c-format
- --flag=N_:1:pass-c-format
-"
-
-# Package copyright holder for gettext files. Defaults to FSF if unset.
-copyright_holder=
-
-# File that should exist in the top directory of a checked out hierarchy,
-# but not in a distribution tarball.
-checkout_only_file=
-
-# Whether to use copies instead of symlinks by default (if set to true,
-# the --copy option has no effect).
-copy=false
-
-# Set this to ".cvsignore .gitignore" in 'bootstrap.conf' if you want
-# those files to be generated in directories like 'lib/', 'm4/', and 'po/',
-# or set it to "auto" to make this script select what to use based
-# on what version control system (if any) is used in the source directory.
-# Or set it to "none" to ignore VCS ignore files entirely. Default is
-# "auto".
-vc_ignore=
-
-
-## ------------------- ##
-## External Libraries. ##
-## ------------------- ##
-
-# Source required external libraries:
-. `echo "$0" |${SED-sed} 's|[^/]*$||'`"funclib.sh"
-. `echo "$0" |${SED-sed} 's|[^/]*$||'`"options-parser"
-. `echo "$0" |${SED-sed} 's|[^/]*$||'`"extract-trace"
-
-# Set a version string for *this* script.
-scriptversion=2014-11-04.13; # UTC
-
-
-## ------------------- ##
-## Hookable functions. ##
-## ------------------- ##
-
-# After 'bootstrap.conf' has been sourced, execution proceeds by calling
-# 'func_bootstrap'. Wherever a function is decorated with
-# 'func_hookable func_name', you will find a matching 'func_run_hooks
-# func_name', which executes all functions added with 'func_add_hook
-# func_name my_func'.
-#
-# You might notice that many of these functions begin with a series of
-# '$require_foo' lines. See the docu-comments at the start of the
-# 'Resource management' section for a description of what these are.
-
-
-# func_bootstrap [ARG]...
-# -----------------------
-# All the functions called inside func_bootstrap are hookable. See the
-# the individual implementations for details.
-func_bootstrap ()
-{
- $debug_cmd
-
- # Save the current positional parameters to prevent them being
- # corrupted by calls to 'set' in 'func_init'.
- func_quote_for_eval ${1+"$@"}
- _G_saved_positional_parameters=$func_quote_for_eval_result
-
- # Initialisation.
- func_init
-
- # Option processing.
- eval func_options "$_G_saved_positional_parameters"
-
- # Post-option preparation.
- func_prep
-
- # Reconfigure the package.
- func_reconfigure
-
- # Ensure .version is up-to-date.
- func_update_dotversion
-
- # Finalisation.
- func_fini
-}
-
-
-# func_init
-# ---------
-# Any early initialisations can be hooked to this function. Consider
-# whether you can hook onto 'func_prep' instead, because if you hook
-# any slow to execute code in here, it will also add to the time before
-# './bootstrap --version' can respond.
-func_hookable func_init
-func_init ()
-{
- $debug_cmd
-
- func_run_hooks func_init
-}
-
-
-# func_prep
-# ---------
-# Function to perform preparation for remaining bootstrap process. If
-# your hooked code relies on the outcome of 'func_options' hook it here
-# rather than to 'func_init'.
-#
-# All the functions called inside func_prep are hookable. See the
-# individual implementations for details.
-func_hookable func_prep
-func_prep ()
-{
- $debug_cmd
-
- $require_buildtools_uptodate
- $require_checkout_only_file
-
- $require_gnulib_merge_changelog
-
- # Report the results of SED and GREP searches from funclib.sh.
- func_verbose "GREP='$GREP'"
- func_verbose "SED='$SED'"
-
- # fetch update files from the translation project
- func_update_translations
-
- func_run_hooks func_prep
-}
-
-
-# func_update_translations
-# ------------------------
-# Update package po files and translations.
-func_hookable func_update_translations
-func_update_translations ()
-{
- $debug_cmd
-
- $opt_skip_po || {
- test -d po && {
- $require_package
-
- func_update_po_files po $package || exit $?
- }
-
- func_run_hooks func_update_translations
- }
-}
-
-
-# func_reconfigure
-# ----------------
-# Reconfigure the current package by running the appropriate autotools in a
-# suitable order.
-func_hookable func_reconfigure
-func_reconfigure ()
-{
- $debug_cmd
-
- $require_automake_options
-
- # Automake (without 'foreign' option) requires that README exists.
- case " $automake_options " in
- " foreign ") ;;
- *) func_ensure_README ;;
- esac
-
- # Ensure ChangeLog presence.
- if test -n "$gnulib_modules"; then
- func_ifcontains "$gnulib_modules" gitlog-to-changelog \
- func_ensure_changelog
- else
- $require_gnulib_cache
- if $SED -n '/^gl_MODULES(\[/,/^])$/p' $gnulib_cache 2>/dev/null |
- func_grep_q gitlog-to-changelog
- then
- func_ensure_changelog
- fi
- fi
-
- # Released 'autopoint' has the tendency to install macros that have
- # been obsoleted in current 'gnulib', so run this before 'gnulib-tool'.
- func_autopoint
-
- # Autoreconf runs 'aclocal' before 'libtoolize', which causes spurious
- # warnings if the initial 'aclocal' is confused by the libtoolized
- # (or worse: out-of-date) macro directory.
- func_libtoolize
-
- # If you need to do anything after 'gnulib-tool' is done, but before
- # 'autoreconf' runs, you don't need to override this whole function,
- # because 'func_gnulib_tool' is hookable.
- func_gnulib_tool
-
- func_autoreconf
-
- func_run_hooks func_reconfigure
-}
-
-
-# func_gnulib_tool
-# ----------------
-# Run 'gnulib-tool' to fetch gnulib modules into the current package.
-#
-# It's assumed that since you are using gnulib's 'bootstrap' script,
-# you're also using gnulib elsewhere in your package. If not, then
-# you can replace this function in 'bootstrap.conf' with:
-#
-# func_gnulib_tool () { :; }
-#
-# (although the function returns immediately if $gnulib_tool is set to
-# true in any case).
-func_hookable func_gnulib_tool
-func_gnulib_tool ()
-{
- $debug_cmd
-
- $require_gnulib_tool
- $require_libtoolize
-
- test true = "$gnulib_tool" || {
- # bootstrap.conf written for gnulib bootstrap expects
- # gnulib_tool_option_extras to which --no-changelog is appended,
- # but libtool bootstrap expects you to append to gnulib_tool_options
- # so that you can override the --no-changelog default: make sure we
- # support both styles so users can migrate between them easily.
- gnulib_tool_all_options="$gnulib_tool_options $gnulib_tool_option_extras"
-
- if test -n "$gnulib_modules"; then
- $require_gnulib_cache
- $require_gnulib_tool_base_options
-
- gnulib_mode=--import
-
- # Try not to pick up any stale values from 'gnulib-cache.m4'.
- rm -f "$gnulib_cache"
-
- test -n "$gnulib_tool_base_options" \
- && func_append_uniq gnulib_tool_all_options " $gnulib_tool_base_options"
- test -n "$gnulib_mk" \
- && func_append_uniq gnulib_tool_all_options " --makefile-name=$gnulib_mk"
- test -n "$tests_base" && {
- func_append_uniq gnulib_tool_all_options " --tests-base=$tests_base"
- func_append_uniq gnulib_tool_all_options " --with-tests"
- }
- else
-
- # 'gnulib_modules' and others are cached in 'gnulib-cache.m4':
- # Use 'gnulib --update' to fetch gnulib modules.
- gnulib_mode=--update
- fi
-
- # Add a sensible default libtool option to gnulib_tool_options.
- # The embedded echo is to squash whitespace before globbing.
- case `echo " "$gnulib_tool_all_options" "` in
- *" --no-libtool "*|*" --libtool "*) ;;
- *) if test true = "$LIBTOOLIZE"; then
- func_append_uniq gnulib_tool_all_options " --no-libtool"
- else
- func_append_uniq gnulib_tool_all_options " --libtool"
- fi
- ;;
- esac
-
- $opt_copy || func_append_uniq gnulib_tool_all_options " --symlink"
-
- func_append_uniq gnulib_tool_all_options " $gnulib_mode"
- func_append gnulib_tool_all_options " $gnulib_modules"
-
- # The embedded echo is to squash whitespace before display.
- gnulib_cmd=`echo $gnulib_tool $gnulib_tool_all_options`
-
- func_show_eval "$gnulib_cmd" 'exit $?'
-
- # Use 'gnulib-tool --copy-file' to install non-module files.
- func_install_gnulib_non_module_files
- }
-
- func_run_hooks func_gnulib_tool
-}
-
-
-# func_fini
-# ---------
-# Function to perform all finalisation for the bootstrap process.
-func_hookable func_fini
-func_fini ()
-{
- $debug_cmd
-
- func_gettext_configuration
- func_clean_dangling_symlinks
- func_clean_unused_macros
- func_skip_po_recommendation
-
- func_run_hooks func_fini
-
- $require_bootstrap_uptodate
-
- func_echo "Done. Now you can run './configure'."
-}
-
-
-# func_gettext_configuration
-# --------------------------
-# Edit configuration values into po/Makevars.
-func_hookable func_gettext_configuration
-func_gettext_configuration ()
-{
- $debug_cmd
-
- $require_autopoint
-
- test true = "$AUTOPOINT" || {
- $require_copyright_holder
- $require_extra_locale_categories
- $require_package_bugreport
-
- # Escape xgettext options for sed Makevars generation below.
- # We have to delete blank lines in a separate script so that we don't
- # append \\\ to the penultimate line, and then delete the last empty
- # line, which messes up the variable substitution later in this
- # function. Note that adding a literal \\\ requires double escaping
- # here, once for the execution subshell, and again for the assignment,
- # which is why there are actually 12 (!!) backslashes in the script.
- _G_xgettext_options=`echo "$xgettext_options$nl" |$SED '/^$/d' |$SED '
- $b
- s|$| \\\\\\\\\\\\|'`
-
- # Create gettext configuration.
- func_echo "Creating po/Makevars from po/Makevars.template ..."
- $RM -f po/Makevars
- $SED '
- /^EXTRA_LOCALE_CATEGORIES *=/s|=.*|= '"$extra_locale_categories"'|
- /^COPYRIGHT_HOLDER *=/s|=.*|= '"$copyright_holder"'|
- /^MSGID_BUGS_ADDRESS *=/s|=.*|= '"$package_bugreport"'|
- /^XGETTEXT_OPTIONS *=/{
- s|$| \\|
- a\
- '"$_G_xgettext_options"' \\\
- $${end_of_xgettext_options+}
- }
- ' po/Makevars.template >po/Makevars || exit 1
- }
-
- func_run_hooks func_gettext_configuration
-}
-
-
-
-## --------------- ##
-## Core functions. ##
-## --------------- ##
-
-# This section contains the main functions called from the 'Hookable
-# functions' (shown above), and are the ones you're most likely
-# to want to replace with your own implementations in 'bootstrap.conf'.
-
-
-# func_autopoint
-# --------------
-# If this package uses gettext, then run 'autopoint'.
-func_autopoint ()
-{
- $debug_cmd
-
- $require_autopoint
-
- test true = "$AUTOPOINT" \
- || func_show_eval "$AUTOPOINT --force" 'exit $?'
-}
-
-
-# func_libtoolize
-# ---------------
-# If this package uses libtool, then run 'libtoolize'.
-func_libtoolize ()
-{
- $debug_cmd
-
- $require_libtoolize
-
- test true = "$LIBTOOLIZE" || {
- _G_libtoolize_options=
- $opt_copy && func_append _G_libtoolize_options " --copy"
- $opt_force && func_append _G_libtoolize_options " --force"
- $opt_verbose || func_append _G_libtoolize_options " --quiet"
- func_show_eval "$LIBTOOLIZE$_G_libtoolize_options" 'exit $?'
- }
-}
-
-
-# func_gnulib_tool_copy_file SRC DEST
-# -----------------------------------
-# Copy SRC, a path relative to the gnulib sub-tree, to DEST, a path
-# relative to the top-level source directory using gnulib-tool so that
-# any patches or replacements in $local_gl_dir are applied.
-func_gnulib_tool_copy_file ()
-{
- $debug_cmd
-
- $require_gnulib_tool
- $require_patch
-
- if test true = "$gnulib_tool"; then
- # If gnulib-tool is not available (e.g. bootstrapping in a
- # distribution tarball), make sure that at least we have some
- # version of the required file already in place.
- test -f "$2" || func_fatal_error "\
-Can't find, copy or download '$2', a required
-gnulib supplied file, please provide the location of a
-complete 'gnulib' tree by setting 'gnulib_path' in your
-'bootstrap.conf' or with the '--gnulib-srcdir' option -
-or else specify the location of your 'git' binary by
-setting 'GIT' in the environment so that a fresh
-'gnulib' submodule can be cloned."
- else
- $require_gnulib_copy_cmd
-
- $gnulib_copy_cmd $1 $2 2>/dev/null || {
- $require_gnulib_path
-
- func_error "'$gnulib_path/$1' does not exist"
- return 1
- }
- fi
-}
-
-
-# func_install_gnulib_non_module_files
-# ------------------------------------
-# Get additional non-module files from gnulib, overriding existing files.
-func_install_gnulib_non_module_files ()
-{
- $debug_cmd
-
- $require_build_aux
- $require_gnulib_tool
-
- test -n "$gnulib_non_module_files" && {
- maybe_exit_cmd=:
-
- for file in $gnulib_non_module_files; do
- case $file in
- */COPYING*) dest=COPYING;;
- */INSTALL) dest=INSTALL;;
- build-aux/missing) dest=
- func_warning settings "\
-Please remove build-aux/missing from gnulib_module_files in
-'bootstrap.conf', as it may clash with Automake's version."
- ;;
- build-aux/*) dest=$build_aux/`expr "$file" : 'build-aux/\(.*\)'`;;
- *) dest=$file;;
- esac
-
- # Be sure to show all copying errors before bailing out
- test -z "$dest" \
- || func_gnulib_tool_copy_file "$file" "$dest" \
- || maybe_exit_cmd="exit $EXIT_FAILURE"
- done
-
- $maybe_exit_cmd
- }
-}
-
-
-# func_ensure_changelog
-# ---------------------
-# Even with 'gitlog-to-changelog' generated ChangeLogs, automake
-# will not run to completion with no ChangeLog file.
-func_ensure_changelog ()
-{
- $debug_cmd
-
- test -f ChangeLog && mv -f ChangeLog ChangeLog~
-
- cat >ChangeLog <<'EOT'
-## ---------------------- ##
-## DO NOT EDIT THIS FILE! ##
-## ---------------------- ##
-
-ChangeLog is generated by gitlog-to-changelog.
-EOT
-
- _G_message="creating dummy 'ChangeLog'"
- test -f ChangeLog~ \
- && func_append _G_message ' (backup in ChangeLog~)'
- func_verbose "$_G_message"
-
- return 0
-}
-
-
-# func_ensure_README
-# ------------------
-# Without AM_INIT_AUTOMAKE([foreign]), automake will not run to
-# completion with no README file, even though README.md or README.txt
-# is often preferable.
-func_ensure_README ()
-{
- $debug_cmd
-
- test -f README || {
- _G_README=
- for _G_readme in README.txt README.md README.rst; do
- test -f "$_G_readme" && break
- done
-
- test -f "$_G_readme" && $LN_S $_G_readme README
- func_verbose "$LN_S $_G_readme README"
- }
-
- return 0
-}
-
-
-# func_autoreconf [SUBDIR]
-# ------------------------
-# Being careful not to re-run 'autopoint' or 'libtoolize', and not to
-# try to run 'autopoint', 'libtoolize' or 'autoheader' on packages that
-# don't use them, defer to 'autoreconf' for execution of the remaining
-# autotools to bootstrap this package.
-#
-# Projects with multiple trees to reconfigure can hook another call to
-# this function onto func_reconfigure:
-#
-# my_autoreconf_foo ()
-# {
-# func_autoreconf foo
-# }
-# func_add_hook func_reconfigure my_autoreconf_foo
-func_autoreconf ()
-{
- $debug_cmd
-
- $require_autoheader
- $require_build_aux # automake and others put files in here
- $require_macro_dir # aclocal and others put files in here
-
- # We ran these manually already, and autoreconf won't exec ':'
- save_AUTOPOINT=$AUTOPOINT; AUTOPOINT=true
- save_LIBTOOLIZE=$LIBTOOLIZE; LIBTOOLIZE=true
-
- _G_autoreconf_options=
- $opt_copy || func_append _G_autoreconf_options " --symlink"
- $opt_force && func_append _G_autoreconf_options " --force"
- $opt_verbose && func_append _G_autoreconf_options " --verbose"
- func_show_eval "$AUTORECONF$_G_autoreconf_options --install${1+ $1}" 'exit $?'
-
- AUTOPOINT=$save_AUTOPOINT
- LIBTOOLIZE=$save_LIBTOOLIZE
-}
-
-
-# func_check_configuration VARNAME [CONFIGURE_MACRO]
-# --------------------------------------------------
-# Exit with a suitable diagnostic for an important configuration change
-# that needs to be made before bootstrap can run correctly.
-func_check_configuration ()
-{
- $debug_cmd
-
- $require_configure_ac
-
- eval 'test -n "$'$1'"' || {
- _G_error_msg="please set '$1' in 'bootstrap.conf'"
- if test -n "$configure_ac" && test -n "$2"; then
- func_append _G_error_msg "
-or add the following (or similar) to your '$configure_ac':
-$2"
- fi
-
- func_fatal_error "$_G_error_msg"
- }
-}
-
-
-# func_clean_dangling_symlinks
-# ----------------------------
-# Remove any dangling symlink matching "*.m4" or "*.[ch]" in some
-# gnulib-populated directories. Such .m4 files would cause aclocal to
-# fail. The following requires GNU find 4.2.3 or newer. Considering
-# the usual portability constraints of this script, that may seem a very
-# demanding requirement, but it should be ok. Ignore any failure,
-# which is fine, since this is only a convenience to help developers
-# avoid the relatively unusual case where a symlinked-to .m4 file is
-# git-removed from gnulib between successive runs of this script.
-func_clean_dangling_symlinks ()
-{
- $debug_cmd
-
- $require_macro_dir
- $require_source_base
-
- func_verbose "cleaning dangling symlinks"
-
- find "$macro_dir" "$source_base" \
- -depth \( -name '*.m4' -o -name '*.[ch]' \) \
- -type l -xtype l -delete > /dev/null 2>&1
-}
-
-
-# func_clean_unused_macros
-# ------------------------
-# Autopoint can result in over-zealously adding macros into $macro_dir
-# even though they are not actually used, for example tests to help
-# build the 'intl' directory even though you have specified
-# 'AM_GNU_GETTEXT([external])' in your configure.ac. This function
-# looks removes any macro files that can be found in gnulib, but
-# are not 'm4_include'd by 'aclocal.m4'.
-func_clean_unused_macros ()
-{
- $debug_cmd
-
- $require_gnulib_path
- $require_macro_dir
-
- test -n "$gnulib_path" && test -f aclocal.m4 && {
- aclocal_m4s=`find . -name aclocal.m4 -print`
-
- # We use 'ls|grep' instead of 'ls *.m4' to avoid exceeding
- # command line length limits in some shells.
- for file in `cd "$macro_dir" && ls -1 |$GREP '\.m4$'`; do
-
- # Remove a macro file when aclocal.m4 does not m4_include it...
- func_grep_q 'm4_include([[]'$macro_dir/$file'])' $aclocal_m4s \
- || test ! -f "$gnulib_path/m4/$file" || {
-
- # ...and there is an identical file in gnulib...
- if func_cmp_s "$gnulib_path/m4/$file" "$macro_dir/$file"; then
-
- # ...and it's not in the precious list ('echo' is needed
- # here to squash whitespace for the match expression).
- case " "`echo $gnulib_precious`" " in
- *" $file "*) ;;
- *) rm -f "$macro_dir/$file"
- func_verbose \
- "removing unused gnulib file '$macro_dir/$file'"
- esac
- fi
- }
- done
- }
-}
-
-
-# func_skip_po_recommendation
-# ---------------------------
-# If there is a po directory, and '--skip-po' wasn't passed, let the
-# user know that they can use '--skip-po' on subsequent invocations.
-func_skip_po_recommendation ()
-{
- $debug_cmd
-
- test ! -d po \
- || $opt_skip_po \
- || func_warning recommend "\
-If your pofiles are up-to-date, you can rerun bootstrap
-as '$progname --skip-po' to avoid redownloading."
-}
-
-
-# func_update_dotversion
-# ----------------------
-# Even with 'gitlog-to-changelog' generated ChangeLogs, automake
-# will not run to completion with no ChangeLog file.
-func_update_dotversion ()
-{
- $debug_cmd
-
- test -f "$build_aux/git-version-gen" && {
- _G_message="updating .version"
- test -f .version && {
- mv .version .version~
- func_append _G_message " (backup in .version~)"
- }
- func_verbose "updating .version"
-
- $build_aux/git-version-gen dummy-arg > .version
- }
-}
-
-
-
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
-
-# This section contains definitions for functions that each ensure a
-# particular resource (a file, or a non-empty configuration variable for
-# example) is available, and if appropriate to extract default values
-# from pertinent package files. Where a variable already has a non-
-# empty value (as set by the package's 'bootstrap.conf'), that value is
-# used in preference to deriving the default. Call them using their
-# associated 'require_*' variable to ensure that they are executed, at
-# most, once.
-
-
-# require_checkout_only_file
-# --------------------------
-# Bail out if this package only bootstraps properly from a repository
-# checkout.
-require_checkout_only_file=func_require_checkout_only_file
-func_require_checkout_only_file ()
-{
- $debug_cmd
-
- $opt_force || {
- test -n "$checkout_only_file" && test ! -f "$checkout_only_file" \
- && func_fatal_error "\
-Bootstrapping from a non-checked-out distribution is risky.
-If you wish to bootstrap anyway, use the '--force' option."
- }
-
- require_checkout_only_file=:
-}
-
-
-# require_aclocal_amflags
-# -----------------------
-# Ensure '$aclocal_amflags' has a sensible default, extracted from
-# 'Makefile.am' if necessary.
-require_aclocal_amflags=func_require_aclocal_amflags
-func_require_aclocal_amflags ()
-{
- $debug_cmd
-
- $require_makefile_am
-
- _G_sed_extract_aclocal_amflags='s|#.*$||
- /^[ ]*ACLOCAL_AMFLAGS[ ]*=/ {
- s|^.*=[ ]*\(.*\)|aclocal_amflags="\1"|
- p
- }'
-
- _G_aclocal_flags_cmd=`$SED -n "$_G_sed_extract_aclocal_amflags" \
- "$makefile_am"`
- eval "$_G_aclocal_flags_cmd"
-
- func_verbose "ACLOCAL_AMFLAGS='$aclocal_amflags'"
-
- require_aclocal_amflags=:
-}
-
-
-# require_autoheader
-# ------------------
-# Skip autoheader if it's not needed.
-require_autoheader=func_require_autoheader
-func_require_autoheader ()
-{
- $debug_cmd
-
- test true = "$AUTOHEADER" || {
- func_extract_trace AC_CONFIG_HEADERS
- test -n "$func_extract_trace_result" \
- || func_extract_trace AC_CONFIG_HEADER
-
- test -n "$func_extract_trace_result" || {
- AUTOHEADER=true
-
- func_verbose "export AUTOHEADER='$AUTOHEADER'"
-
- # Make sure the search result is visible to subshells
- export AUTOHEADER
- }
- }
-
- require_autoheader=:
-}
-
-
-# require_automake_options
-# ------------------------
-# Extract options from AM_AUTOMAKE_INIT.
-require_automake_options=func_require_automake_options
-func_require_automake_options ()
-{
- $debug_cmd
-
- func_extract_trace AM_INIT_AUTOMAKE
- automake_options=$func_extract_trace_result
-
- require_automake_options=:
-}
-
-
-# require_autopoint
-# -----------------
-# Skip autopoint if it's not needed.
-require_autopoint=func_require_autopoint
-func_require_autopoint ()
-{
- $debug_cmd
-
- test true = "$AUTOPOINT" || {
- func_extract_trace AM_GNU_GETTEXT_VERSION
-
- test -n "$func_extract_trace_result" || {
- AUTOPOINT=true
-
- func_verbose "export AUTOPOINT='$AUTOPOINT'"
-
- # Make sure the search result is visible to subshells
- export AUTOPOINT
- }
- }
-
- require_autopoint=:
-}
-
-
-# require_bootstrap_uptodate
-# --------------------------
-# Complain if the version of bootstrap in the gnulib directory differs
-# from the one we are running.
-require_bootstrap_uptodate=func_require_bootstrap_uptodate
-func_require_bootstrap_uptodate ()
-{
- $debug_cmd
-
- $require_build_aux
-
- _G_bootstrap_sources="
- $build_aux/bootstrap.in
- $build_aux/extract-trace
- $build_aux/funclib.sh
- $build_aux/options-parser
- "
-
- _G_missing_bootstrap_sources=false
- for _G_src in $_G_bootstrap_sources; do
- test -f "$_G_src" || _G_missing_bootstrap_sources=:
- done
-
- if $_G_missing_bootstrap_sources; then
- func_warning upgrade "\
-Please add bootstrap to your gnulib_modules list in
-'bootstrap.conf', so that I can tell you when there are
-updates available."
- else
- rm -f bootstrap.new
- $build_aux/inline-source $build_aux/bootstrap.in > bootstrap.new
-
- if func_cmp_s "$progpath" bootstrap.new; then
- rm -f bootstrap.new
- func_verbose "bootstrap script up to date"
- else
- chmod 555 bootstrap.new
- func_warning upgrade "\
-An updated bootstrap script has been generated for you in
-'bootstrap.new'. After you've verified that you want
-the changes, you can update with:
- mv -f bootstrap.new $progname
- ./$progname
-
-Or you can disable this check permanently by adding the
-following to 'bootstrap.conf':
- require_bootstrap_uptodate=:"
- fi
- fi
-
- require_bootstrap_uptodate=:
-}
-
-
-# require_build_aux
-# -----------------
-# Ensure that '$build_aux' is set, and if it doesn't already point to an
-# existing directory, create one.
-require_build_aux=func_require_build_aux
-func_require_build_aux ()
-{
- $debug_cmd
-
- test -n "$build_aux" || {
- func_extract_trace_first AC_CONFIG_AUX_DIR
- build_aux=$func_extract_trace_first_result
- func_check_configuration build_aux \
- "AC_CONFIG_AUX_DIR([name of a directory for build scripts])"
-
- func_verbose "build_aux='$build_aux'"
- }
-
- $require_vc_ignore_files
-
- # If the build_aux directory doesn't exist, create it now, and mark it
- # as ignored for the VCS.
- if test ! -d "$build_aux"; then
- func_show_eval "mkdir '$build_aux'"
-
- test -n "$vc_ignore_files" \
- || func_insert_if_absent "$build_aux" $vc_ignore_files
- fi
-
- require_build_aux=:
-}
-
-
-# require_buildreq_autobuild
-# --------------------------
-# Try to find whether the bootstrap requires autobuild.
-require_buildreq_autobuild=func_require_buildreq_autobuild
-func_require_buildreq_autobuild ()
-{
- $debug_cmd
-
- $require_macro_dir
-
- test -f "$macro_dir/autobuild.m4" \
- || printf '%s\n' "$buildreq" |func_grep_q '^[ ]*autobuild' \
- || {
- func_extract_trace AB_INIT
- test -n "$func_extract_trace_result" && {
- func_append buildreq 'autobuild - http://josefsson.org/autobuild/
-'
- func_verbose "auto-adding 'autobuild' to build requirements"
- }
- }
-
- require_buildreq_autobuild=:
-}
-
-
-# require_buildreq_autoconf
-# require_buildreq_autopoint
-# require_buildreq_libtoolize
-# ---------------------------
-# Try to find the minimum compatible version of autoconf/libtool
-# required to bootstrap successfully, and add it to '$buildreq'.
-for tool in autoconf libtoolize autopoint; do
- b=$tool
- v=require_buildreq_${tool}
- f=func_$v
- case $tool in
- autoconf) m=AC_PREREQ ;;
- libtoolize) m=LT_PREREQ; b=libtool ;;
- autopoint) m=AM_GNU_GETTEXT_VERSION b=gettext ;;
- esac
-
- eval $v'='$f'
- '$f' ()
- {
- $debug_cmd
-
- # The following is ignored if undefined, but might be necessary
- # in order for `func_find_tool` to run.
- ${require_'$tool'-:}
-
- printf '\''%s\n'\'' "$buildreq" |func_grep_q '\''^[ ]*'$tool\'' || {
- func_extract_trace '$m'
- _G_version=$func_extract_trace_result
- test -n "$_G_version" && {
- func_append buildreq "\
- '$tool' $_G_version http://www.gnu.org/s/'$b'
-"
- func_verbose \
- "auto-adding '\'$tool'-$_G_version'\'' to build requirements"
- }
- }
-
- '$v'=:
- }
-'
-done
-
-
-# require_buildreq_automake
-# -------------------------
-# Try to find the minimum compatible version of automake required to
-# bootstrap successfully, and add it to '$buildreq'.
-require_buildreq_automake=func_require_buildreq_automake
-func_require_buildreq_automake ()
-{
- $debug_cmd
-
- # if automake is not already listed in $buildreq...
- printf '%s\n' "$buildreq" |func_grep_q automake || {
- func_extract_trace AM_INIT_AUTOMAKE
-
- # ...and AM_INIT_AUTOMAKE is declared...
- test -n "$func_extract_trace_result" && {
- automake_version=`$ECHO "$func_extract_trace_result" \
- |$SED -e 's|[^0-9]*||' -e 's| .*$||'`
- test -n "$automake_version" || automake_version=-
-
- func_append buildreq "\
- automake $automake_version http://www.gnu.org/s/automake
-"
- func_verbose \
- "auto-adding 'automake-$automake_version' to build requirements"
- }
- }
-
- require_buildreq_automake=:
-}
-
-
-# require_buildreq_patch
-# ----------------------
-# Automatically add a patch build-requirement if there are diff files
-# in $local_gl_dir.
-require_buildreq_patch=func_require_buildreq_patch
-func_require_buildreq_patch ()
-{
- $debug_cmd
-
- $require_local_gl_dir
-
- # This ensures PATCH is set appropriately by the time
- # func_check_versions enforces $buildreq.
- $require_patch
-
- # If patch is not already listed in $buildreq...
- printf '%s\n' "$buildreq" |func_grep_q '^[ ]*patch' || {
- # The ugly find invocation is necessary to exit with non-zero
- # status for old find binaries that don't support -exec fully.
- if test ! -d "$local_gl_dir" \
- || find "$local_gl_dir" -name "*.diff" -exec false {} \; ; then :
- else
- func_append buildreq 'patch - http://www.gnu.org/s/patch
-'
- fi
- }
-
- require_buildreq_patch=:
-}
-
-
-# require_buildtools_uptodate
-# ---------------------------
-# Ensure all the packages listed in BUILDREQS are available on the build
-# machine at the minimum versions or better.
-require_buildtools_uptodate=func_require_buildtools_uptodate
-func_require_buildtools_uptodate ()
-{
- $debug_cmd
-
- $require_buildreq_autobuild
- $require_buildreq_autoconf
- $require_buildreq_automake
- $require_buildreq_libtoolize
- $require_buildreq_autopoint
- $require_buildreq_patch
-
- test -n "$buildreq" && {
- _G_error_hdr=
-
- func_check_versions $buildreq
- $func_check_versions_result || {
- test -n "$buildreq_readme" \
- && test -f "$buildreq_readme" \
- && _G_error_hdr="\
-$buildreq_readme explains how to obtain these prerequisite programs:
-"
- func_strtable 0 11 12 36 \
- "Program" "Min_version" "Homepage" $buildreq
- func_fatal_error "$_G_error_hdr$func_strtable_result"
- }
- }
-
- require_buildtools_uptodate=:
-}
-
-
-# require_copyright_holder
-# ------------------------
-# Ensure there is a sensible non-empty default value in '$copyright_holder'.
-require_copyright_holder=func_require_copyright_holder
-func_require_copyright_holder ()
-{
- $debug_cmd
-
- test -n "$copyright_holder" || {
- copyright_holder='Free Software Foundation, Inc.'
- func_warning settings "\
-Please set copyright_holder explicitly in 'bootstrap.conf';
-defaulting to '$copyright_holder'."
- }
-
- require_copyright_holder=:
-}
-
-
-# require_doc_base
-# ----------------
-# Ensure doc_base has a sensible value, extracted from 'gnulib-cache.m4'
-# if possible, otherwise letting 'gnulib-tool' pick a default.
-require_doc_base=func_require_doc_base
-func_require_doc_base ()
-{
- $debug_cmd
-
- $require_gnulib_cache
-
- test -f "$gnulib_cache" && test -z "$doc_base" && {
- func_extract_trace_first "gl_DOC_BASE" "$gnulib_cache"
- doc_base=$func_extract_trace_first_result
-
- test -n "$doc_base" && func_verbose "doc_base='$doc_base'"
- }
-
- require_doc_base=:
-}
-
-
-# require_dotgitmodules
-# ---------------------
-# Ensure we have a '.gitmodules' file, with appropriate 'gnulib' settings.
-require_dotgitmodules=func_require_dotgitmodules
-func_require_dotgitmodules ()
-{
- $debug_cmd
-
- $require_git
-
- test true = "$GIT" || {
- # A gnulib entry in .gitmodules always takes precedence.
- _G_path=`$GIT config --file .gitmodules submodule.gnulib.path 2>/dev/null`
-
- test -n "$_G_path" || {
- $require_vc_ignore_files
-
- func_verbose "creating '.gitmodules'"
-
- # If the .gitmodules file doesn't exist, create it now, and mark
- # it as ignored for the VCS.
- test -n "$gnulib_path" || gnulib_path=gnulib
- test -n "$gnulib_url" || gnulib_url=git://git.sv.gnu.org/gnulib
-
- {
- echo '[submodule "gnulib"]'
- echo " path = $gnulib_path"
- echo " url = $gnulib_url"
- } >> .gitmodules
-
- test -n "$vc_ignore_files" \
- || func_insert_if_absent ".gitmodules" $vc_ignore_files
- }
- }
-
- require_dotgitmodules=:
-}
-
-
-# require_extra_locale_categories
-# -------------------------------
-# Ensure there is a default value in '$extra_locale_categories'
-require_extra_locale_categories=func_require_extra_locale_categories
-func_require_extra_locale_categories ()
-{
- $debug_cmd
-
- # Defaults to empty, so run with whatever value may have been set in
- # 'bootstrap.conf'.
- require_extra_locale_categories=:
-}
-
-
-# require_git
-# -----------
-# Ignore git if it's not available, or we're not in a git checkout tree.
-require_git=func_require_git
-func_require_git ()
-{
- $debug_cmd
-
- $opt_skip_git && GIT=true
-
- test true = "$GIT" || {
- if test -d .git/.; then
- ($GIT --version) >/dev/null 2>&1 || GIT=true
- fi
- }
-
- func_verbose "GIT='$GIT'"
-
- require_git=:
-}
-
-
-# require_gnulib_cache
-# --------------------
-# Ensure there is a non-empty default for '$gnulib_cache', and that it
-# names an existing file.
-require_gnulib_cache=func_require_gnulib_cache
-func_require_gnulib_cache ()
-{
- $debug_cmd
-
- $require_macro_dir
-
- test -n "$gnulib_cache" \
- || gnulib_cache=$macro_dir/gnulib-cache.m4
-
- func_verbose "found '$gnulib_cache'"
-
- require_gnulib_cache=:
-}
-
-
-# require_gnulib_copy_cmd
-# -----------------------
-# Only calculate the options for copying files with gnulib once.
-require_gnulib_copy_cmd=func_require_gnulib_copy_cmd
-func_require_gnulib_copy_cmd ()
-{
- $debug_cmd
-
- $require_gnulib_tool
- $require_gnulib_tool_base_options
-
- gnulib_copy_cmd="$gnulib_tool $gnulib_tool_base_options --copy-file"
- $opt_copy || func_append gnulib_copy_cmd " --symlink"
- $opt_quiet || func_append gnulib_copy_cmd " --verbose"
-
- require_gnulib_copy_cmd=:
-}
-
-
-# require_gnulib_merge_changelog
-# ------------------------------
-# See if we can use gnulib's git-merge-changelog merge driver.
-require_gnulib_merge_changelog=func_require_gnulib_merge_changelog
-func_require_gnulib_merge_changelog ()
-{
- $debug_cmd
-
- test -f ChangeLog && {
- $require_git
-
- func_grep_q '^\(/\|\)ChangeLog$' .gitignore || test true = "$GIT" || {
- if $GIT config merge.merge-changelog.driver >/dev/null; then
- :
- elif (git-merge-changelog --version) >/dev/null 2>&1; then
- func_echo "initializing git-merge-changelog driver"
- $GIT config merge.merge-changelog.name 'GNU-style ChangeLog merge driver'
- $GIT config merge.merge-changelog.driver 'git-merge-changelog %O %A %B'
- else
- func_warning recommend \
- "Consider installing git-merge-changelog from gnulib."
- fi
- }
- }
-
- require_gnulib_merge_changelog=:
-}
-
-
-# require_gnulib_mk
-# -----------------
-# Ensure gnulib_mk has a sensible value, extracted from 'gnulib-cache.m4'
-# if possible, otherwise letting 'gnulib-tool' pick a default.
-require_gnulib_mk=func_require_gnulib_mk
-func_require_gnulib_mk ()
-{
- $debug_cmd
-
- $require_gnulib_cache
-
- test -f "$gnulib_cache" && test -z "$gnulib_mk" && {
- func_extract_trace_first "gl_MAKEFILE_NAME" "$gnulib_cache"
- gnulib_mk=$func_extract_trace_first_result
-
- test -n "$gnulib_mk" && func_verbose "gnulib_mk='$gnulib_mk'"
- }
-
- require_gnulib_mk=:
-}
-
-
-# require_gnulib_name
-# -------------------
-# Ensure gnulib_name has a sensible value, extracted from 'gnulib-cache.m4'
-# if possible, otherwise letting 'gnulib-tool' pick a default.
-require_gnulib_name=func_require_gnulib_name
-func_require_gnulib_name ()
-{
- $debug_cmd
-
- $require_gnulib_cache
-
- test -f "$gnulib_cache" && test -z "$gnulib_name" && {
- func_extract_trace_first "gl_LIB" "$gnulib_cache"
- gnulib_name=$func_extract_trace_first_result
-
- test -n "$gnulib_name" && func_verbose "gnulib_name='$gnulib_name'"
- }
-
- require_gnulib_name=:
-}
-
-
-# require_gnulib_path
-# require_gnulib_url
-# -------------------
-# Ensure 'gnulib_path' and 'gnulib_url' are set.
-require_gnulib_path=func_require_dotgitmodules_parameters
-require_gnulib_url=func_require_dotgitmodules_parameters
-func_require_dotgitmodules_parameters ()
-{
- $debug_cmd
-
- $require_git
-
- test true = "$GIT" && {
- # If we can't find git (or if the user specified '--skip-git'),
- # then use an existing gnulib directory specified with
- # '--gnulib-srcdir' if possible.
- test -n "$gnulib_path" \
- || test ! -x "$opt_gnulib_srcdir/gnulib-tool" \
- || gnulib_path=$opt_gnulib_srcdir
- }
-
-
- $require_dotgitmodules
-
- test -f .gitmodules && {
- # Extract the parameters with sed, since git may be missing
- test -n "$gnulib_path" \
- || gnulib_path=`$SED -e '/^.submodule "gnulib".$/,${
- /[ ]*path *= */{
- s|[ ]*||g;s|^[^=]*=||;p
- }
- }
- d' .gitmodules |$SED 1q`
- test -n "$gnulib_url" \
- || gnulib_url=`$SED -e '/^.submodule "gnulib".$/,${
- /[ ]*url *= */{
- s|[ ]*||g;s|^[^=]*=||;p
- }
- }
- d' .gitmodules |$SED 1q`
-
- func_verbose "gnulib_path='$gnulib_path'"
- func_verbose "gnulib_url='$gnulib_url'"
- }
-
- require_gnulib_path=:
- require_gnulib_url=:
-}
-
-
-# require_gnulib_submodule
-# ------------------------
-# Ensure that there is a current gnulib submodule at '$gnulib_path'.
-require_gnulib_submodule=func_require_gnulib_submodule
-func_require_gnulib_submodule ()
-{
- $debug_cmd
-
- $require_git
-
- if test true = "$GIT"; then
- func_warning recommend \
- "No 'git' found; imported gnulib modules may be outdated."
- else
- $require_gnulib_path
- $require_gnulib_url
-
- if test -f .gitmodules && test -f "$gnulib_path/gnulib-tool"; then
- : All present and correct.
-
- elif test -n "$opt_gnulib_srcdir"; then
- # Older git can't clone into an empty directory.
- rmdir "$gnulib_path" 2>/dev/null
- func_show_eval "$GIT clone --reference '$opt_gnulib_srcdir' \
- '$gnulib_url' '$gnulib_path'" \
- || func_fatal_error "Unable to fetch gnulib submodule."
-
- # Without --gnulib-srcdir, and no existing checked out submodule, we
- # create a new shallow clone of the remote gnulib repository.
- else
- trap func_cleanup_gnulib 1 2 13 15
-
- shallow=
- $GIT clone -h 2>&1 |func_grep_q -- --depth \
- && shallow='--depth 365'
-
- func_show_eval "$GIT clone $shallow '$gnulib_url' '$gnulib_path'" \
- func_cleanup_gnulib
-
- # FIXME: Solaris /bin/sh will try to execute '-' if any of
- # these signals are caught after this.
- trap - 1 2 13 15
- fi
-
- # Make sure we've checked out the correct revision of gnulib.
- func_show_eval "$GIT submodule init -- $gnulib_path" \
- && func_show_eval "$GIT submodule update -- $gnulib_path" \
- || func_fatal_error "Unable to update gnulib submodule."
- fi
-
- require_gnulib_submodule=:
-}
-
-
-# require_gnulib_tool
-# -------------------
-# Ensure that '$gnulib_tool' is set, and points to an executable file,
-# or else fall back to using the binary 'true' if the main gnulib
-# files appear to have been imported already.
-require_gnulib_tool=func_require_gnulib_tool
-func_require_gnulib_tool ()
-{
- $debug_cmd
-
- test true = "$gnulib_tool" || {
- $require_gnulib_submodule
- $require_gnulib_path
-
- test -n "$gnulib_tool" \
- || gnulib_tool=$gnulib_path/gnulib-tool
-
- test -x "$gnulib_tool" || {
- gnulib_tool=true
- func_warning recommend \
- "No 'gnulib-tool' found; gnulib modules may be missing."
- }
-
- test true = "$gnulib_tool" \
- || func_verbose "found '$gnulib_tool'"
- }
-
- require_gnulib_tool=:
-}
-
-
-# require_gnulib_tool_base_options
-# --------------------------------
-# Ensure that '$gnulib_tool_base_options' contains all the base options
-# required according to user configuration from bootstrap.conf.
-require_gnulib_tool_base_options=func_require_gnulib_tool_base_options
-func_require_gnulib_tool_base_options ()
-{
- $debug_cmd
-
- $require_gnulib_tool
-
- gnulib_tool_base_options=
-
- test true = "$gnulib_tool" || {
- # 'gnulib_modules' and others are maintained in 'bootstrap.conf':
- # Use 'gnulib --import' to fetch gnulib modules.
- $require_build_aux
- test -n "$build_aux" \
- && func_append_uniq gnulib_tool_base_options " --aux-dir=$build_aux"
- $require_macro_dir
- test -n "$macro_dir" \
- && func_append_uniq gnulib_tool_base_options " --m4-base=$macro_dir"
- $require_doc_base
- test -n "$doc_base" \
- && func_append_uniq gnulib_tool_base_options " --doc-base=$doc_base"
- $require_gnulib_name
- test -n "$gnulib_name" \
- && func_append_uniq gnulib_tool_base_options " --lib=$gnulib_name"
- $require_local_gl_dir
- test -n "$local_gl_dir" \
- && func_append_uniq gnulib_tool_base_options " --local-dir=$local_gl_dir"
- $require_source_base
- test -n "$source_base" \
- && func_append_uniq gnulib_tool_base_options " --source-base=$source_base"
- }
-
- require_gnulib_tool_base_options=:
-}
-
-
-# require_libtoolize
-# ------------------
-# Skip libtoolize if it's not needed.
-require_libtoolize=func_require_libtoolize
-func_require_libtoolize ()
-{
- $debug_cmd
-
- # Unless we're not searching for libtool use by this package, set
- # LIBTOOLIZE to true if none of 'LT_INIT', 'AC_PROG_LIBTOOL' and
- # 'AM_PROG_LIBTOOL' are used in configure.
- test true = "$LIBTOOLIZE" || {
- func_extract_trace LT_INIT
- test -n "$func_extract_trace_result" || func_extract_trace AC_PROG_LIBTOOL
- test -n "$func_extract_trace_result" || func_extract_trace AM_PROG_LIBTOOL
- test -n "$func_extract_trace_result" || LIBTOOLIZE=true
- }
-
- test -n "$LIBTOOLIZE" || {
- # Find libtoolize, named glibtoolize in Mac Ports, but prefer
- # user-installed libtoolize to ancient glibtoolize shipped by
- # Apple with Mac OS X when Mac Ports is not installed.
- func_find_tool LIBTOOLIZE libtoolize glibtoolize
- }
-
- test -n "$LIBTOOLIZE" || func_fatal_error "\
-Please install GNU Libtool, or 'export LIBTOOLIZE=/path/to/libtoolize'."
-
- func_verbose "export LIBTOOLIZE='$LIBTOOLIZE'"
-
- # Make sure the search result is visible to subshells
- export LIBTOOLIZE
-
- require_libtoolize=:
-}
-
-
-# require_local_gl_dir
-# --------------------
-# Ensure local_gl_dir has a sensible value, extracted from 'gnulib-cache.m4'
-# if possible, otherwise letting 'gnulib-tool' pick a default.
-require_local_gl_dir=func_require_local_gl_dir
-func_require_local_gl_dir ()
-{
- $debug_cmd
-
- $require_gnulib_cache
-
- test -f "$gnulib_cache" && test -z "$local_gl_dir" && {
- func_extract_trace_first "gl_LOCAL_DIR" "$gnulib_cache"
- local_gl_dir=$func_extract_trace_first_result
-
- test -n "$local_gl_dir" && func_verbose "local_gl_dir='$local_gl_dir'"
- }
-
- require_local_gl_dir=:
-}
-
-
-# require_macro_dir
-# -----------------
-# Ensure that '$macro_dir' is set, and if it doesn't already point to an
-# existing directory, create one.
-require_macro_dir=func_require_macro_dir
-func_require_macro_dir ()
-{
- $debug_cmd
-
- # Sometimes this is stored in 'configure.ac'.
- test -n "$macro_dir" || {
- # AC_CONFIG_MACRO_DIRS takes a space delimited list of directories,
- # but we only care about the first one in bootstrap.
- func_extract_trace_first AC_CONFIG_MACRO_DIRS
- macro_dir=`expr "x$func_extract_trace_first_result" : 'x\([^ ]*\)'`
- }
- test -n "$macro_dir" || {
- func_extract_trace_first AC_CONFIG_MACRO_DIR
- macro_dir=$func_extract_trace_first_result
- }
-
- # Otherwise we might find it in 'Makefile.am'.
- test -n "$macro_dir" || {
- $require_aclocal_amflags
-
- # Take the argument following the first '-I', if any.
- _G_minus_I_seen=false
- for _G_arg in $aclocal_amflags; do
- case $_G_minus_I_seen,$_G_arg in
- :,*) macro_dir=$_G_arg; break ;;
- *,-I) _G_minus_I_seen=: ;;
- *,-I*) macro_dir=`expr x$_G_arg : 'x-I\(.*\)$'`; break ;;
- esac
- done
- }
-
- func_verbose "macro_dir='$macro_dir'"
-
- func_check_configuration macro_dir \
- "AC_CONFIG_MACRO_DIRS([name of a directory for configure m4 files])"
-
- $require_vc_ignore_files
-
- # If the macro_dir directory doesn't exist, create it now, and mark it
- # as ignored for the VCS.
- if test ! -d "$macro_dir"; then
- mkdir "$macro_dir" || func_permissions_error "$macro_dir"
-
- test -n "$vc_ignore_files" \
- || func_insert_if_absent "$macro_dir" $vc_ignore_files
- fi
-
- require_macro_dir=:
-}
-
-
-# require_makefile_am
-# -------------------
-# Ensure there is a 'Makefile.am' in the current directory.
-require_makefile_am=func_require_makefile_am
-func_require_makefile_am ()
-{
- $debug_cmd
-
- test -n "$makefile_am" \
- || makefile_am=Makefile.am
-
- <"$makefile_am"
-
- func_verbose "found '$makefile_am'"
-
- require_makefile_am=:
-}
-
-
-# require_package
-# ---------------
-# Ensure that '$package' contains a sensible default value.
-require_package=func_require_package
-func_require_package ()
-{
- $debug_cmd
-
- test -n "$package" || {
- $require_package_name
-
- package=`echo "$package_name" \
- |$SED -e 's/GNU //' \
- -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- }
-
- func_verbose "package='$package'"
-
- require_package=:
-}
-
-
-# require_package_bugreport
-# -------------------------
-# Ensure that this has a sensible value, extracted from 'configure.ac'
-# if appropriate (and possible!).
-require_package_bugreport=func_require_package_bugreport
-func_require_package_bugreport ()
-{
- $debug_cmd
-
- func_extract_trace AC_INIT
-
- save_ifs=$IFS
- IFS=:
- set dummy $func_extract_trace_result
- IFS=$save_ifs
- shift
-
- test -n "$package_bugreport" || package_bugreport=$3
- func_check_configuration package_bugreport \
- "AC_INIT([$package_name], [$package_version], [bug-$package@gnu.org])"
- func_verbose "package_bugreport='$package_bugreport'"
-
- require_package_bugreport=:
-}
-
-
-# require_package_name
-# --------------------
-# Ensure that this has a sensible value, extracted from 'configure.ac'
-# if appropriate (and possible!).
-require_package_name=func_require_package_name
-func_require_package_name ()
-{
- $debug_cmd
-
- func_extract_trace AC_INIT
-
- save_ifs=$IFS
- IFS=:
- set dummy $func_extract_trace_result
- IFS=$save_ifs
- shift
-
- test -n "$package_name" || package_name=$1
- func_check_configuration package_name \
- "AC_INIT([name of your package], [package version number])"
- func_verbose "package_name='$package_name'"
-
- require_package_name=:
-}
-
-
-# require_package_version
-# -----------------------
-# Ensure that this has a sensible value, extracted from 'configure.ac'
-# if appropriate (and possible!). While we might have set all the
-# parameters extracted from AC_INIT at once, 'package_version' in
-# particular is not necessarily available as early as the others, since
-# 'git-version-gen' is often involved, and until then we can't rely on
-# getting a correct version number from an AC_INIT extraction.
-require_package_version=func_require_package_version
-func_require_package_version ()
-{
- $debug_cmd
-
- func_extract_trace AC_INIT
-
- save_ifs=$IFS
- IFS=:
- set dummy $func_extract_trace_result
- IFS=$save_ifs
- shift
-
- test -n "$package_version" || package_version=$2
- test -n "$package_version" || {
- # The embedded echo is to squash whitespace before globbing.
- case " "`echo $gnulib_modules`" " in
- *" git-version-gen "*)
- func_fatal_error "\
-cannot \$require_package_version in bootstrap.conf before
-func_gnulib_tool has installed the 'git-version-gen' script."
- ;;
- *)
- func_check_configuration package_version \
- "AC_INIT([name of your package], [package version number])"
- ;;
- esac
- }
- func_verbose "package_version='$package_version'"
-
- require_package_version=:
-}
-
-
-# require_patch
-# -------------
-# Find patch, according to the PATCH environment variable, or else
-# searching the user's PATH.
-require_patch=func_require_patch
-func_require_patch ()
-{
- $debug_cmd
-
- test -n "$PATCH" || {
- # Find a patch program, preferring gpatch, which is usually better
- # than the vendor patch.
- func_find_tool PATCH gpatch patch
- }
-
- test -n "$PATCH" || func_fatal_error "\
-Please install GNU Patch, or 'export PATCH=/path/to/gnu/patch'."
-
- func_verbose "export PATCH='$PATCH'"
-
- # Make sure the search result is visible to subshells
- export PATCH
-
- require_patch=:
-}
-
-
-# require_source_base
-# -------------------
-# Ensure that source_base has a sensible value, extracted from
-# 'gnulib-cache.m4' if possible.
-require_source_base=func_require_source_base
-func_require_source_base ()
-{
- $debug_cmd
-
- $require_gnulib_cache
-
- test -f "$gnulib_cache" && test -z "$source_base" && {
- func_extract_trace_first "gl_SOURCE_BASE" "$gnulib_cache"
-
- source_base=$func_extract_trace_first_result
-
- func_verbose "source_base='$source_base'"
- }
-
- require_source_base=:
-}
-
-
-# require_vc_ignore_files
-# -----------------------
-# Ensure that '$vc_ignore' has been processed to list VCS ignore files
-# in '$vc_ignore_files'
-require_vc_ignore_files=func_require_vc_ignore_files
-func_require_vc_ignore_files ()
-{
- $debug_cmd
-
- test -n "$vc_ignore" || vc_ignore=auto
-
- if test auto = "$vc_ignore" && test -z "$vc_ignore_files"; then
- vc_ignore_files=
- test -d .git && vc_ignore_files=.gitignore
- test -d CVS && vc_ignore_files="$vc_ignore_files .cvsignore"
- else
- vc_ignore_files=$vc_ignore
- fi
-
- func_verbose "vc_ignore_files='$vc_ignore_files'"
-
- require_vc_ignore_files=:
-}
-
-
-## ----------------- ##
-## Helper functions. ##
-## ----------------- ##
-
-# This section contains the helper functions used by the rest of 'bootstrap'.
-
-# func_len STRING
-# ---------------
-# STRING may not start with a hyphen.
-if (eval 'x=123; test x${#x} = "x3"') 2>/dev/null
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_len ()
- {
- $debug_cmd
-
- func_len_result=${#1}
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_len ()
- {
- $debug_cmd
-
- func_len_result=`expr "$1" : ".*" 2>/dev/null || echo 0`
- }
-fi
-
-
-# func_unset VAR
-# --------------
-# Portably unset VAR.
-# In some shells, an 'unset VAR' statement leaves a non-zero return
-# status if VAR is already unset, which might be problematic if the
-# statement is used at the end of a function (thus poisoning its return
-# value) or when 'set -e' is active (causing even a spurious abort of
-# the script in this case).
-func_unset ()
-{
- { eval $1=; unset $1; }
-}
-unset=func_unset
-
-
-# func_cmp_s FILE1 FILE2
-# ----------------------
-# Return non-zero exit status unless FILE1 and FILE2 are identical, without
-# any output at all, even error messages.
-func_cmp_s ()
-{
- $debug_cmd
-
- # This function relies on non-zero exit status, which will cause the
- # program to exit when running in 'set -e' mode.
- $CMP "$@" >/dev/null 2>&1
-}
-
-
-# func_grep_q EXPRESSION [FILENAME..]
-# -----------------------------------
-# Check whether EXPRESSION matches any line of any listed FILENAME,
-# without any output at all, even error messages.
-func_grep_q ()
-{
- $debug_cmd
-
- # This function relies on non-zero exit status, which will cause the
- # program to exit when running in 'set -e' mode.
- $GREP "$@" >/dev/null 2>&1
-}
-
-
-# func_ifcontains LIST MEMBER YES-CMD [NO-CMD]
-# --------------------------------------------
-# If whitespace-separated LIST contains MEMBER then execute YES-CMD,
-# otherwise if NO-CMD was given, execute that.
-func_ifcontains ()
-{
- $debug_cmd
-
- _G_wslist=$1
- _G_member=$2
- _G_yes_cmd=$3
- _G_no_cmd=${4-":"}
-
- _G_found=false
- for _G_item in $_G_wslist; do
- test "x$_G_item" = "x$_G_member" && {
- _G_found=:
- break
- }
- done
- if $_G_found; then
- eval "$_G_yes_cmd"
- _G_status=$?
- else
- eval "$_G_no_cmd"
- _G_status=$?
- fi
-
- test 0 -eq "$_G_status" || exit $_G_status
-}
-
-
-# func_strpad STR WIDTH CHAR
-# --------------------------
-# Trim STR, or pad with CHAR to force a total length of WIDTH.
-func_strpad ()
-{
- $debug_cmd
-
- _G_width=`expr "$2" - 1`
- func_strpad_result=`$ECHO "$1" |$SED '
- :a
- s|^.\{0,'"$_G_width"'\}$|&'"$3"'|
- ta
- '`
-}
-
-
-# func_strrpad STR WIDTH CHAR
-# ---------------------------
-# Trim STR, or right-justify-pad with CHAR to force a total length of
-# WIDTH.
-func_strrpad ()
-{
- $debug_cmd
-
- _G_width=`expr "$2" - 1`
- func_strrpad_result=`$ECHO "$1" |$SED '
- :a
- s|^.\{0,'"$_G_width"'\}$|'"$3"'&|
- ta
- '`
-}
-
-
-# func_strrow INDENT FIELD WIDTH [FIELDn WIDTHn]...
-# -------------------------------------------------
-# Return a string containing each FIELD left justified to WIDTH, with
-# the whole thing indented by INDENT spaces. This function is used to
-# render one row of aligned columns for a table by func_strtable().
-func_strrow ()
-{
- $debug_cmd
-
- func_strrow_linelen=$1; shift
-
- _G_row=
- while test $# -gt 0; do
- func_strrow_linelen=`expr $func_strrow_linelen + $2`
- func_strpad "$1" $2 " "
- func_append _G_row "$func_strpad_result"
- shift; shift
- done
-
- func_strrpad "$_G_row" $func_strrow_linelen " "
- func_strrow_result=$func_strrpad_result
-}
-
-
-# func_strtable INDENT WIDTH1...WIDTHn HEADER1...HEADERn FIELD1...FIELDn
-# ----------------------------------------------------------------------
-# Generate a string of newline-separated rows arranged in lined-up
-# columns of the given WIDTHs, with the entire table indented by INDENT
-# spaces. The number of columns is determined by the number of integer
-# valued WIDTH arguments following INDENT. The next set (i.e. a number
-# of arguments equal to the number of WIDTH arguments) of fields are
-# treated as the table's column HEADERs, and are separated from the
-# remainder of the table by an indented row of '-' characters. Remaining
-# arguments are each aligned below the next available header, wrapping
-# to a new row as necessary. Finally another row of '-' characters is
-# added to mark the end of the table.
-#
-# For example an unindented 3 column table with 2 rows of data would be
-# generated by this call:
-#
-# func_strtable 3 20 10 25 \
-# Header1 Header2 Header3 \
-# Row1Col1 Row1Col2 Row1Col3 \
-# Row2Col1 Row2Col2 Row2Col3
-#
-# returning the following string:
-#
-# " Header1 Header2 Header3
-# -------------------------------------------------------
-# Row1Col1 Row1Col2 Row1Col3
-# Row2Col1 Row2Col2 Row2Col3
-# -------------------------------------------------------"
-func_strtable ()
-{
- $debug_cmd
-
- # Save the indent value, we'll need it for each row we render.
- _G_indent=$1; shift
-
- # Collect remaining numeric args into a list for reuse between
- # members of each row when we call func_strrow later.
- _G_widths=$1; shift
- while test 0 -lt `expr "$1" : '[1-9][0-9]*$'`; do
- func_append _G_widths " $1"; shift
- done
-
- # Extract the same number of positional parameters as there are
- # width elements - we'll do the header rows separately so that
- # we can insert a divider line.
- _G_header=$_G_indent
- for _G_width in $_G_widths; do
- func_append _G_header " $1 $_G_width"; shift
- done
- func_strrow $_G_header
-
- # Strip off the indent, and make a divider with '-' chars, then
- # reindent.
- _G_divider=`$ECHO "$func_strrow_result" \
- |$SED 's|[^ ]|-|g
- :a
- s|- |--|g
- ta
- '`
-
- # Append the header and divider to the running result.
- func_append func_strtable_result "\
-$func_strrow_result
-$_G_divider
-"
-
- # The remaining rows are zipped between the width values we
- # unwound earlier just like the header row above.
- while test $# -gt 0; do
- _G_row=$_G_indent
- for _G_width in $_G_widths; do
- func_append _G_row " $1 $_G_width"; shift
- done
- func_strrow $_G_row
- func_append func_strtable_result "\
-$func_strrow_result
-"
- done
-
- # Mark the end of the table with a final divider line.
- func_append func_strtable_result "$_G_divider"
-}
-
-
-# func_internal_error ARG...
-# --------------------------
-# Echo program name prefixed message to standard error, and exit.
-func_internal_error ()
-{
- func_fatal_error "\
-INTERNAL: " ${1+"$@"} "
- Please report this bug to 'bug-gnulib@gnu.org'
- in as much detail as possible."
-}
-
-
-# func_permissions_error FILE-OR-DIRECTORY
-# ----------------------------------------
-# Echo program name prefixed permissions error message to standard
-# error, and exit.
-func_permissions_error ()
-{
- $debug_cmd
-
- func_fatal_error "Failed to create '$1', check permissions."
-}
-
-
-# func_show_eval CMD [FAIL_EXP]
-# -----------------------------
-# Unless opt_silent is true, then output CMD. Then, if opt_dryrun is
-# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.
-func_show_eval ()
-{
- $debug_cmd
-
- $require_term_colors
-
- _G_cmd=$1
- _G_fail_exp=${2-':'}
-
- ${opt_silent-'false'} || {
- func_quote_for_eval $_G_cmd
- eval func_truncate_cmd $func_quote_for_eval_result
- func_echo "running: $tc_bold$func_truncate_cmd_result$tc_reset"
- }
-
- ${opt_dry_run-'false'} || {
- eval "$_G_cmd"
- _G_status=$?
- test 0 -eq "$_G_status" || eval "(exit $_G_status); $_G_fail_exp"
- }
-}
-
-
-# func_truncate_cmd CMD [ARG]...
-# ------------------------------
-# For unreasonably long commands (such as a gnulib-tool invocation with
-# the full module list for import), truncate CMD after the second non-
-# option ARG.
-func_truncate_cmd ()
-{
- $debug_cmd
-
- _G_last_arg_opt_p=false
- func_truncate_cmd_result=
-
- set dummy "$@"; shift
-
- while test $# -gt 0; do
- _G_opt=$1; shift
-
- test -n "$func_truncate_cmd_result" \
- && func_append func_truncate_cmd_result ' '
- func_append func_truncate_cmd_result "$_G_opt"
-
- func_len "x$func_truncate_cmd_result"
-
- case $_G_opt in
- -*) _G_last_arg_opt_p=: ;;
- *) $_G_last_arg_opt_p \
- || test "$min_cmd_len" -gt "$func_len_result" \
- || break
- _G_last_arg_opt_p=false
- ;;
- esac
- done
-
- test $# -gt 0 && func_append func_truncate_cmd_result "..."
-}
-
-
-# func_gitignore_entries FILE...
-# ------------------------------
-# Strip blank and comment lines to leave significant entries.
-func_gitignore_entries ()
-{
- $debug_cmd
-
- $SED -e '/^#/d' -e '/^$/d' "$@"
-}
-
-
-# func_insert_if_absent STR FILE...
-# ---------------------------------
-# If $STR is not already on a line by itself in $FILE, insert it, at the
-# start. Entries are inserted at the start of the ignore list to ensure
-# existing entries starting with ! are not overridden. Such entries
-# support whilelisting exceptions after a more generic blacklist pattern.
-# sorting the new contents of the file and replacing $FILE with the result.
-func_insert_if_absent ()
-{
- $debug_cmd
-
- str=$1
- shift
-
- for file
- do
- test -f "$file" || touch "$file"
-
- duplicate_entries=`func_gitignore_entries "$file" |sort |uniq -d`
- test -n "$duplicate_entries" \
- && func_error "duplicate entries in $file: " $duplicate_entries
-
- func_grep_q "^$str\$" "$file" \
- || func_verbose "inserting '$str' into '$file'"
-
- linesold=`func_gitignore_entries "$file" |wc -l`
- linesnew=`{ $ECHO "$str"; cat "$file"; } \
- |func_gitignore_entries |sort -u |wc -l`
- test "$linesold" -eq "$linesnew" \
- || { $SED "1i\\$nl$str$nl" "$file" >"$file"T && mv "$file"T "$file"; } \
- || func_permissions_error "$file"
- done
-}
-
-
-# func_get_version APP
-# --------------------
-# echo the version number (if any) of APP, which is looked up along your
-# PATH.
-func_get_version ()
-{
- $debug_cmd
-
- _G_app=$1
-
- # Rather than uncomment the sed script in-situ, strip the comments
- # programatically before passing the result to $SED for evaluation.
- sed_get_version=`$ECHO '# extract version within line
- s|.*[v ]\{1,\}\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1|
- t done
-
- # extract version at start of line
- s|^\([0-9]\{1,\}\.[.a-z0-9-]*\).*|\1|
- t done
-
- d
-
- :done
- # the following essentially does s|5.005|5.5|
- s|\.0*\([1-9]\)|.\1|g
- p
- q' \
- |$SED '/^[ ]*#.*$/d'`
-
- func_tool_version_output $_G_app >/dev/null
- _G_status=$?
-
- test 0 -ne "$_G_status" \
- || $_G_app --version 2>&1 |$SED -n "$sed_get_version"
-
- (exit $_G_status)
-}
-
-
-# func_check_tool APP
-# -------------------
-# Search PATH for an executable at APP.
-func_check_tool ()
-{
- $debug_cmd
-
- func_check_tool_result=
-
- case $1 in
- *[\\/]*)
- test -x "$1" && func_check_tool_result=$1
- ;;
- *)
- save_IFS=$IFS
- IFS=${PATH_SEPARATOR-:}
- for _G_check_tool_path in $PATH; do
- IFS=$save_IFS
- if test -x "$_G_check_tool_path/$1"; then
- func_check_tool_result=$_G_check_tool_path/$1
- break
- fi
- done
- IFS=$save_IFS
- ;;
- esac
-}
-
-
-# func_check_versions APP1 VER1 URL1 ...[APPN VERN URLN]
-# ------------------------------------------------------
-func_check_versions ()
-{
- $debug_cmd
-
- func_check_versions_result=:
-
- while test $# -gt 0; do
- _G_app=$1; shift
- _G_reqver=$1; shift
- _G_url=$1; shift
-
- # Diagnose bad buildreq formatting.
- case $_G_url in
- [a-z]*://*) ;; # looks like a url
- *) func_fatal_error "\
-'$_G_url' from the buildreq table in
-'bootstrap.conf' does not look like the URL for downloading
-$_G_app. Please ensure that buildreq is a strict newline
-delimited list of triples; 'program min-version url'."
- ;;
- esac
-
- # Honor $APP variables ($TAR, $AUTOCONF, etc.)
- _G_appvar=`echo $_G_app |tr '[a-z]' '[A-Z]'`
- test TAR = "$_G_appvar" && _G_appvar=AMTAR
- eval "_G_app=\${$_G_appvar-$_G_app}"
-
- # Fail if no version specified, but the program can't be found.
- if test x- = "x$_G_reqver"; then
- func_check_tool $_G_app
- if test -z "$func_check_tool_result"; then
- func_error "Prerequisite '$_G_app' not not found. Please install it, or
-'export $_G_appvar=/path/to/$_G_app'."
- func_check_versions_result=false
- else
- func_verbose "found '$func_check_tool_result' for $_G_appvar."
- fi
- else
- _G_instver=`func_get_version $_G_app`
-
- # Fail if --version didn't work.
- if test -z "$_G_instver"; then
- func_error "Prerequisite '$_G_app' not found. Please install it, or
-'export $_G_appvar=/path/to/$_G_app'."
- func_check_versions_result=false
-
- # Fail if a newer version than what we have is required.
- else
- func_verbose "found '$_G_app' version $_G_instver."
-
- case $_G_reqver in
- =*)
- # If $buildreq version starts with '=', version must
- # match the installed program exactly.
- test "x$_G_reqver" = "x=$_G_instver" || {
- func_error "\
- '$_G_app' version == $_G_instver is too old
- 'exactly $_G_app-$_G_reqver is required"
- func_check_versions_result=false
- }
- ;;
- *)
- # Otherwise, anything that is not older is a match.
- func_lt_ver "$_G_reqver" "$_G_instver" || {
- func_error "\
- '$_G_app' version == $_G_instver is too old
- '$_G_app' version >= $_G_reqver is required"
- func_check_versions_result=false
- }
- ;;
- esac
- fi
- fi
- done
-}
-
-
-# func_cleanup_gnulib
-# -------------------
-# Recursively delete everything below the path in the global variable
-# GNULIB_PATH.
-func_cleanup_gnulib ()
-{
- $debug_cmd
-
- _G_status=$?
- $RM -fr "$gnulib_path"
- exit $_G_status
-}
-
-
-# func_download_po_files SUBDIR DOMAIN
-# ------------------------------------
-func_download_po_files ()
-{
- $debug_cmd
-
- func_echo "getting translations into $1 for $2..."
- _G_cmd=`printf "$po_download_command_format" "$2" "$1"`
- eval "$_G_cmd"
-}
-
-
-# func_update_po_files PO_DIR DOMAIN
-# ----------------------------------
-# Mirror .po files to $po_dir/.reference and copy only the new
-# or modified ones into $po_dir. Also update $po_dir/LINGUAS.
-# Note po files that exist locally only are left in $po_dir but will
-# not be included in LINGUAS and hence will not be distributed.
-func_update_po_files ()
-{
- $debug_cmd
-
- # Directory containing primary .po files.
- # Overwrite them only when we're sure a .po file is new.
- _G_po_dir=$1
- _G_domain=$2
-
- # Mirror *.po files into this dir.
- # Usually contains *.s1 checksum files.
- _G_ref_po_dir=$_G_po_dir/.reference
-
- test -d "$_G_ref_po_dir" || mkdir $_G_ref_po_dir || return
- func_download_po_files $_G_ref_po_dir $_G_domain \
- && ls "$_G_ref_po_dir"/*.po 2>/dev/null \
- |$SED -e 's|.*/||' -e 's|\.po$||' > "$_G_po_dir/LINGUAS" || return
-
- # Find sha1sum, named gsha1sum on MacPorts, and shasum on MacOS 10.6+.
- func_find_tool SHA1SUM sha1sum gsha1sum shasum sha1
-
- test -n "$SHA1SUM" || func_fatal_error "\
-Please install GNU Coreutils, or 'export SHA1SUM=/path/to/sha1sum'."
-
- _G_langs=`cd $_G_ref_po_dir && echo *.po|$SED 's|\.po||g'`
- test '*' = "$_G_langs" && _G_langs=x
- for _G_po in $_G_langs; do
- case $_G_po in x) continue;; esac
- _G_new_po=$_G_ref_po_dir/$_G_po.po
- _G_cksum_file=$_G_ref_po_dir/$_G_po.s1
- if ! test -f "$_G_cksum_file" ||
- ! test -f "$_G_po_dir/$_G_po.po" ||
- ! $SHA1SUM -c "$_G_cksum_file" \
- < "$_G_new_po" > /dev/null; then
- echo "updated $_G_po_dir/$_G_po.po..."
- cp "$_G_new_po" "$_G_po_dir/$_G_po.po" \
- && $SHA1SUM < "$_G_new_po" > "$_G_cksum_file" || return
- fi
- done
-}
-
-
-
-## --------------- ##
-## Option parsing. ##
-## --------------- ##
-
-# Hook in the functions to make sure our own options are parsed during
-# the option parsing loop.
-
-usage='$progpath [OPTION]...'
-
-# Short help message in response to '-h'. Add to this in 'bootstrap.conf'
-# if you accept any additional options.
-usage_message="Common Bootstrap Options:
- -c, --copy copy files instead of creating symbolic links.
- --debug enable verbose shell tracing
- -n, --dry-run print commands rather than running them
- -f, --force attempt to bootstrap even if the sources seem not
- to have been checked out.
- --gnulib-srcdir=DIRNAME
- specify a local directory where gnulib sources
- reside. Use this if you already have the gnulib
- sources on your machine, and don't want to waste
- your bandwidth downloading them again. Defaults to
- \$GNULIB_SRCDIR.
- --no-warnings equivalent to '-Wnone'
- --skip-git do not fetch files from remote repositories
- --skip-po do not download po files.
- -v, --verbose verbosely report processing
- --version print version information and exit
- -W, --warnings=CATEGORY
- report the warnings falling in CATEGORY [all]
- -h, --help print short or long help message and exit
-"
-
-# Additional text appended to 'usage_message' in response to '--help'.
-long_help_message=$long_help_message"
- 'recommend' show warnings about missing recommended packages
- 'settings' show warnings about missing '$progname.conf' settings
- 'upgrade' show warnings about out-dated files
-
-If the file '$progname.conf' exists in the same directory as this
-script, its contents are read as shell variables to configure the
-bootstrap.
-
-For build prerequisites, environment variables like \$AUTOCONF and
-\$AMTAR are honored.
-
-Running without arguments will suffice in most cases.
-"
-
-# Warning categories used by 'bootstrap', append others if you use them
-# in your 'bootstrap.conf'.
-warning_categories='recommend settings upgrade'
-
-
-# bootstrap_options_prep [ARG]...
-# -------------------------------
-# Preparation for options parsed by Bootstrap.
-bootstrap_options_prep ()
-{
- $debug_cmd
-
- # Option defaults:
- opt_copy=${copy-'false'}
- opt_dry_run=false
- opt_force=false
- opt_gnulib_srcdir=$GNULIB_SRCDIR
- opt_skip_git=false
- opt_skip_po=false
-
- # Pass back the list of options we consumed.
- func_quote_for_eval ${1+"$@"}
- bootstrap_options_prep_result=$func_quote_for_eval_result
-}
-func_add_hook func_options_prep bootstrap_options_prep
-
-
-# bootstrap_parse_options [ARG]...
-# --------------------------------
-# Provide handling for Bootstrap specific options.
-bootstrap_parse_options ()
-{
- $debug_cmd
-
- # Perform our own loop to consume as many options as possible in
- # each iteration.
- while test $# -gt 0; do
- _G_opt=$1
- shift
- case $_G_opt in
- --dry-run|--dryrun|-n)
- opt_dry_run=: ;;
- --copy|-c) opt_copy=: ;;
- --force|-f) opt_force=: ;;
-
- --gnulib-srcdir)
- test $# = 0 && func_missing_arg $_G_opt && break
- opt_gnulib_srcdir=$1
- shift
- ;;
-
- --skip-git|--no-git)
- opt_skip_git=:
- ;;
-
- --skip-po|--no-po)
- opt_skip_po=:
- ;;
-
- # Separate non-argument short options:
- -c*|-f*|-n*)
- func_split_short_opt "$_G_opt"
- set dummy "$func_split_short_opt_name" \
- "-$func_split_short_opt_arg" ${1+"$@"}
- shift
- ;;
-
- *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
- esac
- done
-
- # save modified positional parameters for caller
- func_quote_for_eval ${1+"$@"}
- bootstrap_parse_options_result=$func_quote_for_eval_result
-}
-func_add_hook func_parse_options bootstrap_parse_options
-
-
-# bootstrap_validate_options [ARG]...
-# -----------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-bootstrap_validate_options ()
-{
- $debug_cmd
-
- # Validate options.
- test $# -gt 0 \
- && func_fatal_help "too many arguments"
-
- # Pass back the (empty) list of unconsumed options.
- func_quote_for_eval ${1+"$@"}
- bootstrap_validate_options_result=$func_quote_for_eval_result
-}
-func_add_hook func_validate_options bootstrap_validate_options
-
-
-## -------------------------------------------------- ##
-## Source package customisations in 'bootstrap.conf'. ##
-## -------------------------------------------------- ##
-
-# Override the default configuration, if necessary.
-# Make sure that bootstrap.conf is sourced from the current directory
-# if we were invoked as "sh bootstrap".
-case $0 in
- */*) test -r "$0.conf" && . "$0.conf" ;;
- *) test -r "$0.conf" && . ./"$0.conf" ;;
-esac
-
-
-## ------------------------------- ##
-## Actually perform the bootstrap. ##
-## ------------------------------- ##
-
-func_bootstrap ${1+"$@"}
-
-# The End.
-exit ${exit_status-$EXIT_SUCCESS}
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "500/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
diff --git a/build-aux/gl/build-aux/extract-trace b/build-aux/gl/build-aux/extract-trace
deleted file mode 100755
index d0d83fe4..00000000
--- a/build-aux/gl/build-aux/extract-trace
+++ /dev/null
@@ -1,420 +0,0 @@
-#! /bin/sh
-
-# Extract macro arguments from autotools input with GNU M4.
-# Written by Gary V. Vaughan, 2010
-#
-# Copyright (C) 2010-2014, 2017 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# Make sure we've evaluated scripts we depend on.
-test -z "$progpath" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/funclib.sh
-test extract-trace = "$progname" && . `echo "$0" |${SED-sed} 's|[^/]*$||'`/options-parser
-
-# Set a version string.
-scriptversion=2014-01-04.01; # UTC
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Run './extract-trace --help' for help with using this script from the
-# command line.
-#
-# Or source first 'options-parser' and then this file into your own
-# scripts in order to make use of the function and variable framework
-# they define, and also to avoid the overhead of forking to run this
-# script in its own process on every call.
-
-
-
-## ----------------- ##
-## Helper functions. ##
-## ----------------- ##
-
-# This section contains the helper functions used by the rest of
-# 'extract-trace'.
-
-
-# func_autoconf_configure MAYBE-CONFIGURE-FILE
-# --------------------------------------------
-# Ensure that MAYBE-CONFIGURE-FILE is the name of a file in the current
-# directory that contains an uncommented call to AC_INIT.
-func_autoconf_configure ()
-{
- $debug_cmd
-
- _G_sed_no_comment='
- s|#.*$||
- s|^dnl .*$||
- s| dnl .*$||'
- _G_ac_init=
-
- # If we were passed a genuine file, make sure it calls AC_INIT.
- test -f "$1" \
- && _G_ac_init=`$SED "$_G_sed_no_comment" "$1" |$GREP AC_INIT`
-
- # Otherwise it is not a genuine Autoconf input file.
- test -n "$_G_ac_init"
- _G_status=$?
-
- test 0 -ne "$_G_status" \
- && func_verbose "'$1' not using Autoconf"
-
- (exit $_G_status)
-}
-
-
-# func_find_tool ENVVAR NAMES...
-# ------------------------------
-# Search for a required program. Use the value of ENVVAR, if set,
-# otherwise find the first of the NAMES that can be run (i.e.,
-# supports --version). If found, set ENVVAR to the program name,
-# die otherwise.
-func_find_tool ()
-{
- $debug_cmd
-
- _G_find_tool_envvar=$1
- shift
- _G_find_tool_names=$@
- eval "_G_find_tool_res=\$$_G_find_tool_envvar"
- if test -n "$_G_find_tool_res"; then
- _G_find_tool_error_prefix="\$$find_tool_envvar: "
- else
- for _G_prog
- do
- if func_tool_version_output $_G_prog >/dev/null; then
- _G_find_tool_res=$_G_prog
- break
- fi
- done
- fi
- if test -n "$_G_find_tool_res"; then
- func_tool_version_output >/dev/null $_G_find_tool_res "\
-${_G_find_tool_error_prefix}Cannot run '$_G_find_tool_res --version'"
-
- # Make sure the result is exported to the environment for children
- # to use.
- eval "$_G_find_tool_envvar=\$_G_find_tool_res"
- eval "export $_G_find_tool_envvar"
- else
- func_error "\
-One of these is required:
- $_G_find_tool_names"
- fi
-}
-
-
-# func_tool_version_output CMD [FATAL-ERROR-MSG]
-# ----------------------------------------------
-# Attempt to run 'CMD --version', discarding errors. The output can be
-# ignored by redirecting stdout, and this function used simply to test
-# whether the command exists and exits normally when passed a
-# '--version' argument.
-# When FATAL-ERROR-MSG is given, then this function will display the
-# message and exit if running 'CMD --version' returns a non-zero exit
-# status.
-func_tool_version_output ()
-{
- $debug_cmd
-
- _G_cmd=$1
- _G_fatal_error_msg=$2
-
- # Some tools, like 'git2cl' produce thousands of lines of output
- # unless stdin is /dev/null - in that case we want to return
- # successfully without saving all of that output. Other tools,
- # such as 'help2man' exit with a non-zero status when stdin comes
- # from /dev/null, so we re-execute without /dev/null if that
- # happens. This means that occasionally, the output from both calls
- # ends up in the result, but the alternative would be to discard the
- # output from one call, and hope the other produces something useful.
- { $_G_cmd --version </dev/null || $_G_cmd --version; } 2>/dev/null
- _G_status=$?
-
- test 0 -ne "$_G_status" && test -n "$_G_fatal_error_msg" \
- && func_fatal_error "$_G_fatal_error_msg"
-
- (exit $_G_status)
-}
-
-
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
-
-# This section contains definitions for functions that each ensure a
-# particular resource (a file, or a non-empty configuration variable for
-# example) is available, and if appropriate to extract default values
-# from pertinent package files. Where a variable already has a non-
-# empty value (as set by the package's 'bootstrap.conf'), that value is
-# used in preference to deriving the default. Call them using their
-# associated 'require_*' variable to ensure that they are executed, at
-# most, once.
-#
-# It's entirely deliberate that calling these functions can set
-# variables that don't obey the namespace limitations obeyed by the rest
-# of this file, in order that that they be as useful as possible to
-# callers.
-
-
-# require_configure_ac
-# --------------------
-# Ensure that there is a 'configure.ac' or 'configure.in' file in the
-# current directory that contains an uncommented call to AC_INIT, and
-# that '$configure_ac' contains its name.
-require_configure_ac=func_require_configure_ac
-func_require_configure_ac ()
-{
- $debug_cmd
-
- test -z "$configure_ac" \
- && func_autoconf_configure configure.ac && configure_ac=configure.ac
- test -z "$configure_ac" \
- && func_autoconf_configure configure.in && configure_ac=configure.in
- test -z "$configure_ac" \
- || func_verbose "found '$configure_ac'"
-
- require_configure_ac=:
-}
-
-
-# require_gnu_m4
-# --------------
-# Search for GNU M4, and export it in $M4.
-require_gnu_m4=func_require_gnu_m4
-func_require_gnu_m4 ()
-{
- $debug_cmd
-
- test -n "$M4" || {
- # Find the first m4 binary that responds to --version.
- func_find_tool M4 gm4 gnum4 m4
- }
-
- test -n "$M4" || func_fatal_error "\
-Please install GNU M4, or 'export M4=/path/to/gnu/m4'."
-
- func_verbose "export M4='$M4'"
-
- # Make sure the search result is visible to subshells
- export M4
-
- require_gnu_m4=:
-}
-
-
-## --------------- ##
-## Core functions. ##
-## --------------- ##
-
-# This section contains the high level functions used when calling this
-# file as a script. 'func_extract_trace' is probably the only one that you
-# won't want to replace if you source this file into your own script.
-
-
-# func_extract_trace MACRO_NAMES [FILENAME]...
-# --------------------------------------------
-# set '$func_extract_trace_result' to a colon delimited list of arguments
-# to any of the comma separated list of MACRO_NAMES in FILENAME. If no
-# FILENAME is given, then '$configure_ac' is assumed.
-func_extract_trace ()
-{
- $debug_cmd
-
- $require_configure_ac
- $require_gnu_m4
-
- _G_m4_traces=`$ECHO "--trace=$1" |$SED 's%,% --trace=%g'`
- _G_re_macros=`$ECHO "($1)" |$SED 's%,%|%g'`
- _G_macros="$1"; shift
- test $# -gt 0 || {
- set dummy $configure_ac
- shift
- }
-
- # Generate an error if the first file is missing
- <"$1"
-
- # Sadly, we can't use 'autom4te' tracing to extract macro arguments,
- # because it complains about things we want to ignore at bootstrap
- # time - like missing m4_include files; AC_PREREQ being newer than
- # the installed autoconf; and returns nothing when tracing
- # 'AM_INIT_AUTOMAKE' when aclocal hasn't been generated yet.
- #
- # The following tries to emulate a less persnickety version of (and
- # due to not having to wait for Perl startup on every invocation,
- # it's probably faster too):
- #
- # autom4te --language=Autoconf --trace=$my_macro:\$% "$@"
- #
- # First we give a minimal set of macro declarations to M4 to prime
- # it for reading Autoconf macros, while still providing some of the
- # functionality generally used at m4-time to supply dynamic
- # arguments to Autocof functions, but without following
- # 'm4_s?include' files.
- _G_mini='
- # Initialisation.
- m4_changequote([,])
- m4_define([m4_copy], [m4_define([$2], m4_defn([$1]))])
- m4_define([m4_rename], [m4_copy([$1], [$2])m4_undefine([$1])])
-
- # Disable these macros.
- m4_undefine([m4_dnl])
- m4_undefine([m4_include])
- m4_undefine([m4_m4exit])
- m4_undefine([m4_m4wrap])
- m4_undefine([m4_maketemp])
-
- # Copy and rename macros not handled by "m4 --prefix".
- m4_define([dnl], [m4_builtin([dnl])])
- m4_copy([m4_define], [m4_defun])
- m4_rename([m4_ifelse], [m4_if])
- m4_ifdef([m4_mkstemp], [m4_undefine([m4_mkstemp])])
- m4_rename([m4_patsubst], [m4_bpatsubst])
- m4_rename([m4_regexp], [m4_bregexp])
-
- # "m4sugar.mini" - useful m4-time macros for dynamic arguments.
- # If we discover packages that need more m4 macros defined in
- # order to bootstrap correctly, add them here:
- m4_define([m4_bmatch],
- [m4_if([$#], 0, [], [$#], 1, [], [$#], 2, [$2],
- [m4_if(m4_bregexp([$1], [$2]), -1,
- [$0([$1], m4_shift3($@))], [$3])])])
- m4_define([m4_ifndef], [m4_ifdef([$1], [$3], [$2])])
- m4_define([m4_ifset],
- [m4_ifdef([$1], [m4_ifval(m4_defn([$1]), [$2], [$3])], [$3])])
- m4_define([m4_require], [$1])
- m4_define([m4_shift3], [m4_shift(m4shift(m4shift($@)))])
-
- # "autoconf.mini" - things from autoconf macros we care about.
- m4_copy([m4_defun], [AC_DEFUN])
-
- # Dummy definitions for the macros we want to trace.
- # AM_INIT_AUTOMAKE at least produces no trace without this.
- '
-
- _G_save=$IFS
- IFS=,
- for _G_macro in $_G_macros; do
- IFS=$_G_save
- func_append _G_mini "AC_DEFUN([$_G_macro])$nl"
- done
- IFS=$_G_save
-
- # We discard M4's stdout, but the M4 trace output from reading our
- # "autoconf.mini" followed by any other files passed to this
- # function is then scanned by sed to transform it into a colon
- # delimited argument list assigned to a shell variable.
- _G_transform='s|#.*$||; s|^dnl .*$||; s| dnl .*$||;'
-
- # Unfortunately, alternation in regexp addresses doesn't work in at
- # least BSD (and hence Mac OS X) sed, so we have to append a capture
- # and print block for each traced macro to the sed transform script.
- _G_save=$IFS
- IFS=,
- for _G_macro in $_G_macros; do
- IFS=$_G_save
- func_append _G_transform '
- /^m4trace: -1- '"$_G_macro"'/ {
- s|^m4trace: -1- '"$_G_macro"'[([]*||
- s|], [[]|:|g
- s|[])]*$|:|
- s|\(.\):$|\1|
- p
- }'
- done
- IFS=$_G_save
-
- # Save the command pipeline results for further use by callers of
- # this function.
- func_extract_trace_result=`$ECHO "$_G_mini" \
- |$M4 -daq --prefix $_G_m4_traces - "$@" 2>&1 1>/dev/null \
- |$SED -n -e "$_G_transform"`
-}
-
-
-# func_extract_trace_first MACRO_NAMES [FILENAME]...
-# --------------------------------------------------
-# Exactly like func_extract_trace, except that only the first argument
-# to the first invocation of one of the comma separated MACRO_NAMES is
-# returned in '$func_extract_trace_first_result'.
-func_extract_trace_first ()
-{
- $debug_cmd
-
- func_extract_trace ${1+"$@"}
- func_extract_trace_first_result=`$ECHO "$func_extract_trace_result" \
- |$SED -e 's|:.*$||g' -e 1q`
-}
-
-
-# func_main [ARG]...
-# ------------------
-func_main ()
-{
- $debug_cmd
-
- # Configuration.
- usage='$progname MACRO_NAME FILE [...]'
-
- long_help_message='
-The first argument to this program is the name of an autotools macro
-whose arguments you want to extract by examining the files listed in the
-remaining arguments using the same tool that Autoconf and Automake use,
-GNU M4.
-
-The arguments are returned separated by colons, with each traced call
-on a separate line.'
-
- # Option processing.
- func_options "$@"
- eval set dummy "$func_options_result"; shift
-
- # Validate remaining non-option arguments.
- test $# -gt 1 \
- || func_fatal_help "not enough arguments"
-
- # Pass non-option arguments to extraction function.
- func_extract_trace "$@"
-
- # Display results.
- test -n "$func_extract_trace_result" \
- && $ECHO "$func_extract_trace_result"
-
- # The End.
- exit $EXIT_SUCCESS
-}
-
-
-## --------------------------- ##
-## Actually perform the trace. ##
-## --------------------------- ##
-
-# Only call 'func_main' if this script was called directly.
-test extract-trace = "$progname" && func_main "$@"
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "20/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
diff --git a/build-aux/gl/build-aux/funclib.sh b/build-aux/gl/build-aux/funclib.sh
deleted file mode 100644
index fbe8b67d..00000000
--- a/build-aux/gl/build-aux/funclib.sh
+++ /dev/null
@@ -1,1304 +0,0 @@
-# Set a version string for this script.
-scriptversion=2014-01-03.01; # UTC
-
-# General shell script boiler plate, and helper functions.
-# Written by Gary V. Vaughan, 2004
-
-# Copyright (C) 2004-2014, 2017 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-
-# As a special exception to the GNU General Public License, if you distribute
-# this file as part of a program or library that is built using GNU Libtool,
-# you may include this file under the same distribution terms that you use
-# for the rest of that program.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNES FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Evaluate this file near the top of your script to gain access to
-# the functions and variables defined here:
-#
-# . `echo "$0" | ${SED-sed} 's|[^/]*$||'`/build-aux/funclib.sh
-#
-# If you need to override any of the default environment variable
-# settings, do that before evaluating this file.
-
-
-## -------------------- ##
-## Shell normalisation. ##
-## -------------------- ##
-
-# Some shells need a little help to be as Bourne compatible as possible.
-# Before doing anything else, make sure all that help has been provided!
-
-DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
- emulate sh
- NULLCMD=:
- # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac
-fi
-
-# NLS nuisances: We save the old values in case they are required later.
-_G_user_locale=
-_G_safe_locale=
-for _G_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
-do
- eval "if test set = \"\${$_G_var+set}\"; then
- save_$_G_var=\$$_G_var
- $_G_var=C
- export $_G_var
- _G_user_locale=\"$_G_var=\\\$save_\$_G_var; \$_G_user_locale\"
- _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\"
- fi"
-done
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-# Make sure IFS has a sensible default
-sp=' '
-nl='
-'
-IFS="$sp $nl"
-
-# There are apparently some retarded systems that use ';' as a PATH separator!
-if test "${PATH_SEPARATOR+set}" != set; then
- PATH_SEPARATOR=:
- (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
- (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
- PATH_SEPARATOR=';'
- }
-fi
-
-
-
-## ------------------------- ##
-## Locate command utilities. ##
-## ------------------------- ##
-
-
-# func_executable_p FILE
-# ----------------------
-# Check that FILE is an executable regular file.
-func_executable_p ()
-{
- test -f "$1" && test -x "$1"
-}
-
-
-# func_path_progs PROGS_LIST CHECK_FUNC [PATH]
-# --------------------------------------------
-# Search for either a program that responds to --version with output
-# containing "GNU", or else returned by CHECK_FUNC otherwise, by
-# trying all the directories in PATH with each of the elements of
-# PROGS_LIST.
-#
-# CHECK_FUNC should accept the path to a candidate program, and
-# set $func_check_prog_result if it truncates its output less than
-# $_G_path_prog_max characters.
-func_path_progs ()
-{
- _G_progs_list=$1
- _G_check_func=$2
- _G_PATH=${3-"$PATH"}
-
- _G_path_prog_max=0
- _G_path_prog_found=false
- _G_save_IFS=$IFS; IFS=$PATH_SEPARATOR
- for _G_dir in $_G_PATH; do
- IFS=$_G_save_IFS
- test -z "$_G_dir" && _G_dir=.
- for _G_prog_name in $_G_progs_list; do
- for _exeext in '' .EXE; do
- _G_path_prog=$_G_dir/$_G_prog_name$_exeext
- func_executable_p "$_G_path_prog" || continue
- case `"$_G_path_prog" --version 2>&1` in
- *GNU*) func_path_progs_result=$_G_path_prog _G_path_prog_found=: ;;
- *) $_G_check_func $_G_path_prog
- func_path_progs_result=$func_check_prog_result
- ;;
- esac
- $_G_path_prog_found && break 3
- done
- done
- done
- IFS=$_G_save_IFS
- test -z "$func_path_progs_result" && {
- echo "no acceptable sed could be found in \$PATH" >&2
- exit 1
- }
-}
-
-
-# We want to be able to use the functions in this file before configure
-# has figured out where the best binaries are kept, which means we have
-# to search for them ourselves - except when the results are already set
-# where we skip the searches.
-
-# Unless the user overrides by setting SED, search the path for either GNU
-# sed, or the sed that truncates its output the least.
-test -z "$SED" && {
- _G_sed_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
- for _G_i in 1 2 3 4 5 6 7; do
- _G_sed_script=$_G_sed_script$nl$_G_sed_script
- done
- echo "$_G_sed_script" 2>/dev/null | sed 99q >conftest.sed
- _G_sed_script=
-
- func_check_prog_sed ()
- {
- _G_path_prog=$1
-
- _G_count=0
- printf 0123456789 >conftest.in
- while :
- do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo '' >> conftest.nl
- "$_G_path_prog" -f conftest.sed <conftest.nl >conftest.out 2>/dev/null || break
- diff conftest.out conftest.nl >/dev/null 2>&1 || break
- _G_count=`expr $_G_count + 1`
- if test "$_G_count" -gt "$_G_path_prog_max"; then
- # Best one so far, save it but keep looking for a better one
- func_check_prog_result=$_G_path_prog
- _G_path_prog_max=$_G_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test 10 -lt "$_G_count" && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out
- }
-
- func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin
- rm -f conftest.sed
- SED=$func_path_progs_result
-}
-
-
-# Unless the user overrides by setting GREP, search the path for either GNU
-# grep, or the grep that truncates its output the least.
-test -z "$GREP" && {
- func_check_prog_grep ()
- {
- _G_path_prog=$1
-
- _G_count=0
- _G_path_prog_max=0
- printf 0123456789 >conftest.in
- while :
- do
- cat conftest.in conftest.in >conftest.tmp
- mv conftest.tmp conftest.in
- cp conftest.in conftest.nl
- echo 'GREP' >> conftest.nl
- "$_G_path_prog" -e 'GREP$' -e '-(cannot match)-' <conftest.nl >conftest.out 2>/dev/null || break
- diff conftest.out conftest.nl >/dev/null 2>&1 || break
- _G_count=`expr $_G_count + 1`
- if test "$_G_count" -gt "$_G_path_prog_max"; then
- # Best one so far, save it but keep looking for a better one
- func_check_prog_result=$_G_path_prog
- _G_path_prog_max=$_G_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test 10 -lt "$_G_count" && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out
- }
-
- func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin
- GREP=$func_path_progs_result
-}
-
-
-## ------------------------------- ##
-## User overridable command paths. ##
-## ------------------------------- ##
-
-# All uppercase variable names are used for environment variables. These
-# variables can be overridden by the user before calling a script that
-# uses them if a suitable command of that name is not already available
-# in the command search PATH.
-
-: ${CP="cp -f"}
-: ${ECHO="printf %s\n"}
-: ${EGREP="$GREP -E"}
-: ${FGREP="$GREP -F"}
-: ${LN_S="ln -s"}
-: ${MAKE="make"}
-: ${MKDIR="mkdir"}
-: ${MV="mv -f"}
-: ${RM="rm -f"}
-: ${SHELL="${CONFIG_SHELL-/bin/sh}"}
-
-
-## -------------------- ##
-## Useful sed snippets. ##
-## -------------------- ##
-
-sed_dirname='s|/[^/]*$||'
-sed_basename='s|^.*/||'
-
-# Sed substitution that helps us do robust quoting. It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s|\([`"$\\]\)|\\\1|g'
-
-# Same as above, but do not quote variable references.
-sed_double_quote_subst='s/\(["`\\]\)/\\\1/g'
-
-# Sed substitution that turns a string into a regex matching for the
-# string literally.
-sed_make_literal_regex='s|[].[^$\\*\/]|\\&|g'
-
-# Sed substitution that converts a w32 file name or path
-# that contains forward slashes, into one that contains
-# (escaped) backslashes. A very naive implementation.
-sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
-
-# Re-'\' parameter expansions in output of sed_double_quote_subst that
-# were '\'-ed in input to the same. If an odd number of '\' preceded a
-# '$' in input to sed_double_quote_subst, that '$' was protected from
-# expansion. Since each input '\' is now two '\'s, look for any number
-# of runs of four '\'s followed by two '\'s and then a '$'. '\' that '$'.
-_G_bs='\\'
-_G_bs2='\\\\'
-_G_bs4='\\\\\\\\'
-_G_dollar='\$'
-sed_double_backslash="\
- s/$_G_bs4/&\\
-/g
- s/^$_G_bs2$_G_dollar/$_G_bs&/
- s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g
- s/\n//g"
-
-
-## ----------------- ##
-## Global variables. ##
-## ----------------- ##
-
-# Except for the global variables explicitly listed below, the following
-# functions in the '^func_' namespace, and the '^require_' namespace
-# variables initialised in the 'Resource management' section, sourcing
-# this file will not pollute your global namespace with anything
-# else. There's no portable way to scope variables in Bourne shell
-# though, so actually running these functions will sometimes place
-# results into a variable named after the function, and often use
-# temporary variables in the '^_G_' namespace. If you are careful to
-# avoid using those namespaces casually in your sourcing script, things
-# should continue to work as you expect. And, of course, you can freely
-# overwrite any of the functions or variables defined here before
-# calling anything to customize them.
-
-EXIT_SUCCESS=0
-EXIT_FAILURE=1
-EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing.
-EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake.
-
-# Allow overriding, eg assuming that you follow the convention of
-# putting '$debug_cmd' at the start of all your functions, you can get
-# bash to show function call trace with:
-#
-# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name
-debug_cmd=${debug_cmd-":"}
-exit_cmd=:
-
-# By convention, finish your script with:
-#
-# exit $exit_status
-#
-# so that you can set exit_status to non-zero if you want to indicate
-# something went wrong during execution without actually bailing out at
-# the point of failure.
-exit_status=$EXIT_SUCCESS
-
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath=$0
-
-# The name of this program.
-progname=`$ECHO "$progpath" |$SED "$sed_basename"`
-
-# Make sure we have an absolute progpath for reexecution:
-case $progpath in
- [\\/]*|[A-Za-z]:\\*) ;;
- *[\\/]*)
- progdir=`$ECHO "$progpath" |$SED "$sed_dirname"`
- progdir=`cd "$progdir" && pwd`
- progpath=$progdir/$progname
- ;;
- *)
- _G_IFS=$IFS
- IFS=${PATH_SEPARATOR-:}
- for progdir in $PATH; do
- IFS=$_G_IFS
- test -x "$progdir/$progname" && break
- done
- IFS=$_G_IFS
- test -n "$progdir" || progdir=`pwd`
- progpath=$progdir/$progname
- ;;
-esac
-
-
-## ----------------- ##
-## Standard options. ##
-## ----------------- ##
-
-# The following options affect the operation of the functions defined
-# below, and should be set appropriately depending on run-time para-
-# meters passed on the command line.
-
-opt_dry_run=false
-opt_quiet=false
-opt_verbose=false
-
-# Categories 'all' and 'none' are always available. Append any others
-# you will pass as the first argument to func_warning from your own
-# code.
-warning_categories=
-
-# By default, display warnings according to 'opt_warning_types'. Set
-# 'warning_func' to ':' to elide all warnings, or func_fatal_error to
-# treat the next displayed warning as a fatal error.
-warning_func=func_warn_and_continue
-
-# Set to 'all' to display all warnings, 'none' to suppress all
-# warnings, or a space delimited list of some subset of
-# 'warning_categories' to display only the listed warnings.
-opt_warning_types=all
-
-
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
-
-# This section contains definitions for functions that each ensure a
-# particular resource (a file, or a non-empty configuration variable for
-# example) is available, and if appropriate to extract default values
-# from pertinent package files. Call them using their associated
-# 'require_*' variable to ensure that they are executed, at most, once.
-#
-# It's entirely deliberate that calling these functions can set
-# variables that don't obey the namespace limitations obeyed by the rest
-# of this file, in order that that they be as useful as possible to
-# callers.
-
-
-# require_term_colors
-# -------------------
-# Allow display of bold text on terminals that support it.
-require_term_colors=func_require_term_colors
-func_require_term_colors ()
-{
- $debug_cmd
-
- test -t 1 && {
- # COLORTERM and USE_ANSI_COLORS environment variables take
- # precedence, because most terminfo databases neglect to describe
- # whether color sequences are supported.
- test -n "${COLORTERM+set}" && : ${USE_ANSI_COLORS="1"}
-
- if test 1 = "$USE_ANSI_COLORS"; then
- # Standard ANSI escape sequences
- tc_reset=''
- tc_bold=''; tc_standout=''
- tc_red=''; tc_green=''
- tc_blue=''; tc_cyan=''
- else
- # Otherwise trust the terminfo database after all.
- test -n "`tput sgr0 2>/dev/null`" && {
- tc_reset=`tput sgr0`
- test -n "`tput bold 2>/dev/null`" && tc_bold=`tput bold`
- tc_standout=$tc_bold
- test -n "`tput smso 2>/dev/null`" && tc_standout=`tput smso`
- test -n "`tput setaf 1 2>/dev/null`" && tc_red=`tput setaf 1`
- test -n "`tput setaf 2 2>/dev/null`" && tc_green=`tput setaf 2`
- test -n "`tput setaf 4 2>/dev/null`" && tc_blue=`tput setaf 4`
- test -n "`tput setaf 5 2>/dev/null`" && tc_cyan=`tput setaf 5`
- }
- fi
- }
-
- require_term_colors=:
-}
-
-
-## ----------------- ##
-## Function library. ##
-## ----------------- ##
-
-# This section contains a variety of useful functions to call in your
-# scripts. Take note of the portable wrappers for features provided by
-# some modern shells, which will fall back to slower equivalents on
-# less featureful shells.
-
-
-# func_append VAR VALUE
-# ---------------------
-# Append VALUE onto the existing contents of VAR.
-
- # We should try to minimise forks, especially on Windows where they are
- # unreasonably slow, so skip the feature probes when bash or zsh are
- # being used:
- if test set = "${BASH_VERSION+set}${ZSH_VERSION+set}"; then
- : ${_G_HAVE_ARITH_OP="yes"}
- : ${_G_HAVE_XSI_OPS="yes"}
- # The += operator was introduced in bash 3.1
- case $BASH_VERSION in
- [12].* | 3.0 | 3.0*) ;;
- *)
- : ${_G_HAVE_PLUSEQ_OP="yes"}
- ;;
- esac
- fi
-
- # _G_HAVE_PLUSEQ_OP
- # Can be empty, in which case the shell is probed, "yes" if += is
- # useable or anything else if it does not work.
- test -z "$_G_HAVE_PLUSEQ_OP" \
- && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \
- && _G_HAVE_PLUSEQ_OP=yes
-
-if test yes = "$_G_HAVE_PLUSEQ_OP"
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_append ()
- {
- $debug_cmd
-
- eval "$1+=\$2"
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_append ()
- {
- $debug_cmd
-
- eval "$1=\$$1\$2"
- }
-fi
-
-
-# func_append_quoted VAR VALUE
-# ----------------------------
-# Quote VALUE and append to the end of shell variable VAR, separated
-# by a space.
-if test yes = "$_G_HAVE_PLUSEQ_OP"; then
- eval 'func_append_quoted ()
- {
- $debug_cmd
-
- func_quote_for_eval "$2"
- eval "$1+=\\ \$func_quote_for_eval_result"
- }'
-else
- func_append_quoted ()
- {
- $debug_cmd
-
- func_quote_for_eval "$2"
- eval "$1=\$$1\\ \$func_quote_for_eval_result"
- }
-fi
-
-
-# func_append_uniq VAR VALUE
-# --------------------------
-# Append unique VALUE onto the existing contents of VAR, assuming
-# entries are delimited by the first character of VALUE. For example:
-#
-# func_append_uniq options " --another-option option-argument"
-#
-# will only append to $options if " --another-option option-argument "
-# is not already present somewhere in $options already (note spaces at
-# each end implied by leading space in second argument).
-func_append_uniq ()
-{
- $debug_cmd
-
- eval _G_current_value='`$ECHO $'$1'`'
- _G_delim=`expr "$2" : '\(.\)'`
-
- case $_G_delim$_G_current_value$_G_delim in
- *"$2$_G_delim"*) ;;
- *) func_append "$@" ;;
- esac
-}
-
-
-# func_arith TERM...
-# ------------------
-# Set func_arith_result to the result of evaluating TERMs.
- test -z "$_G_HAVE_ARITH_OP" \
- && (eval 'test 2 = $(( 1 + 1 ))') 2>/dev/null \
- && _G_HAVE_ARITH_OP=yes
-
-if test yes = "$_G_HAVE_ARITH_OP"; then
- eval 'func_arith ()
- {
- $debug_cmd
-
- func_arith_result=$(( $* ))
- }'
-else
- func_arith ()
- {
- $debug_cmd
-
- func_arith_result=`expr "$@"`
- }
-fi
-
-
-# func_basename FILE
-# ------------------
-# Set func_basename_result to FILE with everything up to and including
-# the last / stripped.
-if test yes = "$_G_HAVE_XSI_OPS"; then
- # If this shell supports suffix pattern removal, then use it to avoid
- # forking. Hide the definitions single quotes in case the shell chokes
- # on unsupported syntax...
- _b='func_basename_result=${1##*/}'
- _d='case $1 in
- */*) func_dirname_result=${1%/*}$2 ;;
- * ) func_dirname_result=$3 ;;
- esac'
-
-else
- # ...otherwise fall back to using sed.
- _b='func_basename_result=`$ECHO "$1" |$SED "$sed_basename"`'
- _d='func_dirname_result=`$ECHO "$1" |$SED "$sed_dirname"`
- if test "X$func_dirname_result" = "X$1"; then
- func_dirname_result=$3
- else
- func_append func_dirname_result "$2"
- fi'
-fi
-
-eval 'func_basename ()
-{
- $debug_cmd
-
- '"$_b"'
-}'
-
-
-# func_dirname FILE APPEND NONDIR_REPLACEMENT
-# -------------------------------------------
-# Compute the dirname of FILE. If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-eval 'func_dirname ()
-{
- $debug_cmd
-
- '"$_d"'
-}'
-
-
-# func_dirname_and_basename FILE APPEND NONDIR_REPLACEMENT
-# --------------------------------------------------------
-# Perform func_basename and func_dirname in a single function
-# call:
-# dirname: Compute the dirname of FILE. If nonempty,
-# add APPEND to the result, otherwise set result
-# to NONDIR_REPLACEMENT.
-# value returned in "$func_dirname_result"
-# basename: Compute filename of FILE.
-# value retuned in "$func_basename_result"
-# For efficiency, we do not delegate to the functions above but instead
-# duplicate the functionality here.
-eval 'func_dirname_and_basename ()
-{
- $debug_cmd
-
- '"$_b"'
- '"$_d"'
-}'
-
-
-# func_echo ARG...
-# ----------------
-# Echo program name prefixed message.
-func_echo ()
-{
- $debug_cmd
-
- _G_message=$*
-
- func_echo_IFS=$IFS
- IFS=$nl
- for _G_line in $_G_message; do
- IFS=$func_echo_IFS
- $ECHO "$progname: $_G_line"
- done
- IFS=$func_echo_IFS
-}
-
-
-# func_echo_all ARG...
-# --------------------
-# Invoke $ECHO with all args, space-separated.
-func_echo_all ()
-{
- $ECHO "$*"
-}
-
-
-# func_echo_infix_1 INFIX ARG...
-# ------------------------------
-# Echo program name, followed by INFIX on the first line, with any
-# additional lines not showing INFIX.
-func_echo_infix_1 ()
-{
- $debug_cmd
-
- $require_term_colors
-
- _G_infix=$1; shift
- _G_indent=$_G_infix
- _G_prefix="$progname: $_G_infix: "
- _G_message=$*
-
- # Strip color escape sequences before counting printable length
- for _G_tc in "$tc_reset" "$tc_bold" "$tc_standout" "$tc_red" "$tc_green" "$tc_blue" "$tc_cyan"
- do
- test -n "$_G_tc" && {
- _G_esc_tc=`$ECHO "$_G_tc" | $SED "$sed_make_literal_regex"`
- _G_indent=`$ECHO "$_G_indent" | $SED "s|$_G_esc_tc||g"`
- }
- done
- _G_indent="$progname: "`echo "$_G_indent" | $SED 's|.| |g'`" " ## exclude from sc_prohibit_nested_quotes
-
- func_echo_infix_1_IFS=$IFS
- IFS=$nl
- for _G_line in $_G_message; do
- IFS=$func_echo_infix_1_IFS
- $ECHO "$_G_prefix$tc_bold$_G_line$tc_reset" >&2
- _G_prefix=$_G_indent
- done
- IFS=$func_echo_infix_1_IFS
-}
-
-
-# func_error ARG...
-# -----------------
-# Echo program name prefixed message to standard error.
-func_error ()
-{
- $debug_cmd
-
- $require_term_colors
-
- func_echo_infix_1 " $tc_standout${tc_red}error$tc_reset" "$*" >&2
-}
-
-
-# func_fatal_error ARG...
-# -----------------------
-# Echo program name prefixed message to standard error, and exit.
-func_fatal_error ()
-{
- $debug_cmd
-
- func_error "$*"
- exit $EXIT_FAILURE
-}
-
-
-# func_grep EXPRESSION FILENAME
-# -----------------------------
-# Check whether EXPRESSION matches any line of FILENAME, without output.
-func_grep ()
-{
- $debug_cmd
-
- $GREP "$1" "$2" >/dev/null 2>&1
-}
-
-
-# func_len STRING
-# ---------------
-# Set func_len_result to the length of STRING. STRING may not
-# start with a hyphen.
- test -z "$_G_HAVE_XSI_OPS" \
- && (eval 'x=a/b/c;
- test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
- && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"; then
- eval 'func_len ()
- {
- $debug_cmd
-
- func_len_result=${#1}
- }'
-else
- func_len ()
- {
- $debug_cmd
-
- func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
- }
-fi
-
-
-# func_mkdir_p DIRECTORY-PATH
-# ---------------------------
-# Make sure the entire path to DIRECTORY-PATH is available.
-func_mkdir_p ()
-{
- $debug_cmd
-
- _G_directory_path=$1
- _G_dir_list=
-
- if test -n "$_G_directory_path" && test : != "$opt_dry_run"; then
-
- # Protect directory names starting with '-'
- case $_G_directory_path in
- -*) _G_directory_path=./$_G_directory_path ;;
- esac
-
- # While some portion of DIR does not yet exist...
- while test ! -d "$_G_directory_path"; do
- # ...make a list in topmost first order. Use a colon delimited
- # list incase some portion of path contains whitespace.
- _G_dir_list=$_G_directory_path:$_G_dir_list
-
- # If the last portion added has no slash in it, the list is done
- case $_G_directory_path in */*) ;; *) break ;; esac
-
- # ...otherwise throw away the child directory and loop
- _G_directory_path=`$ECHO "$_G_directory_path" | $SED -e "$sed_dirname"`
- done
- _G_dir_list=`$ECHO "$_G_dir_list" | $SED 's|:*$||'`
-
- func_mkdir_p_IFS=$IFS; IFS=:
- for _G_dir in $_G_dir_list; do
- IFS=$func_mkdir_p_IFS
- # mkdir can fail with a 'File exist' error if two processes
- # try to create one of the directories concurrently. Don't
- # stop in that case!
- $MKDIR "$_G_dir" 2>/dev/null || :
- done
- IFS=$func_mkdir_p_IFS
-
- # Bail out if we (or some other process) failed to create a directory.
- test -d "$_G_directory_path" || \
- func_fatal_error "Failed to create '$1'"
- fi
-}
-
-
-# func_mktempdir [BASENAME]
-# -------------------------
-# Make a temporary directory that won't clash with other running
-# libtool processes, and avoids race conditions if possible. If
-# given, BASENAME is the basename for that directory.
-func_mktempdir ()
-{
- $debug_cmd
-
- _G_template=${TMPDIR-/tmp}/${1-$progname}
-
- if test : = "$opt_dry_run"; then
- # Return a directory name, but don't create it in dry-run mode
- _G_tmpdir=$_G_template-$$
- else
-
- # If mktemp works, use that first and foremost
- _G_tmpdir=`mktemp -d "$_G_template-XXXXXXXX" 2>/dev/null`
-
- if test ! -d "$_G_tmpdir"; then
- # Failing that, at least try and use $RANDOM to avoid a race
- _G_tmpdir=$_G_template-${RANDOM-0}$$
-
- func_mktempdir_umask=`umask`
- umask 0077
- $MKDIR "$_G_tmpdir"
- umask $func_mktempdir_umask
- fi
-
- # If we're not in dry-run mode, bomb out on failure
- test -d "$_G_tmpdir" || \
- func_fatal_error "cannot create temporary directory '$_G_tmpdir'"
- fi
-
- $ECHO "$_G_tmpdir"
-}
-
-
-# func_normal_abspath PATH
-# ------------------------
-# Remove doubled-up and trailing slashes, "." path components,
-# and cancel out any ".." path components in PATH after making
-# it an absolute path.
-func_normal_abspath ()
-{
- $debug_cmd
-
- # These SED scripts presuppose an absolute path with a trailing slash.
- _G_pathcar='s|^/\([^/]*\).*$|\1|'
- _G_pathcdr='s|^/[^/]*||'
- _G_removedotparts=':dotsl
- s|/\./|/|g
- t dotsl
- s|/\.$|/|'
- _G_collapseslashes='s|/\{1,\}|/|g'
- _G_finalslash='s|/*$|/|'
-
- # Start from root dir and reassemble the path.
- func_normal_abspath_result=
- func_normal_abspath_tpath=$1
- func_normal_abspath_altnamespace=
- case $func_normal_abspath_tpath in
- "")
- # Empty path, that just means $cwd.
- func_stripname '' '/' "`pwd`"
- func_normal_abspath_result=$func_stripname_result
- return
- ;;
- # The next three entries are used to spot a run of precisely
- # two leading slashes without using negated character classes;
- # we take advantage of case's first-match behaviour.
- ///*)
- # Unusual form of absolute path, do nothing.
- ;;
- //*)
- # Not necessarily an ordinary path; POSIX reserves leading '//'
- # and for example Cygwin uses it to access remote file shares
- # over CIFS/SMB, so we conserve a leading double slash if found.
- func_normal_abspath_altnamespace=/
- ;;
- /*)
- # Absolute path, do nothing.
- ;;
- *)
- # Relative path, prepend $cwd.
- func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
- ;;
- esac
-
- # Cancel out all the simple stuff to save iterations. We also want
- # the path to end with a slash for ease of parsing, so make sure
- # there is one (and only one) here.
- func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
- -e "$_G_removedotparts" -e "$_G_collapseslashes" -e "$_G_finalslash"`
- while :; do
- # Processed it all yet?
- if test / = "$func_normal_abspath_tpath"; then
- # If we ascended to the root using ".." the result may be empty now.
- if test -z "$func_normal_abspath_result"; then
- func_normal_abspath_result=/
- fi
- break
- fi
- func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
- -e "$_G_pathcar"`
- func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
- -e "$_G_pathcdr"`
- # Figure out what to do with it
- case $func_normal_abspath_tcomponent in
- "")
- # Trailing empty path component, ignore it.
- ;;
- ..)
- # Parent dir; strip last assembled component from result.
- func_dirname "$func_normal_abspath_result"
- func_normal_abspath_result=$func_dirname_result
- ;;
- *)
- # Actual path component, append it.
- func_append func_normal_abspath_result "/$func_normal_abspath_tcomponent"
- ;;
- esac
- done
- # Restore leading double-slash if one was found on entry.
- func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
-}
-
-
-# func_notquiet ARG...
-# --------------------
-# Echo program name prefixed message only when not in quiet mode.
-func_notquiet ()
-{
- $debug_cmd
-
- $opt_quiet || func_echo ${1+"$@"}
-
- # A bug in bash halts the script if the last line of a function
- # fails when set -e is in force, so we need another command to
- # work around that:
- :
-}
-
-
-# func_relative_path SRCDIR DSTDIR
-# --------------------------------
-# Set func_relative_path_result to the relative path from SRCDIR to DSTDIR.
-func_relative_path ()
-{
- $debug_cmd
-
- func_relative_path_result=
- func_normal_abspath "$1"
- func_relative_path_tlibdir=$func_normal_abspath_result
- func_normal_abspath "$2"
- func_relative_path_tbindir=$func_normal_abspath_result
-
- # Ascend the tree starting from libdir
- while :; do
- # check if we have found a prefix of bindir
- case $func_relative_path_tbindir in
- $func_relative_path_tlibdir)
- # found an exact match
- func_relative_path_tcancelled=
- break
- ;;
- $func_relative_path_tlibdir*)
- # found a matching prefix
- func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
- func_relative_path_tcancelled=$func_stripname_result
- if test -z "$func_relative_path_result"; then
- func_relative_path_result=.
- fi
- break
- ;;
- *)
- func_dirname $func_relative_path_tlibdir
- func_relative_path_tlibdir=$func_dirname_result
- if test -z "$func_relative_path_tlibdir"; then
- # Have to descend all the way to the root!
- func_relative_path_result=../$func_relative_path_result
- func_relative_path_tcancelled=$func_relative_path_tbindir
- break
- fi
- func_relative_path_result=../$func_relative_path_result
- ;;
- esac
- done
-
- # Now calculate path; take care to avoid doubling-up slashes.
- func_stripname '' '/' "$func_relative_path_result"
- func_relative_path_result=$func_stripname_result
- func_stripname '/' '/' "$func_relative_path_tcancelled"
- if test -n "$func_stripname_result"; then
- func_append func_relative_path_result "/$func_stripname_result"
- fi
-
- # Normalisation. If bindir is libdir, return '.' else relative path.
- if test -n "$func_relative_path_result"; then
- func_stripname './' '' "$func_relative_path_result"
- func_relative_path_result=$func_stripname_result
- fi
-
- test -n "$func_relative_path_result" || func_relative_path_result=.
-
- :
-}
-
-
-# func_quote_for_eval ARG...
-# --------------------------
-# Aesthetically quote ARGs to be evaled later.
-# This function returns two values:
-# i) func_quote_for_eval_result
-# double-quoted, suitable for a subsequent eval
-# ii) func_quote_for_eval_unquoted_result
-# has all characters that are still active within double
-# quotes backslashified.
-func_quote_for_eval ()
-{
- $debug_cmd
-
- func_quote_for_eval_unquoted_result=
- func_quote_for_eval_result=
- while test 0 -lt $#; do
- case $1 in
- *[\\\`\"\$]*)
- _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;;
- *)
- _G_unquoted_arg=$1 ;;
- esac
- if test -n "$func_quote_for_eval_unquoted_result"; then
- func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg"
- else
- func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg"
- fi
-
- case $_G_unquoted_arg in
- # Double-quote args containing shell metacharacters to delay
- # word splitting, command substitution and variable expansion
- # for a subsequent eval.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- _G_quoted_arg=\"$_G_unquoted_arg\"
- ;;
- *)
- _G_quoted_arg=$_G_unquoted_arg
- ;;
- esac
-
- if test -n "$func_quote_for_eval_result"; then
- func_append func_quote_for_eval_result " $_G_quoted_arg"
- else
- func_append func_quote_for_eval_result "$_G_quoted_arg"
- fi
- shift
- done
-}
-
-
-# func_quote_for_expand ARG
-# -------------------------
-# Aesthetically quote ARG to be evaled later; same as above,
-# but do not quote variable references.
-func_quote_for_expand ()
-{
- $debug_cmd
-
- case $1 in
- *[\\\`\"]*)
- _G_arg=`$ECHO "$1" | $SED \
- -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;;
- *)
- _G_arg=$1 ;;
- esac
-
- case $_G_arg in
- # Double-quote args containing shell metacharacters to delay
- # word splitting and command substitution for a subsequent eval.
- # Many Bourne shells cannot handle close brackets correctly
- # in scan sets, so we specify it separately.
- *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"")
- _G_arg=\"$_G_arg\"
- ;;
- esac
-
- func_quote_for_expand_result=$_G_arg
-}
-
-
-# func_stripname PREFIX SUFFIX NAME
-# ---------------------------------
-# strip PREFIX and SUFFIX from NAME, and store in func_stripname_result.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-if test yes = "$_G_HAVE_XSI_OPS"; then
- eval 'func_stripname ()
- {
- $debug_cmd
-
- # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
- # positional parameters, so assign one to ordinary variable first.
- func_stripname_result=$3
- func_stripname_result=${func_stripname_result#"$1"}
- func_stripname_result=${func_stripname_result%"$2"}
- }'
-else
- func_stripname ()
- {
- $debug_cmd
-
- case $2 in
- .*) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%\\\\$2\$%%"`;;
- *) func_stripname_result=`$ECHO "$3" | $SED -e "s%^$1%%" -e "s%$2\$%%"`;;
- esac
- }
-fi
-
-
-# func_show_eval CMD [FAIL_EXP]
-# -----------------------------
-# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
-# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it.
-func_show_eval ()
-{
- $debug_cmd
-
- _G_cmd=$1
- _G_fail_exp=${2-':'}
-
- func_quote_for_expand "$_G_cmd"
- eval "func_notquiet $func_quote_for_expand_result"
-
- $opt_dry_run || {
- eval "$_G_cmd"
- _G_status=$?
- if test 0 -ne "$_G_status"; then
- eval "(exit $_G_status); $_G_fail_exp"
- fi
- }
-}
-
-
-# func_show_eval_locale CMD [FAIL_EXP]
-# ------------------------------------
-# Unless opt_quiet is true, then output CMD. Then, if opt_dryrun is
-# not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP
-# is given, then evaluate it. Use the saved locale for evaluation.
-func_show_eval_locale ()
-{
- $debug_cmd
-
- _G_cmd=$1
- _G_fail_exp=${2-':'}
-
- $opt_quiet || {
- func_quote_for_expand "$_G_cmd"
- eval "func_echo $func_quote_for_expand_result"
- }
-
- $opt_dry_run || {
- eval "$_G_user_locale
- $_G_cmd"
- _G_status=$?
- eval "$_G_safe_locale"
- if test 0 -ne "$_G_status"; then
- eval "(exit $_G_status); $_G_fail_exp"
- fi
- }
-}
-
-
-# func_tr_sh
-# ----------
-# Turn $1 into a string suitable for a shell variable name.
-# Result is stored in $func_tr_sh_result. All characters
-# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
-# if $1 begins with a digit, a '_' is prepended as well.
-func_tr_sh ()
-{
- $debug_cmd
-
- case $1 in
- [0-9]* | *[!a-zA-Z0-9_]*)
- func_tr_sh_result=`$ECHO "$1" | $SED -e 's/^\([0-9]\)/_\1/' -e 's/[^a-zA-Z0-9_]/_/g'`
- ;;
- * )
- func_tr_sh_result=$1
- ;;
- esac
-}
-
-
-# func_verbose ARG...
-# -------------------
-# Echo program name prefixed message in verbose mode only.
-func_verbose ()
-{
- $debug_cmd
-
- $opt_verbose && func_echo "$*"
-
- :
-}
-
-
-# func_warn_and_continue ARG...
-# -----------------------------
-# Echo program name prefixed warning message to standard error.
-func_warn_and_continue ()
-{
- $debug_cmd
-
- $require_term_colors
-
- func_echo_infix_1 "${tc_red}warning$tc_reset" "$*" >&2
-}
-
-
-# func_warning CATEGORY ARG...
-# ----------------------------
-# Echo program name prefixed warning message to standard error. Warning
-# messages can be filtered according to CATEGORY, where this function
-# elides messages where CATEGORY is not listed in the global variable
-# 'opt_warning_types'.
-func_warning ()
-{
- $debug_cmd
-
- # CATEGORY must be in the warning_categories list!
- case " $warning_categories " in
- *" $1 "*) ;;
- *) func_internal_error "invalid warning category '$1'" ;;
- esac
-
- _G_category=$1
- shift
-
- case " $opt_warning_types " in
- *" $_G_category "*) $warning_func ${1+"$@"} ;;
- esac
-}
-
-
-# func_sort_ver VER1 VER2
-# -----------------------
-# 'sort -V' is not generally available.
-# Note this deviates from the version comparison in automake
-# in that it treats 1.5 < 1.5.0, and treats 1.4.4a < 1.4-p3a
-# but this should suffice as we won't be specifying old
-# version formats or redundant trailing .0 in bootstrap.conf.
-# If we did want full compatibility then we should probably
-# use m4_version_compare from autoconf.
-func_sort_ver ()
-{
- $debug_cmd
-
- printf '%s\n%s\n' "$1" "$2" \
- | sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n -k 5,5n -k 6,6n -k 7,7n -k 8,8n -k 9,9n
-}
-
-# func_lt_ver PREV CURR
-# ---------------------
-# Return true if PREV and CURR are in the correct order according to
-# func_sort_ver, otherwise false. Use it like this:
-#
-# func_lt_ver "$prev_ver" "$proposed_ver" || func_fatal_error "..."
-func_lt_ver ()
-{
- $debug_cmd
-
- test "x$1" = x`func_sort_ver "$1" "$2" | $SED 1q`
-}
-
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
diff --git a/build-aux/gl/build-aux/inline-source b/build-aux/gl/build-aux/inline-source
deleted file mode 100755
index 0e4da9c4..00000000
--- a/build-aux/gl/build-aux/inline-source
+++ /dev/null
@@ -1,164 +0,0 @@
-#! /bin/sh
-
-# Output the contents of a shell script with sourced files inlined.
-# Written by Gary V. Vaughan, 2012
-
-# Copyright (C) 2012-2014, 2017 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# Source required external libraries:
-. `echo "$0" |${SED-sed} 's|[^/]*$||'`"funclib.sh"
-. `echo "$0" |${SED-sed} 's|[^/]*$||'`"options-parser"
-
-# Set a version string for *this* script.
-scriptversion=2014-01-03.01; # UTC
-
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to bug-libtool@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# Run 'build-aux/inline-source --help' for help with using this script
-# from the command line.
-
-# Recursively scan through a FILE passed on the command line, replacing
-# either of the following:
-# . "relative/file"
-# . `echo "$0" |edit`"relative/file"
-# with the contents of the referenced files.
-
-
-## ---------------- ##
-## Options parsing. ##
-## ---------------- ##
-
-usage='$progpath [OPTION]... FILE'
-
-# Short help message in response to '-h'.
-usage_message='Options:
- --debug enable verbose shell tracing
- --version print version information and exit
- -h, --help print help message and exit
-'
-
-long_help_message="\
-Report bugs to <bug-libtool@gnu.org>
-General help using GNU software: <http://www.gnu.org/gethelp/>."
-
-func_options ${1+"$@"}
-eval set dummy "$func_options_result"; shift
-
-
-## -------------------- ##
-## Resource management. ##
-## -------------------- ##
-
-# require_AWK
-# -----------
-# Search for a "not hopeless" awk.
-require_AWK=func_require_AWK
-func_require_AWK ()
-{
- $debug_cmd
-
- test -n "$AWK" || {
- # Find the first executable in the list.
- for _G_prog in gawk mawk nawk awk
- do
- require_AWK_IFS=$IFS
- IFS=${PATH_SEPARATOR-:}
- for _G_dir in $PATH
- do
- IFS=$require_AWK_IFS
- if test -f "$_G_dir/$_G_prog" && test -x "$_G_dir/$_G_prog"
- then
- AWK=$_G_dir/$_G_prog
- break 2
- fi
- done
- IFS=$require_AWK_IFS
- done
- }
-
- test -n "$AWK" || func_fatal_error "\
-Please install GNU Awk, or 'export AWK=/path/to/gnu/awk'."
-
- func_verbose "found '$AWK'."
-
- require_AWK=:
-}
-
-
-## --------------- ##
-## Core functions. ##
-## --------------- ##
-
-# func_include LINE
-# -----------------
-# Output the contents of file included by LINE.
-func_include ()
-{
- $require_AWK
-
- test -f "$1" \
- || func_fatal_error "file '$1' not found"
-
- _G_scriptdir=`echo "$1" |$SED 's|[^/]*$||'`
- test -n "$_G_scriptdir" || _G_scriptdir="./"
-
- $AWK '
- BEGIN { magic = '${_RECURSE_MAGIC-0}'; }
-
- /^#!/ && magic == 0 {
- print $0;
- print "## DO NOT EDIT - This file generated from '$1'";
- print "## by '$progname' v'$scriptversion'";
- magic++;
- next;
- }
-
- /^\. ['\''"].*['\''"]$/ {
- file = substr ($2, 2, length ($2) -2);
- system (sprintf ("env _RECURSE_MAGIC=%d '$progpath' %s", magic, file));
- next;
- }
-
- /^\. `echo [^`]*`['\''"][^'\''"]*['\''"]$/ {
- tail = substr ($0, match ($0, /`['\''"]/));
- file = substr (tail, 3, length (tail) -3);
- system (sprintf ("env _RECURSE_MAGIC=%d '$progpath' '"$_G_scriptdir"'%s", magic, file));
- next;
- }
-
- { print; }
- ' < "$1"
-}
-
-func_include "$1"
-
-exit 0
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "20/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
diff --git a/build-aux/gl/build-aux/options-parser b/build-aux/gl/build-aux/options-parser
deleted file mode 100644
index dd9867f2..00000000
--- a/build-aux/gl/build-aux/options-parser
+++ /dev/null
@@ -1,608 +0,0 @@
-#! /bin/sh
-
-# Set a version string for this script.
-scriptversion=2014-01-07.03; # UTC
-
-# A portable, pluggable option parser for Bourne shell.
-# Written by Gary V. Vaughan, 2010
-
-# Copyright (C) 2010-2014, 2017 Free Software Foundation, Inc.
-# This is free software; see the source for copying conditions. There is NO
-# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Please report bugs or propose patches to gary@gnu.org.
-
-
-## ------ ##
-## Usage. ##
-## ------ ##
-
-# This file is a library for parsing options in your shell scripts along
-# with assorted other useful supporting features that you can make use
-# of too.
-#
-# For the simplest scripts you might need only:
-#
-# #!/bin/sh
-# . relative/path/to/funclib.sh
-# . relative/path/to/options-parser
-# scriptversion=1.0
-# func_options ${1+"$@"}
-# eval set dummy "$func_options_result"; shift
-# ...rest of your script...
-#
-# In order for the '--version' option to work, you will need to have a
-# suitably formatted comment like the one at the top of this file
-# starting with '# Written by ' and ending with '# warranty; '.
-#
-# For '-h' and '--help' to work, you will also need a one line
-# description of your script's purpose in a comment directly above the
-# '# Written by ' line, like the one at the top of this file.
-#
-# The default options also support '--debug', which will turn on shell
-# execution tracing (see the comment above debug_cmd below for another
-# use), and '--verbose' and the func_verbose function to allow your script
-# to display verbose messages only when your user has specified
-# '--verbose'.
-#
-# After sourcing this file, you can plug processing for additional
-# options by amending the variables from the 'Configuration' section
-# below, and following the instructions in the 'Option parsing'
-# section further down.
-
-## -------------- ##
-## Configuration. ##
-## -------------- ##
-
-# You should override these variables in your script after sourcing this
-# file so that they reflect the customisations you have added to the
-# option parser.
-
-# The usage line for option parsing errors and the start of '-h' and
-# '--help' output messages. You can embed shell variables for delayed
-# expansion at the time the message is displayed, but you will need to
-# quote other shell meta-characters carefully to prevent them being
-# expanded when the contents are evaled.
-usage='$progpath [OPTION]...'
-
-# Short help message in response to '-h' and '--help'. Add to this or
-# override it after sourcing this library to reflect the full set of
-# options your script accepts.
-usage_message="\
- --debug enable verbose shell tracing
- -W, --warnings=CATEGORY
- report the warnings falling in CATEGORY [all]
- -v, --verbose verbosely report processing
- --version print version information and exit
- -h, --help print short or long help message and exit
-"
-
-# Additional text appended to 'usage_message' in response to '--help'.
-long_help_message="
-Warning categories include:
- 'all' show all warnings
- 'none' turn off all the warnings
- 'error' warnings are treated as fatal errors"
-
-# Help message printed before fatal option parsing errors.
-fatal_help="Try '\$progname --help' for more information."
-
-
-
-## ------------------------- ##
-## Hook function management. ##
-## ------------------------- ##
-
-# This section contains functions for adding, removing, and running hooks
-# to the main code. A hook is just a named list of of function, that can
-# be run in order later on.
-
-# func_hookable FUNC_NAME
-# -----------------------
-# Declare that FUNC_NAME will run hooks added with
-# 'func_add_hook FUNC_NAME ...'.
-func_hookable ()
-{
- $debug_cmd
-
- func_append hookable_fns " $1"
-}
-
-
-# func_add_hook FUNC_NAME HOOK_FUNC
-# ---------------------------------
-# Request that FUNC_NAME call HOOK_FUNC before it returns. FUNC_NAME must
-# first have been declared "hookable" by a call to 'func_hookable'.
-func_add_hook ()
-{
- $debug_cmd
-
- case " $hookable_fns " in
- *" $1 "*) ;;
- *) func_fatal_error "'$1' does not accept hook functions." ;;
- esac
-
- eval func_append ${1}_hooks '" $2"'
-}
-
-
-# func_remove_hook FUNC_NAME HOOK_FUNC
-# ------------------------------------
-# Remove HOOK_FUNC from the list of functions called by FUNC_NAME.
-func_remove_hook ()
-{
- $debug_cmd
-
- eval ${1}_hooks='`$ECHO "\$'$1'_hooks" |$SED "s| '$2'||"`'
-}
-
-
-# func_run_hooks FUNC_NAME [ARG]...
-# ---------------------------------
-# Run all hook functions registered to FUNC_NAME.
-# It is assumed that the list of hook functions contains nothing more
-# than a whitespace-delimited list of legal shell function names, and
-# no effort is wasted trying to catch shell meta-characters or preserve
-# whitespace.
-func_run_hooks ()
-{
- $debug_cmd
-
- case " $hookable_fns " in
- *" $1 "*) ;;
- *) func_fatal_error "'$1' does not support hook funcions.n" ;;
- esac
-
- eval _G_hook_fns=\$$1_hooks; shift
-
- for _G_hook in $_G_hook_fns; do
- eval $_G_hook '"$@"'
-
- # store returned options list back into positional
- # parameters for next 'cmd' execution.
- eval _G_hook_result=\$${_G_hook}_result
- eval set dummy "$_G_hook_result"; shift
- done
-
- func_quote_for_eval ${1+"$@"}
- func_run_hooks_result=$func_quote_for_eval_result
-}
-
-
-
-## --------------- ##
-## Option parsing. ##
-## --------------- ##
-
-# In order to add your own option parsing hooks, you must accept the
-# full positional parameter list in your hook function, remove any
-# options that you action, and then pass back the remaining unprocessed
-# options in '<hooked_function_name>_result', escaped suitably for
-# 'eval'. Like this:
-#
-# my_options_prep ()
-# {
-# $debug_cmd
-#
-# # Extend the existing usage message.
-# usage_message=$usage_message'
-# -s, --silent don'\''t print informational messages
-# '
-#
-# func_quote_for_eval ${1+"$@"}
-# my_options_prep_result=$func_quote_for_eval_result
-# }
-# func_add_hook func_options_prep my_options_prep
-#
-#
-# my_silent_option ()
-# {
-# $debug_cmd
-#
-# # Note that for efficiency, we parse as many options as we can
-# # recognise in a loop before passing the remainder back to the
-# # caller on the first unrecognised argument we encounter.
-# while test $# -gt 0; do
-# opt=$1; shift
-# case $opt in
-# --silent|-s) opt_silent=: ;;
-# # Separate non-argument short options:
-# -s*) func_split_short_opt "$_G_opt"
-# set dummy "$func_split_short_opt_name" \
-# "-$func_split_short_opt_arg" ${1+"$@"}
-# shift
-# ;;
-# *) set dummy "$_G_opt" "$*"; shift; break ;;
-# esac
-# done
-#
-# func_quote_for_eval ${1+"$@"}
-# my_silent_option_result=$func_quote_for_eval_result
-# }
-# func_add_hook func_parse_options my_silent_option
-#
-#
-# my_option_validation ()
-# {
-# $debug_cmd
-#
-# $opt_silent && $opt_verbose && func_fatal_help "\
-# '--silent' and '--verbose' options are mutually exclusive."
-#
-# func_quote_for_eval ${1+"$@"}
-# my_option_validation_result=$func_quote_for_eval_result
-# }
-# func_add_hook func_validate_options my_option_validation
-#
-# You'll alse need to manually amend $usage_message to reflect the extra
-# options you parse. It's preferable to append if you can, so that
-# multiple option parsing hooks can be added safely.
-
-
-# func_options [ARG]...
-# ---------------------
-# All the functions called inside func_options are hookable. See the
-# individual implementations for details.
-func_hookable func_options
-func_options ()
-{
- $debug_cmd
-
- func_options_prep ${1+"$@"}
- eval func_parse_options \
- ${func_options_prep_result+"$func_options_prep_result"}
- eval func_validate_options \
- ${func_parse_options_result+"$func_parse_options_result"}
-
- eval func_run_hooks func_options \
- ${func_validate_options_result+"$func_validate_options_result"}
-
- # save modified positional parameters for caller
- func_options_result=$func_run_hooks_result
-}
-
-
-# func_options_prep [ARG]...
-# --------------------------
-# All initialisations required before starting the option parse loop.
-# Note that when calling hook functions, we pass through the list of
-# positional parameters. If a hook function modifies that list, and
-# needs to propogate that back to rest of this script, then the complete
-# modified list must be put in 'func_run_hooks_result' before
-# returning.
-func_hookable func_options_prep
-func_options_prep ()
-{
- $debug_cmd
-
- # Option defaults:
- opt_verbose=false
- opt_warning_types=
-
- func_run_hooks func_options_prep ${1+"$@"}
-
- # save modified positional parameters for caller
- func_options_prep_result=$func_run_hooks_result
-}
-
-
-# func_parse_options [ARG]...
-# ---------------------------
-# The main option parsing loop.
-func_hookable func_parse_options
-func_parse_options ()
-{
- $debug_cmd
-
- func_parse_options_result=
-
- # this just eases exit handling
- while test $# -gt 0; do
- # Defer to hook functions for initial option parsing, so they
- # get priority in the event of reusing an option name.
- func_run_hooks func_parse_options ${1+"$@"}
-
- # Adjust func_parse_options positional parameters to match
- eval set dummy "$func_run_hooks_result"; shift
-
- # Break out of the loop if we already parsed every option.
- test $# -gt 0 || break
-
- _G_opt=$1
- shift
- case $_G_opt in
- --debug|-x) debug_cmd='set -x'
- func_echo "enabling shell trace mode"
- $debug_cmd
- ;;
-
- --no-warnings|--no-warning|--no-warn)
- set dummy --warnings none ${1+"$@"}
- shift
- ;;
-
- --warnings|--warning|-W)
- test $# = 0 && func_missing_arg $_G_opt && break
- case " $warning_categories $1" in
- *" $1 "*)
- # trailing space prevents matching last $1 above
- func_append_uniq opt_warning_types " $1"
- ;;
- *all)
- opt_warning_types=$warning_categories
- ;;
- *none)
- opt_warning_types=none
- warning_func=:
- ;;
- *error)
- opt_warning_types=$warning_categories
- warning_func=func_fatal_error
- ;;
- *)
- func_fatal_error \
- "unsupported warning category: '$1'"
- ;;
- esac
- shift
- ;;
-
- --verbose|-v) opt_verbose=: ;;
- --version) func_version ;;
- -\?|-h) func_usage ;;
- --help) func_help ;;
-
- # Separate optargs to long options (plugins may need this):
- --*=*) func_split_equals "$_G_opt"
- set dummy "$func_split_equals_lhs" \
- "$func_split_equals_rhs" ${1+"$@"}
- shift
- ;;
-
- # Separate optargs to short options:
- -W*)
- func_split_short_opt "$_G_opt"
- set dummy "$func_split_short_opt_name" \
- "$func_split_short_opt_arg" ${1+"$@"}
- shift
- ;;
-
- # Separate non-argument short options:
- -\?*|-h*|-v*|-x*)
- func_split_short_opt "$_G_opt"
- set dummy "$func_split_short_opt_name" \
- "-$func_split_short_opt_arg" ${1+"$@"}
- shift
- ;;
-
- --) break ;;
- -*) func_fatal_help "unrecognised option: '$_G_opt'" ;;
- *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;;
- esac
- done
-
- # save modified positional parameters for caller
- func_quote_for_eval ${1+"$@"}
- func_parse_options_result=$func_quote_for_eval_result
-}
-
-
-# func_validate_options [ARG]...
-# ------------------------------
-# Perform any sanity checks on option settings and/or unconsumed
-# arguments.
-func_hookable func_validate_options
-func_validate_options ()
-{
- $debug_cmd
-
- # Display all warnings if -W was not given.
- test -n "$opt_warning_types" || opt_warning_types=" $warning_categories"
-
- func_run_hooks func_validate_options ${1+"$@"}
-
- # Bail if the options were screwed!
- $exit_cmd $EXIT_FAILURE
-
- # save modified positional parameters for caller
- func_validate_options_result=$func_run_hooks_result
-}
-
-
-
-## ----------------- ##
-## Helper functions. ##
-## ----------------- ##
-
-# This section contains the helper functions used by the rest of the
-# hookable option parser framework in ascii-betical order.
-
-
-# func_fatal_help ARG...
-# ----------------------
-# Echo program name prefixed message to standard error, followed by
-# a help hint, and exit.
-func_fatal_help ()
-{
- $debug_cmd
-
- eval \$ECHO \""Usage: $usage"\"
- eval \$ECHO \""$fatal_help"\"
- func_error ${1+"$@"}
- exit $EXIT_FAILURE
-}
-
-
-# func_help
-# ---------
-# Echo long help message to standard output and exit.
-func_help ()
-{
- $debug_cmd
-
- func_usage_message
- $ECHO "$long_help_message"
- exit 0
-}
-
-
-# func_missing_arg ARGNAME
-# ------------------------
-# Echo program name prefixed message to standard error and set global
-# exit_cmd.
-func_missing_arg ()
-{
- $debug_cmd
-
- func_error "Missing argument for '$1'."
- exit_cmd=exit
-}
-
-
-# func_split_equals STRING
-# ------------------------
-# Set func_split_equals_lhs and func_split_equals_rhs shell variables after
-# splitting STRING at the '=' sign.
-test -z "$_G_HAVE_XSI_OPS" \
- && (eval 'x=a/b/c;
- test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \
- && _G_HAVE_XSI_OPS=yes
-
-if test yes = "$_G_HAVE_XSI_OPS"
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_split_equals ()
- {
- $debug_cmd
-
- func_split_equals_lhs=${1%%=*}
- func_split_equals_rhs=${1#*=}
- test "x$func_split_equals_lhs" = "x$1" \
- && func_split_equals_rhs=
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_split_equals ()
- {
- $debug_cmd
-
- func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'`
- func_split_equals_rhs=
- test "x$func_split_equals_lhs" = "x$1" \
- || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'`
- }
-fi #func_split_equals
-
-
-# func_split_short_opt SHORTOPT
-# -----------------------------
-# Set func_split_short_opt_name and func_split_short_opt_arg shell
-# variables after splitting SHORTOPT after the 2nd character.
-if test yes = "$_G_HAVE_XSI_OPS"
-then
- # This is an XSI compatible shell, allowing a faster implementation...
- eval 'func_split_short_opt ()
- {
- $debug_cmd
-
- func_split_short_opt_arg=${1#??}
- func_split_short_opt_name=${1%"$func_split_short_opt_arg"}
- }'
-else
- # ...otherwise fall back to using expr, which is often a shell builtin.
- func_split_short_opt ()
- {
- $debug_cmd
-
- func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'`
- func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'`
- }
-fi #func_split_short_opt
-
-
-# func_usage
-# ----------
-# Echo short help message to standard output and exit.
-func_usage ()
-{
- $debug_cmd
-
- func_usage_message
- $ECHO "Run '$progname --help |${PAGER-more}' for full usage"
- exit 0
-}
-
-
-# func_usage_message
-# ------------------
-# Echo short help message to standard output.
-func_usage_message ()
-{
- $debug_cmd
-
- eval \$ECHO \""Usage: $usage"\"
- echo
- $SED -n 's|^# ||
- /^Written by/{
- x;p;x
- }
- h
- /^Written by/q' < "$progpath"
- echo
- eval \$ECHO \""$usage_message"\"
-}
-
-
-# func_version
-# ------------
-# Echo version message to standard output and exit.
-func_version ()
-{
- $debug_cmd
-
- printf '%s\n' "$progname $scriptversion"
- $SED -n '
- /(C)/!b go
- :more
- /\./!{
- N
- s|\n# | |
- b more
- }
- :go
- /^# Written by /,/# warranty; / {
- s|^# ||
- s|^# *$||
- s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2|
- p
- }
- /^# Written by / {
- s|^# ||
- p
- }
- /^warranty; /q' < "$progpath"
-
- exit $?
-}
-
-
-# Local variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC"
-# time-stamp-time-zone: "UTC"
-# End:
diff --git a/build-aux/gl/lib/clean-temp.c.diff b/build-aux/gl/lib/clean-temp.c.diff
deleted file mode 100644
index 2eafde69..00000000
--- a/build-aux/gl/lib/clean-temp.c.diff
+++ /dev/null
@@ -1,14 +0,0 @@
-diff --git i/lib/clean-temp.c w/lib/clean-temp.c
-index 40ec02f..1053312 100644
---- i/lib/clean-temp.c
-+++ w/lib/clean-temp.c
-@@ -582,6 +582,9 @@ static bool
- supports_delete_on_close ()
- {
- static int known; /* 1 = yes, -1 = no, 0 = unknown */
-+ /* M4 wants to close and later reopen a temporary file, so
-+ delete-on-close must not be used. */
-+ known = -1;
- if (!known)
- {
- OSVERSIONINFO v;
diff --git a/build-aux/gnulib b/build-aux/gnulib
deleted file mode 160000
-Subproject 31bc499696c19bb64741e56c8cd13e1a2ead87c
diff --git a/build-aux/m4/debug.m4 b/build-aux/m4/debug.m4
deleted file mode 100644
index ec45e2de..00000000
--- a/build-aux/m4/debug.m4
+++ /dev/null
@@ -1,94 +0,0 @@
-## -*- Autoconf -*-
-## debug.m4 -- massage compiler flags for debugging/optimisation
-##
-## Copyright (C) 2000-2001, 2003, 2005-2007, 2010, 2013-2014, 2017 Free
-## Software Foundation, Inc.
-## Copyright (C) 1999-2000 Ralf S. Engelschall
-## Written by <rse@engelschall.com>
-## Modified for M4 by Gary V. Vaughan <gary@gnu.org>
-##
-## This file is part of GNU M4.
-##
-## GNU M4 is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## GNU M4 is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# serial 9
-
-# M4_CHECK_DEBUGGING
-# ------------------
-# Debugging Support
-AC_DEFUN([M4_CHECK_DEBUGGING],
-[AC_REQUIRE([AC_PROG_CC])
-AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug],
- [build for debugging [default=no]])])
-AC_MSG_CHECKING([for compilation debug mode])
-AC_MSG_RESULT([${enable_debug-no}])
-
-: ${rm=rm -f}
-: ${RM=rm -f}
-
-set dummy $CC
-compiler="${compiler-[$]2}"
-test -n "$rm" || rm="rm -f"
-
-if test "X$enable_debug" = Xyes; then
- AC_DISABLE_SHARED
- AC_DEFINE([DEBUG], [1],
- [Define this to enable additional runtime debugging])
- M4_default_preload="m4 traditional gnu load \
-import modtest mpeval shadow stdlib time"
- if test "$GCC" = yes; then
- case "$CFLAGS" in
- *-O* ) CFLAGS=`echo $CFLAGS | $SED 's/-O[[^ ]]* / /;s/-O[[^ ]]*$//'` ;;
- esac
- case "$CFLAGS" in
- *-g* ) ;;
- * ) AC_LIBTOOL_COMPILER_OPTION([if $compiler accepts -ggdb3],
- [M4_cv_prog_compiler_ggdb3],
- [-ggdb3 -c conftest.$ac_ext], [],
- [CFLAGS="$CFLAGS -ggdb3"],
- [CFLAGS="$CFLAGS -g"])
- ;;
- esac
- CFLAGS="$CFLAGS -Wall"
- WMORE="-Wshadow -Wpointer-arith -Wcast-align -Wnested-externs"
- WMORE="$WMORE -Wmissing-prototypes -Wmissing-declarations -Winline"
- AC_LIBTOOL_COMPILER_OPTION([if $compiler accepts $WMORE],
- [M4_cv_prog_compiler_warning_flags],
- [$WMORE -c conftest.$ac_ext], [],
- [CFLAGS="$CFLAGS $WMORE"])
-
- AC_LIBTOOL_COMPILER_OPTION([if $compiler accepts -Wno-long-long],
- [M4_cv_prog_compiler_wnolonglong],
- [-Wno-long-long -c conftest.$ac_ext], [],
- [CFLAGS="$CFLAGS -Wno-long-long"])
- else
- case "$CFLAGS" in
- *-g* ) ;;
- * ) CFLAGS="$CFLAGS -g" ;;
- esac
- fi
-else
- AC_ENABLE_SHARED
- case "$CFLAGS" in
- *-g* ) CFLAGS=`echo "$CFLAGS" |\
- $SED -e 's/ -g / /g;s/ -g$//;s/^-g //g;s/^-g$//'`
- ;;
- esac
- case "$CXXFLAGS" in
- *-g* ) CXXFLAGS=`echo "$CXXFLAGS" |\
- $SED -e 's/ -g / /g;s/ -g$//;s/^-g //g;s/^-g$//'`
- ;;
- esac
-fi
-])# M4_CHECK_DEBUGGING
diff --git a/build-aux/m4/gmp.m4 b/build-aux/m4/gmp.m4
deleted file mode 100644
index 0e60bdcc..00000000
--- a/build-aux/m4/gmp.m4
+++ /dev/null
@@ -1,77 +0,0 @@
-## -*- Autoconf -*-
-## Copyright (C) 2000-2001, 2003, 2006-2008, 2010, 2013-2014, 2017 Free
-## Software Foundation, Inc.
-##
-## This file is part of GNU M4.
-##
-## GNU M4 is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## GNU M4 is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# serial 10
-
-m4_define([_M4_LIB_GMP],
-[AC_ARG_WITH([gmp],
- [AS_HELP_STRING([--without-gmp],
- [don't use GNU multiple precision arithmetic library])],
-[use_gmp=$withval], [use_gmp=yes])
-
-case $use_gmp:$LIBADD_GMP:$ac_cv_header_gmp_h in
- no:*)
- M4_cv_using_lib_gmp=no
- ;;
- *::yes)
- AC_MSG_WARN([gmp library not found or does not appear to work
- but `gmp.h' is present])
- M4_cv_using_lib_gmp=no
- ;;
- *:-lgmp:no)
- AC_MSG_WARN([gmp works but `gmp.h' is missing])
- M4_cv_using_lib_gmp=no
- ;;
- yes:*:yes)
- M4_cv_using_lib_gmp=yes
- ;;
- *)
- M4_cv_using_lib_gmp=no
- AC_MSG_WARN([could not detect gmp library])
- ;;
-esac
-])# _M4_LIB_GMP
-
-
-AC_DEFUN([M4_LIB_GMP],
-[AC_PREREQ([2.56])dnl We use the new compiler based header checking in 2.56
-AC_CHECK_HEADERS([gmp.h], [], [], [AC_INCLUDES_DEFAULT])
-m4_pattern_allow([^M4_gmp_save_LIBS$])
-# Some versions of gmp provide mpq_init as a macro, so we need to
-# include the header file, otherwise the detection will fail.
-M4_gmp_save_LIBS="$LIBS"
-LIBS="$LIBS -lgmp"
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[#if HAVE_GMP_H
-# include <gmp.h>
-#endif]],
- [[mpq_t n; mpq_init (n);]])],
- [LIBADD_GMP=-lgmp])
-LIBS=$M4_gmp_save_LIBS
-AC_SUBST([LIBADD_GMP])
-
-_M4_LIB_GMP
-
-# Don't try to link in libgmp if we are not using it after the last call
-if test "$M4_cv_using_lib_gmp" = yes; then
- AC_DEFINE([USE_GMP], [1],
- [Define to 1 if using the GNU multiple precision library.])
-fi
-
-AC_SUBST([USE_GMP], [$M4_cv_using_lib_gmp])
-])# M4_LIB_GMP
diff --git a/build-aux/m4/gnulib-cache.m4 b/build-aux/m4/gnulib-cache.m4
deleted file mode 100644
index 667d2ff9..00000000
--- a/build-aux/m4/gnulib-cache.m4
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright (C) 2002-2017 Free Software Foundation, Inc.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
-# (at your option) any later version.
-#
-# This file is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this file. If not, see <http://www.gnu.org/licenses/>.
-#
-# As a special exception to the GNU General Public License,
-# this file may be distributed as part of a program that
-# contains a configuration script generated by Autoconf, under
-# the same distribution terms as the rest of that program.
-#
-# Generated by gnulib-tool.
-#
-# This file represents the specification of how gnulib-tool is used.
-# It acts as a cache: It is written and read by gnulib-tool.
-# In projects that use version control, this file is meant to be put under
-# version control, like the configure.ac and various Makefile.am files.
-
-
-# Specification in the form of a command-line invocation:
-# gnulib-tool --import --local-dir=build-aux/gl --lib=libgnu --source-base=m4/gnu --m4-base=build-aux/m4 --doc-base=doc --tests-base=tests/gnu --aux-dir=build-aux --with-tests --with-c++-tests --no-conditional-dependencies --libtool --macro-prefix=M4 assert autobuild avltree-oset binary-io bitrotate clean-temp cloexec close-stream closein config-h configmake dirname error execute fclose fdl-1.3 fflush filenamecat flexmember fopen fopen-safer freadptr freadseek fseeko gendocs gettext git-version-gen gitlog-to-changelog gnumakefile gnupload gpl-3.0 intprops inttypes maintainer-makefile manywarnings memchr2 memcmp2 memmem mkstemp obstack obstack-printf-posix progname propername quote regex regexprops-generic rename setenv sigpipe snprintf-posix spawn-pipe sprintf-posix stdbool stdlib-safer strnlen strtod tempname unlocked-io unsetenv update-copyright vasnprintf-posix verify verror wait-process xalloc xalloc-die xmemdup0 xoset xprintf-posix xstrndup xvasprintf-posix
-
-# Specification in the form of a few gnulib-tool.m4 macro invocations:
-gl_LOCAL_DIR([build-aux/gl])
-gl_MODULES([
- assert
- autobuild
- avltree-oset
- binary-io
- bitrotate
- clean-temp
- cloexec
- close-stream
- closein
- config-h
- configmake
- dirname
- error
- execute
- fclose
- fdl-1.3
- fflush
- filenamecat
- flexmember
- fopen
- fopen-safer
- freadptr
- freadseek
- fseeko
- gendocs
- gettext
- git-version-gen
- gitlog-to-changelog
- gnumakefile
- gnupload
- gpl-3.0
- intprops
- inttypes
- maintainer-makefile
- manywarnings
- memchr2
- memcmp2
- memmem
- mkstemp
- obstack
- obstack-printf-posix
- progname
- propername
- quote
- regex
- regexprops-generic
- rename
- setenv
- sigpipe
- snprintf-posix
- spawn-pipe
- sprintf-posix
- stdbool
- stdlib-safer
- strnlen
- strtod
- tempname
- unlocked-io
- unsetenv
- update-copyright
- vasnprintf-posix
- verify
- verror
- wait-process
- xalloc
- xalloc-die
- xmemdup0
- xoset
- xprintf-posix
- xstrndup
- xvasprintf-posix
-])
-gl_WITH_CXX_TESTS
-gl_AVOID([])
-gl_SOURCE_BASE([m4/gnu])
-gl_M4_BASE([build-aux/m4])
-gl_PO_BASE([])
-gl_DOC_BASE([doc])
-gl_TESTS_BASE([tests/gnu])
-gl_WITH_TESTS
-gl_LIB([libgnu])
-gl_MAKEFILE_NAME([])
-gl_LIBTOOL
-gl_MACRO_PREFIX([M4])
-gl_PO_DOMAIN([])
-gl_WITNESS_C_MACRO([])
diff --git a/build-aux/m4/m4-error.m4 b/build-aux/m4/m4-error.m4
deleted file mode 100644
index ba9907c1..00000000
--- a/build-aux/m4/m4-error.m4
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- Autoconf -*-
-# m4-error.m4 -- Use the installed version of error.h if available.
-# Written by Gary V. Vaughan <gary@gnu.org>
-#
-# Copyright (C) 2003-2004, 2006-2007, 2010, 2013-2014, 2017 Free
-# Software Foundation, Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# serial 4
-
-# M4_ERROR
-# --------
-# Use the installed version of error.h if available.
-AC_DEFUN([M4_ERROR],
-[AC_BEFORE([gl_ERROR], [M4_ERROR])
-
-AC_CHECK_HEADERS([error.h],
- [ERROR_H=""], [ERROR_H="error.h"], [AC_INCLUDES_DEFAULT])
-AC_SUBST([ERROR_H])
-
-if test $ac_cv_header_error_h = yes; then
- INCLUDE_ERROR_H='#include <error.h>'
-else
- INCLUDE_ERROR_H='#include <gnu/error.h>'
-fi
-AC_SUBST([INCLUDE_ERROR_H])
-])# M4_ERROR
diff --git a/build-aux/m4/m4-getopt.m4 b/build-aux/m4/m4-getopt.m4
deleted file mode 100644
index 2799e38c..00000000
--- a/build-aux/m4/m4-getopt.m4
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- Autoconf -*-
-# m4-getopt.m4 -- Use the installed version of getopt.h if available.
-# Written by Gary V. Vaughan <gary@gnu.org>
-#
-# Copyright (C) 2005-2007, 2009-2010, 2013-2014, 2017 Free Software
-# Foundation, Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# serial 3
-
-# M4_GETOPT
-# ---------
-# Use the installed version of getopt.h if available.
-AC_DEFUN([M4_GETOPT],
-[
- m4_divert_text([INIT_PREPARE], [M4_replace_getopt=])
- m4_pushdef([AC_LIBOBJ], [M4_replace_getopt=:])
- AC_REQUIRE([gl_FUNC_GETOPT_GNU])
- m4_popdef([AC_LIBOBJ])
- AM_CONDITIONAL([GETOPT], [test -n "$M4_replace_getopt"])
-])# M4_GETOPT
diff --git a/build-aux/m4/m4-gettext.m4 b/build-aux/m4/m4-gettext.m4
deleted file mode 100644
index 65c12995..00000000
--- a/build-aux/m4/m4-gettext.m4
+++ /dev/null
@@ -1,35 +0,0 @@
-# -*- Autoconf -*-
-# m4-gettext.m4 -- Use the installed version of GNU gettext if available.
-# Written by Gary V. Vaughan <gary@gnu.org>
-#
-# Copyright (C) 2003-2004, 2006-2007, 2010, 2013-2014, 2017 Free
-# Software Foundation, Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# serial 3
-
-# M4_GNU_GETTEXT
-# --------------
-# Use the installed version of GNU gettext if available.
-AC_DEFUN([M4_GNU_GETTEXT],
-[AC_BEFORE([AM_GNU_GETTEXT], [M4_GNU_GETTEXT])
-AC_CHECK_HEADERS([gettext.h],
- [GETTEXT_H=""], [GETTEXT_H="gettext.h"], [AC_INCLUDES_DEFAULT])
-AC_SUBST([GETTEXT_H])
-
-AC_CONFIG_FILES([po/Makefile.in])
-])# M4_GNU_GETTEXT
diff --git a/build-aux/m4/m4-obstack.m4 b/build-aux/m4/m4-obstack.m4
deleted file mode 100644
index db31b01e..00000000
--- a/build-aux/m4/m4-obstack.m4
+++ /dev/null
@@ -1,50 +0,0 @@
-# -*- Autoconf -*-
-# m4-obstack.m4 -- the libc supplied version of obstacks if available.
-#
-# Copyright (C) 2000-2001, 2003-2004, 2006-2007, 2010, 2013-2014, 2017
-# Free Software Foundation, Inc.
-# Written by Gary V. Vaughan <gary@gnu.org>
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# serial 10
-
-# M4_OBSTACK
-# ----------
-# Use the libc supplied version of obstacks if available.
-AC_DEFUN([M4_OBSTACK],
-[AC_PREREQ([2.56])dnl We use the compiler based header checking in 2.56
-AC_BEFORE([gl_OBSTACK], [M4_OBSTACK])
-AC_ARG_WITH([included-obstack],
- [AS_HELP_STRING([--with-included-obstack],
- [use the obstack implementation included here])])
-
-AC_CHECK_HEADERS([obstack.h], [], [], [AC_INCLUDES_DEFAULT])
-
-if test "x${with_included_obstack-no}" != xno; then
- ac_cv_func_obstack=no
-fi
-
-OBSTACK_H=
-if test $ac_cv_func_obstack = yes; then
- INCLUDE_OBSTACK_H='#include <obstack.h>'
-else
- INCLUDE_OBSTACK_H='#include <gnu/obstack.h>'
- OBSTACK_H=obstack.h
-fi
-AC_SUBST([OBSTACK_H])
-AC_SUBST([INCLUDE_OBSTACK_H])
-])# M4_FUNC_OBSTACK
diff --git a/build-aux/m4/m4-regex.m4 b/build-aux/m4/m4-regex.m4
deleted file mode 100644
index c1e8acdd..00000000
--- a/build-aux/m4/m4-regex.m4
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- Autoconf -*-
-# m4-regex.m4 -- Use the installed regex if it is good enough.
-# Written by Gary V. Vaughan <gary@gnu.org>
-#
-# Copyright (C) 2003-2004, 2006-2007, 2010, 2013-2014, 2017 Free
-# Software Foundation, Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# serial 4
-
-# M4_REGEX([path/to/regex.c])
-# ---------------------------
-# Use the installed regex if it is good enough.
-AC_DEFUN([M4_REGEX],
-[AC_BEFORE([gl_REGEX], [M4_REGEX])
-if test $ac_use_included_regex = no; then
- INCLUDE_REGEX_H='#include <regex.h>'
- REGEX_H=
-else
- INCLUDE_REGEX_H='#include <gnu/regex.h>'
- REGEX_H=regex.h
-fi
-AC_SUBST([REGEX_H])
-AC_SUBST([INCLUDE_REGEX_H])
-])# M4_REGEX
diff --git a/build-aux/m4/m4-rename.m4 b/build-aux/m4/m4-rename.m4
deleted file mode 100644
index faafd1ba..00000000
--- a/build-aux/m4/m4-rename.m4
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- Autoconf -*-
-# m4-rename.m4 -- Test the abilities of rename.
-# Written by Eric Blake <ebb9@byu.net>
-#
-# Copyright (C) 2008, 2010, 2013-2014, 2017 Free Software Foundation,
-# Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# serial 1
-
-# M4_RENAME
-# ---------
-# Detect platforms like mingw where rename can't move open files.
-AC_DEFUN([M4_RENAME],
-[AC_CACHE_CHECK([whether an open file can be renamed],
- [M4_cv_func_rename_open_file_works],
- [AC_RUN_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
- [FILE *f = fopen ("conftest.1", "w+");
- int result = rename ("conftest.1", "conftest.2");
- fclose (f); remove ("conftest.1"); remove ("conftest.2");
- return result;])],
- [M4_cv_func_rename_open_file_works=yes],
- [M4_cv_func_rename_open_file_works=no],
- [M4_cv_func_rename_open_file_works='guessing no'])])
-if test "$M4_cv_func_rename_open_file_works" = yes ; then
- M4_rename_open_works=1
-else
- M4_rename_open_works=0
-fi
-AC_DEFINE_UNQUOTED([RENAME_OPEN_FILE_WORKS], [$M4_rename_open_works],
- [Define to 1 if a file can be renamed while open, or to 0 if not.])
-])
diff --git a/build-aux/m4/m4-syscmd.m4 b/build-aux/m4/m4-syscmd.m4
deleted file mode 100644
index 2b4beb56..00000000
--- a/build-aux/m4/m4-syscmd.m4
+++ /dev/null
@@ -1,60 +0,0 @@
-# -*- Autoconf -*-
-# m4-syscmd.m4 -- Allow choice of syscmd shell.
-# Written by Eric Blake <ebb9@byu.net>
-#
-# Copyright (C) 2009-2010, 2013-2014, 2017 Free Software Foundation,
-# Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# serial 1
-
-# M4_SYSCMD
-# ---------
-# Allow user to choose different shell than /bin/sh for e?syscmd.
-AC_DEFUN([M4_SYSCMD],
-[AC_MSG_CHECKING([[which shell to use for syscmd]])
-AC_ARG_WITH([syscmd-shell],
- [AS_HELP_STRING([--with-syscmd-shell], [shell used by syscmd [/bin/sh]])],
- [case $withval in
- yes[)] with_syscmd_shell=no;;
- esac], [with_syscmd_shell=no])
-if test "$with_syscmd_shell" = no ; then
- with_syscmd_shell=/bin/sh
- if test "$cross_compiling" != yes ; then
-dnl Give mingw a default that is more likely to be available.
- AS_IF([AS_EXECUTABLE_P([/bin/sh$EXEEXT])], [],
- [if (cmd /c) 2>/dev/null; then with_syscmd_shell=cmd; fi])
-dnl Too bad _AS_PATH_WALK is not public.
- M4_save_IFS=$IFS; IFS=$PATH_SEPARATOR
- for M4_dir in `if (command -p getconf PATH) 2>/dev/null ; then
- command -p getconf PATH
- else
- echo "/bin$PATH_SEPARATOR$PATH"
- fi`
- do
- IFS=$M4_save_IFS
- test -z "$M4_dir" && continue
- AS_EXECUTABLE_P(["$M4_dir/sh"]) \
- && { with_syscmd_shell=$M4_dir/sh; break; }
- done
- IFS=$M4_save_IFS
- fi
-fi
-AC_MSG_RESULT([$with_syscmd_shell])
-AC_DEFINE_UNQUOTED([M4_SYSCMD_SHELL], ["$with_syscmd_shell"],
- [Shell used by syscmd and esyscmd, must accept -c argument.])
-])
diff --git a/build-aux/m4/stackovf.m4 b/build-aux/m4/stackovf.m4
deleted file mode 100644
index 104f737a..00000000
--- a/build-aux/m4/stackovf.m4
+++ /dev/null
@@ -1,91 +0,0 @@
-# -*- Autoconf -*-
-# stackovf.m4 -- how do we deal with stack overflow?
-#
-# Copyright (C) 2000, 2003, 2006-2007, 2010, 2013-2014, 2017 Free
-# Software Foundation, Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# serial 7
-
-# M4_SYS_STACKOVF
-# ---------------
-AC_DEFUN([M4_SYS_STACKOVF],
-[AC_PREREQ([2.60])dnl We use the _ONCE variants
-AC_REQUIRE([AC_TYPE_SIGNAL])dnl
-
-AC_CHECK_HEADERS_ONCE([siginfo.h])
-AC_CHECK_FUNCS_ONCE([sigaction sigaltstack sigstack sigvec])
-AC_CHECK_MEMBERS([stack_t.ss_sp], [], [],
-[[#include <signal.h>
-#if HAVE_SIGINFO_H
-# include <siginfo.h>
-#endif
-]])
-
-# Code from Jim Avera <jima@netcom.com>.
-# stackovf.c requires:
-# 1. Either sigaction with SA_ONSTACK, or sigvec with SV_ONSTACK
-# 2. Either sigaltstack or sigstack
-# 3. getrlimit, including support for RLIMIT_STACK
-AC_CACHE_CHECK([if stack overflow is detectable], [M4_cv_use_stackovf],
-[M4_cv_use_stackovf=no
-if test "$ac_cv_func_sigaction" = yes || test "$ac_cv_func_sigvec" = yes; then
- if test "$ac_cv_func_sigaltstack" = yes || test "$ac_cv_func_sigstack" = yes; then
- AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/time.h>
-#include <sys/resource.h>
-#include <signal.h>
-]], [[struct rlimit r; getrlimit (RLIMIT_STACK, &r);
-#if (!defined HAVE_SIGACTION || !defined SA_ONSTACK) \
- && (!defined HAVE_SIGVEC || !defined SV_ONSTACK)
-choke me /* SA_ONSTACK and/or SV_ONSTACK are not defined */
-#endif
-]])], [M4_cv_use_stackovf=yes])
- fi
-fi])
-
-AM_CONDITIONAL([STACKOVF], [test "$M4_cv_use_stackovf" = yes])
-if test "$M4_cv_use_stackovf" = yes; then
- AC_DEFINE([USE_STACKOVF], [1],
- [Define to 1 if using stack overflow detection.])
- AC_CHECK_TYPES([rlim_t], [],
- [AC_DEFINE([rlim_t], [int],
- [Define to int if rlim_t is not defined in sys/resource.h])],
- [[#include <sys/resource.h>
-]])
- AC_CHECK_TYPES([stack_t], [],
- [AC_DEFINE([stack_t], [struct sigaltstack],
- [Define to struct sigaltstack if stack_t is not in signal.h])],
- [[#include <signal.h>
-]])
- AC_CHECK_TYPES([sigcontext], [], [], [[#include <signal.h>
-]])
- AC_CHECK_TYPES([siginfo_t], [], [], [[#include <signal.h>
-#if HAVE_SIGINFO_H
-# include <siginfo.h>
-#endif
-]])
- AC_CHECK_MEMBERS([struct sigaction.sa_sigaction], [], [],
-[[#include <signal.h>
-]])
-
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>
-]],
- [[struct sigaltstack x; x.ss_base = 0;]])],
- [AC_DEFINE([ss_sp], [ss_base],
- [Define to ss_base if stack_t has ss_base instead of ss_sp.])])
-fi
-])# M4_SYS_STACKOVF
diff --git a/build-aux/thanks-gen b/build-aux/thanks-gen
deleted file mode 100755
index 92090ced..00000000
--- a/build-aux/thanks-gen
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/perl -nl
-# Use Perl's multi-byte alignment code, via sprintf, while
-# performing a rudimentary check for duplicate names and
-# removing duplicate name,email pairs.
-use Encode;
-
-BEGIN { my (%elide, %seen, %name) }
-
-chomp;
-my ($name, $email) = split '\0', decode ('UTF-8', $_);
-
-if ($elide{"!$name"}) {
-; # ignore this author
-} elsif (index ($name, '!') == 0) {
- $elide{$name}++;
-} elsif ($seen{$name}++) {
- warn "$0: NO-THANKS: duplicate name: $name\n";
-} else {
- print encode ('UTF-8', sprintf ('%-36s', $name)), $email;
-}
diff --git a/cfg.mk b/cfg.mk
deleted file mode 100644
index 3b5c6f17..00000000
--- a/cfg.mk
+++ /dev/null
@@ -1,63 +0,0 @@
-# Customize maint.mk. -*- makefile -*-
-# Copyright (C) 2003-2011, 2013-2014, 2017 Free Software Foundation,
-# Inc.
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# We intentionally hide the submodule in a subdirectory
-gnulib_dir = $(srcdir)/build-aux/gnulib
-
-# Used in maint.mk's web-manual rule
-manual_title = GNU macro processor
-
-# Always use shorthand copyrights.
-update-copyright-env = \
- UPDATE_COPYRIGHT_USE_INTERVALS=1 \
- UPDATE_COPYRIGHT_MAX_LINE_LENGTH=72
-
-# Tests not to run as part of "make syntax-check".
-# M4 intentionally uses a coding style that compiles under C++.
-# sc_proper_name_utf8_requires_ICONV doesn't work with non-recursive Makefile
-# sc_po_check assumes a directory layout that we don't quite provide
-local-checks-to-skip = sc_cast_of_x_alloc_return_value \
- sc_proper_name_utf8_requires_ICONV \
- sc_po_check \
- sc_bindtextdomain
-
-# PRAGMA_SYSTEM_HEADER includes #, which does not work through a
-# Makefile variable, so we exempt it.
-_makefile_at_at_check_exceptions = ' && !/PRAGMA_SYSTEM_HEADER/'
-
-# Hash of NEWS contents, to ensure we don't add entries to wrong section.
-old_NEWS_hash = 761ae30101b24be4aea2f564e9ceee75
-
-# Indent only with spaces.
-sc_prohibit_tab_based_indentation:
- @re='^ * ' \
- msg='TAB in indentation; use only spaces' \
- $(_prohibit_regexp)
-
-# List all syntax-check exemptions:
-exclude_file_name_regexp--sc_cast_of_argument_to_free = ^m4/m4private.h$
-exclude_file_name_regexp--sc_prohibit_always_true_header_tests = \
- ^Makefile.am$$
-exclude_file_name_regexp--sc_prohibit_strncpy = ^m4/path.c$$
-exclude_file_name_regexp--sc_prohibit_tab_based_indentation = \
- (^(GNU)?Makefile(\.am)?|\.mk|^HACKING|^ChangeLog.*)$$
-exclude_file_name_regexp--sc_require_config_h = \
- ^modules/(evalparse|format)\.c$$
-exclude_file_name_regexp--sc_require_config_h_first = \
- ^modules/(evalparse|format)\.c$$
-exclude_file_name_regexp--update_copyright = \
- ^(doc/m4\.texi|ltdl/m4/gnulib-cache.m4)$$
diff --git a/configure.ac b/configure.ac
deleted file mode 100644
index c4644af5..00000000
--- a/configure.ac
+++ /dev/null
@@ -1,362 +0,0 @@
-# Configure template for GNU m4. -*-Autoconf-*-
-# Copyright (C) 1991-1994, 2000-2002, 2004-2014, 2017 Free Software
-# Foundation, Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-dnl We depend on autotest's ./testsuite -C.
-AC_PREREQ([2.62])
-
-## ------------------------ ##
-## Autoconf initialization. ##
-## ------------------------ ##
-m4_define([M4_VERSION],
- m4_esyscmd([build-aux/git-version-gen .tarball-version]))
-m4_bmatch(m4_defn([M4_VERSION]), [^[0-9]], [],
- [m4_define([M4_VERSION], [1.9a])])
-AC_INIT([GNU M4], m4_defn([M4_VERSION]), [bug-m4@gnu.org])
-
-AC_CONFIG_SRCDIR([src/m4.h])
-AC_CONFIG_AUX_DIR([build-aux])
-AC_CONFIG_MACRO_DIR([build-aux/m4])
-AC_CONFIG_LIBOBJ_DIR([m4/gnu])
-AC_CONFIG_TESTDIR([tests])
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_FILES([tests/m4], [chmod +x tests/m4])
-
-
-## -------------------------- ##
-## M4 specific configuration. ##
-## -------------------------- ##
-dnl Autoconf recommends that packages use lowercase for their package-specific
-dnl prefix for cache variables. But in the case of m4, that collides with
-dnl the m4_ namespace provided by m4sugar, so we prefer M4_ as our
-dnl package-specific prefix.
-m4_pattern_forbid([^M4_[A-Z]])
-
-AC_DEFUN([M4_DEFAULT_PRELOAD], [])
-M4_default_preload="M4_DEFAULT_PRELOAD"
-
-
-## ------------------------ ##
-## Automake Initialization. ##
-## ------------------------ ##
-AM_INIT_AUTOMAKE([1.11.6 subdir-objects dist-bzip2 dist-xz
-color-tests parallel-tests silent-rules]
-m4_if(m4_index(m4_defn([M4_VERSION]), [-]), [-1], [gnits], [gnu]))
-AM_SILENT_RULES([yes]) # make --enable-silent-rules the default.
-
-
-## ------------------ ##
-## C compiler checks. ##
-## ------------------ ##
-AC_PROG_CC
-AC_DEFUN([gl_CXX_CHOICE_DEFAULT_NO])
-M4_EARLY
-
-# Maintainer note - comment this line out if you plan to rerun
-# GNULIB_POSIXCHECK testing to see if M4 should be using more modules.
-# Leave it uncommented for normal releases, for faster ./configure.
-gl_ASSERT_NO_GNULIB_POSIXCHECK
-
-AC_SYS_LARGEFILE
-AC_PROG_CPP
-AM_PROG_CC_C_O
-M4_CHECK_DEBUGGING
-
-
-## --------------------------- ##
-## C compiler characteristics. ##
-## --------------------------- ##
-AC_TYPE_SIZE_T
-AC_CHECK_SIZEOF([long long int])
-
-AS_CASE([$host], [*-*-os2*], [OS2_LDFLAGS=-Zargs-resp])
-AC_SUBST([OS2_LDFLAGS])
-
-
-## ----------------------- ##
-## Libtool initialization. ##
-## ----------------------- ##
-LT_PREREQ([2.2])
-LT_INIT([shared dlopen win32-dll])
-
-AC_ARG_ENABLE([gcc-warnings],
- [AS_HELP_STRING([--enable-gcc-warnings],
- [turn on lots of GCC warnings (for developers)])],
- [case $enableval in
- yes|no) ;;
- *) AC_MSG_ERROR([bad value $enableval for gcc-warnings option]) ;;
- esac
- gl_gcc_warnings=$enableval],
- [gl_gcc_warnings=no]
-)
-
-if test "$gl_gcc_warnings" = yes; then
- gl_WARN_ADD([-Werror], [WERROR_CFLAGS])
- AC_SUBST([WERROR_CFLAGS])
-
- # This, $nw, is the list of warnings we disable.
- nw=
- nw="$nw -Waggregate-return" # K&R is anachronistic
- nw="$nw -Wtraditional-conversion" # K&R is anachronistic
- nw="$nw -Wundef" # K&R is anachronistic
- nw="$nw -Wlong-long" # C90 is anachronistic
- nw="$nw -Wsystem-headers" # Don't let system headers trigger warnings
- nw="$nw -Wpadded" # Our structs are not packed
- nw="$nw -Wformat-nonliteral" # Needed in builtin.c
- nw="$nw -Wconversion" # Too many warnings for now
- nw="$nw -Wsign-conversion" # Too many warnings for now
- nw="$nw -Wcast-qual" # Too many warnings for now
- nw="$nw -Wswitch-enum" # Too many warnings for now
- # gcc 4.4.6 complains enum-compare is C++ only; gcc 4.7.0 implies it in -Wall
- nw="$nw -Wenum-compare"
-
- # Gnulib uses '#pragma GCC diagnostic push' to silence some
- # warnings, but older gcc doesn't support this.
- AC_CACHE_CHECK([whether pragma GCC diagnostic push works],
- [M4_cv_gcc_pragma_push_works], [
- save_CFLAGS=$CFLAGS
- CFLAGS='-Wunknown-pragmas -Werror'
- AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
- #pragma GCC diagnostic push
- #pragma GCC diagnostic pop
- ]])],
- [M4_cv_gcc_pragma_push_works=yes],
- [M4_cv_gcc_pragma_push_works=no])
- CFLAGS=$save_CFLAGS])
- if test $M4_cv_gcc_pragma_push_works = no; then
- nw="$nw -Wmissing-prototypes"
- nw="$nw -Wmissing-declarations"
- nw="$nw -Wunreachable-code"
- fi
-
- gl_MANYWARN_ALL_GCC([ws])
- gl_MANYWARN_COMPLEMENT([ws], [$ws], [$nw])
- for w in $ws; do
- gl_WARN_ADD([$w])
- done
-
- gl_WARN_ADD([-fdiagnostics-show-option])
- gl_WARN_ADD([-funit-at-a-time])
-
- AC_SUBST([WARN_CFLAGS])
-
- AH_VERBATIM([FORTIFY_SOURCE],
- [/* Enable compile-time and run-time bounds-checking, and some warnings,
- without upsetting newer glibc. */
- #if defined __OPTIMIZE__ && __OPTIMIZE__
- # define _FORTIFY_SOURCE 2
- #endif
- ])
-fi
-
-# Use gcc's -pipe option if available: for faster compilation.
-case "$CFLAGS" in
- *-pipe* ) ;;
- * ) _LT_COMPILER_OPTION([if $compiler supports -pipe],
- [M4_cv_prog_compiler_pipe],
- [-pipe -c conftest.$ac_ext], [],
- [CFLAGS="$CFLAGS -pipe"])
- ;;
-esac
-
-
-## ------------------------------- ##
-## Dynamic Loader Characteristics. ##
-## ------------------------------- ##
-
-LT_LIB_DLLOAD
-LT_SYS_SYMBOL_USCORE
-
-LT_SYS_MODULE_EXT
-
-if test yes = "$sys_symbol_underscore"; then
- libm4_shlibext=$libltdl_cv_shlibext
-
- AC_MSG_CHECKING([whether dlsym requires underscore prefixed symbols])
- AC_CACHE_VAL([libm4_cv_sys_dlsym_uscore], [dnl
- libname=conftmod # stay within 8.3 filename limits!
- cat >$libname.$ac_ext <<_M4_EOF
-[#line $LINENO "configure"
-#include "confdefs.h"
-/* When -fvisibility=hidden is used, assume the code has been annotated
- correspondingly for the symbols needed. */
-#if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
-int fnord () __attribute__((visibility("default")));
-#endif
-int fnord () { return 42; }]
-_M4_EOF
-
- # fn_module_cmds module_cmds
- # Execute tilde-delimited MODULE_CMDS with environment primed for
- # ${module_cmds} or ${archive_cmds} type content.
- fn_module_cmds ()
- {( # subshell avoids polluting parent global environment
- module_cmds_save_ifs=$IFS; IFS='~'
- for cmd in $1; do
- IFS=$module_cmds_save_ifs
- libobjs=$libname.$ac_objext; lib=$libname$libm4_shlibext
- rpath=/not-exists; soname=$libname$libm4_shlibext; output_objdir=.
- major=; versuffix=; verstring=; deplibs=
- ECHO=echo; wl=$lt_prog_compiler_wl; allow_undefined_flag=
- eval $cmd
- done
- IFS=$module_cmds_save_ifs
- )}
-
- # Compile a loadable module using libtool macro expansion results.
- $CC $pic_flag -c $libname.$ac_ext
- fn_module_cmds "${module_cmds:-$archive_cmds}"
-
- # Try to fetch fnord with dlsym().
- libm4_dlunknown=0; libm4_dlnouscore=1; libm4_dluscore=2
- cat >conftest.$ac_ext <<_M4_EOF
-[#line $LINENO "configure"
-#include "confdefs.h"
-#if HAVE_DLFCN_H
-#include <dlfcn.h>
-#endif
-#include <stdio.h>
-#ifndef RTLD_GLOBAL
-# ifdef DL_GLOBAL
-# define RTLD_GLOBAL DL_GLOBAL
-# else
-# define RTLD_GLOBAL 0
-# endif
-#endif
-#ifndef RTLD_NOW
-# ifdef DL_NOW
-# define RTLD_NOW DL_NOW
-# else
-# define RTLD_NOW 0
-# endif
-#endif
-int main () {
- void *handle = dlopen ("`pwd`/$libname$libm4_shlibext", RTLD_GLOBAL|RTLD_NOW);
- int status = $libm4_dlunknown;
- if (handle) {
- if (dlsym (handle, "fnord"))
- status = $libm4_dlnouscore;
- else {
- if (dlsym (handle, "_fnord"))
- status = $libm4_dluscore;
- else
- puts (dlerror ());
- }
- dlclose (handle);
- } else
- puts (dlerror ());
- return status;
-}]
-_M4_EOF
- if AC_TRY_EVAL(ac_link) && test -s "conftest$ac_exeext" 2>/dev/null; then
- (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null
- libm4_status=$?
- case x$libm4_status in
- x$libm4_dlnouscore) libm4_cv_sys_dlsym_uscore=no ;;
- x$libm4_dluscore) libm4_cv_sys_dlsym_uscore=yes ;;
- x*) libm4_cv_sys_dlsym_uscore=unknown ;;
- esac
- fi
- rm -rf conftest* $libname*
- ])
- sys_dlsym_uscore=$libm4_cv_sys_dlsym_uscore
- AC_MSG_RESULT($sys_dlsym_uscore)
- if test yes = "$sys_dlsym_uscore"; then
- AC_DEFINE([DLSYM_USCORE], [1],
- [Define if dlsym() requires a leading underscore in symbol names.])
- fi
-fi
-
-AC_DEFINE_UNQUOTED([PATH_SEPARATOR], ['$PATH_SEPARATOR'],
- [Define this to system search path delimiter])
-
-
-## ---------------- ##
-## Gettext support. ##
-## ---------------- ##
-AM_GNU_GETTEXT([external])
-AM_GNU_GETTEXT_NEED([need-formatstring-macros])
-AM_GNU_GETTEXT_VERSION([0.16])
-M4_GNU_GETTEXT
-
-
-## --------------- ##
-## Gnulib support. ##
-## --------------- ##
-M4_INIT
-
-gl_VERSION_ETC
-
-# Gnulib doesn't always do things quite the way M4 would like...
-M4_ERROR
-M4_GETOPT
-M4_OBSTACK
-M4_REGEX
-M4_RENAME
-
-
-## ------------------------- ##
-## C headers required by M4. ##
-## ------------------------- ##
-AC_CHECK_HEADERS_ONCE([limits.h])
-
-if test $ac_cv_header_stdbool_h = yes; then
- INCLUDE_STDBOOL_H='#include <stdbool.h>'
-else
- INCLUDE_STDBOOL_H='#include <gnu/stdbool.h>'
-fi
-AC_SUBST([INCLUDE_STDBOOL_H])
-
-
-## --------------------------------- ##
-## Library functions required by M4. ##
-## --------------------------------- ##
-AC_CHECK_FUNCS_ONCE([calloc strerror])
-
-AM_WITH_DMALLOC
-
-M4_SYS_STACKOVF
-
-# This is for the modules
-AC_STRUCT_TM
-AC_FUNC_STRFTIME
-AC_CHECK_FUNCS_ONCE([getcwd gethostname mktime uname])
-
-
-## ------------------ ##
-## Configure options. ##
-## ------------------ ##
-
-M4_LIB_GMP
-AM_CONDITIONAL([USE_GMP], [test "x$USE_GMP" = xyes])
-M4_SYSCMD
-
-
-## -------- ##
-## Outputs. ##
-## -------- ##
-AC_CONFIG_FILES([
-Makefile
-doc/Makefile
-m4/gnu/Makefile
-m4/system.h:m4/system_.h
-tests/atlocal
-tests/gnu/Makefile
-])
-
-AC_OUTPUT
diff --git a/doc/Makefile.am b/doc/Makefile.am
deleted file mode 100644
index 59648e51..00000000
--- a/doc/Makefile.am
+++ /dev/null
@@ -1,38 +0,0 @@
-## Makefile.am - template for generating Makefile via Automake
-##
-## Copyright (C) 2000-2001, 2003-2010, 2013-2014, 2017 Free Software
-## Foundation, Inc.
-##
-## This file is part of GNU M4.
-##
-## GNU M4 is free software: you can redistribute it and/or modify
-## it under the terms of the GNU General Public License as published by
-## the Free Software Foundation, either version 3 of the License, or
-## (at your option) any later version.
-##
-## GNU M4 is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-## GNU General Public License for more details.
-##
-## You should have received a copy of the GNU General Public License
-## along with this program. If not, see <http://www.gnu.org/licenses/>.
-##
-## Written by Gary V. Vaughan <gary@gnu.org>
-
-config_aux_dir = build-aux
-
-info_TEXINFOS = m4.texi
-m4_TEXINFOS = regexprops-generic.texi fdl-1.3.texi gpl-3.0.texi
-dist_man_MANS = $(srcdir)/m4.1
-EXTRA_DIST = gendocs_template
-MAINTAINERCLEANFILES = gendocs_template
-HELP2MAN = $(SHELL) $(top_srcdir)/$(config_aux_dir)/missing --run help2man
-
-# Build the man page once in the srcdir, rather than in every VPATH build
-# dir, to match how automake builds info pages. This is safe for 'make
-# distcheck' since it is distributed pre-built.
-$(srcdir)/m4.1: $(top_srcdir)/.version $(top_srcdir)/src/main.c
- @echo "Updating the \`man' page \`$@'"; \
- $(HELP2MAN) --name="macro processor" --source=FSF \
- --info-page=m4 --output=$@ $(top_srcdir)/src/m4$(EXEEXT)
diff --git a/doc/STYLE b/doc/STYLE
deleted file mode 100644
index 6b106446..00000000
--- a/doc/STYLE
+++ /dev/null
@@ -1,100 +0,0 @@
-GNU m4 STYLE - The way this code should look. -*- outline -*-
-
-Before all else this code follows the GNU coding standards and
-indentation style described in standards.info. Additionally the
-following restrictions on coding style apply:
-
-* SPACING
-
- + Avoid TABs in .h and .c files. See HACKING for details.
-
-* C STANDARD
-
- + All of this code is ANSI-C, GNU C extensions are conditional so that
- the code will compile cleanly on non GLIBC/GCC systems.
-
-* SYMBOL NAMES
-
- + All non-static symbols have a prefix either `M4' or `m4'.
-
- + All exported symbols which are part of the library api have the
- prefix `m4_'.
-
- + Symbols which are exported from the library (for efficiency perhaps)
- but are not part of the supported library api have the prefix
- `m4__',
-
- + Function names should be verb phrases; m4_module_get_field.
-
- + Functions which exist to be used as callbacks from API functions, and
- hence which likely have strange looking parameters are named with the
- suffix `_CB', to make it obvious why they look a little odd.
-
- + Macros which implement fast versions of functions share the
- same name as the function they replace, and may not evaluate
- parameters more than once.
-
- + Otherwise macros are in uppercase, prefixed `M4' if they are visible
- to the user after installation, to help the user know when to be
- careful about multiple evaluations of parameters.
-
- + Function names should contain the name of the module they belong to,
- usually immediately after the namespace prefix: m4_module_load.
-
- + Variables should not be exported (not true, but I'm working on it),
- but accessor functions used instead. Note the `get'/`set' part of
- the symbol name comes before the module part: m4_get_module_macros.
-
- + Structures come with accessor macros named <struct name>_<field
- name> (in upper case), to make refactoring of nested structures much
- easier: SYMBOL_FLAGS.
-
- + Structures are typedeffed separately, and the structure itself
- generally not exported unless in the `m4__' namespace to support
- fast accessor macros.
-
- + An opaque abstract data type (ADT) can have public and private fields:
- By convention public fields will have exported accessor functions (and
- maybe also fast macro versions of the same), and private fields will
- not export accessors at all. However, there should be non-exported
- (or at least in the `m4__' namespace) accessor functions for even the
- private fields of an ADT to aid possible later refactoring.
-
-* ARCHITECTURE
-
- + There are four groups of sources in subdirectories: `gnu' contains
- the files maintained outside of m4, as a portability layer when building
- the souce for non-glibc2 machines; `m4' contains the functionality for
- libm4 and enables the user to write modules; `modules' implements the
- builtin macros for the m4 binary; `src' is a small wrapper program
- which links libm4 and loads initial modules to implement the m4 engine.
-
- + The headers in gnu need to be managed carefully: gnulib headers
- can be included by other files in the same directory using `#include
- "file.h"', and from files in other directories with `#include
- <m4/file.h>'. The include path to invocations of the compiler from
- various Makefile.am are set to prevent the possibility of picking up
- an m4/file.h when the system file.h (e.g stdbool.h) is present. This,
- in turn means the replacement headers can live in gnulib/m4 without
- suffering a renaming scheme at configure time. Don't break with the
- `#include' convention, or the compile will go wrong in hard to debug
- ways on some platforms.
-
- + Low coupling. Classes (and in C, by this I mean files of functions)
- should not rely on a web of other classes to be useful, they should
- communicate with as few other classes as possible.
-
- + High cohesion. The api and caller boundaries should be well defined
- and adhered to; a class should do one thing only.
-
-========================================================================
-
-Copyright (C) 2003, 2006, 2010, 2013-2014, 2017 Free Software
-Foundation, Inc.
-
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
-Texts. A copy of the license is included in the ``GNU Free
-Documentation License'' file as part of this distribution.
diff --git a/doc/examples/COPYING b/doc/examples/COPYING
deleted file mode 100644
index e0170d74..00000000
--- a/doc/examples/COPYING
+++ /dev/null
@@ -1,8 +0,0 @@
-The files in this directory provide example uses of GNU M4.
-The following copyright notice applies to each of these
-description files.
-
-Copyright (C) 2006, 2010, 2013-2014, 2017 Free Software Foundation, Inc.
-This file is free software; the Free Software Foundation
-gives unlimited permission to copy and/or distribute it,
-with or without modifications, as long as this notice is preserved.
diff --git a/doc/examples/WWW/COPYING b/doc/examples/WWW/COPYING
deleted file mode 100644
index e0170d74..00000000
--- a/doc/examples/WWW/COPYING
+++ /dev/null
@@ -1,8 +0,0 @@
-The files in this directory provide example uses of GNU M4.
-The following copyright notice applies to each of these
-description files.
-
-Copyright (C) 2006, 2010, 2013-2014, 2017 Free Software Foundation, Inc.
-This file is free software; the Free Software Foundation
-gives unlimited permission to copy and/or distribute it,
-with or without modifications, as long as this notice is preserved.
diff --git a/doc/examples/WWW/Makefile b/doc/examples/WWW/Makefile
deleted file mode 100644
index c296ccf4..00000000
--- a/doc/examples/WWW/Makefile
+++ /dev/null
@@ -1,45 +0,0 @@
-M4 = ./m4/src/m4
-M4OPTS = -Im4lib
-
-VPATH = .:m4lib
-
-HTM = _footer.htm _header.htm bugs.htm changelog.htm download.htm \
- features.htm feedback.htm index.htm lists.htm modules.htm \
- news.htm readme.htm thanks.htm thissite.htm todo.htm uses.htm \
- visions.htm whatis.htm
-
-M4LIB = m4lib/bugs.m4 m4lib/changelog.m4 m4lib/download.m4 \
- m4lib/features.m4 m4lib/feedback.m4 m4lib/html.m4 \
- m4lib/index.m4 m4lib/layout.m4 m4lib/lists.m4 m4lib/menu.m4 \
- m4lib/modules.m4 m4lib/news.m4 m4lib/readme.m4 \
- m4lib/setup.m4 m4lib/test.m4 m4lib/thanks.m4 \
- m4lib/thissite.m4 m4lib/tmpl.m4 m4lib/todo.m4 m4lib/uses.m4 \
- m4lib/visions.m4 m4lib/whatis.m4
-
-all: ./m4 $(HTM)
-
-./m4:
- ln -s ../.. m4
-
-%.htm: %.m4
- @$(M4) $(M4OPTS) $< >new.htm && \
- if cmp new.htm $@ >/dev/null 2>&1; then \
- rm new.htm; \
- echo "$@ has not changed"; \
- else \
- echo "$@ updated"; \
- mv new.htm $@; \
- fi
-
-.FORCE:
-$(HTM): .FORCE $(M4LIB)
-
-changelog.htm: m4/ChangeLog
-readme.htm: m4/README
-todo.htm: m4/TODO
-news.htm: m4/NEWS
-modules.htm: m4/modules/README
-
-.PHONY: man
-man:
- cd man; $(MAKE)
diff --git a/doc/examples/WWW/_footer.htm b/doc/examples/WWW/_footer.htm
deleted file mode 100644
index 6bed8f2c..00000000
--- a/doc/examples/WWW/_footer.htm
+++ /dev/null
@@ -1,10 +0,0 @@
-</TD>
-
-</TR>
-
-</TABLE>
-
-</BODY>
-
-
-</HTML>
diff --git a/doc/examples/WWW/_header.htm b/doc/examples/WWW/_header.htm
deleted file mode 100644
index 1aea7999..00000000
--- a/doc/examples/WWW/_header.htm
+++ /dev/null
@@ -1,231 +0,0 @@
-<!DOCTYPE html public "-//w3c//dtd html 4.0 transitional//en">
-<HTML>
-<HEAD>
-<TITLE>GNU m4 - Development site</TITLE>
-<META NAME="AUTHOR" CONTENT="René Seindal">
-<META NAME="GENERATOR" CONTENT="GNU m4 __m4_version__">
-</HEAD>
- <BODY text="#000000" bgcolor="#FFCC99" link="#0000EF" alink="#FF0000" vlink="#51188E">
-<TABLE cellpadding=5 width="100%">
-<TR align=left valign=bottom>
-<TD align=center valign=middle colspan="3" width="100%" bgcolor="#FF9900">
-
-<H1>GNU m4</H1>
-
-<H2>Discussion Forum</H2>
-
-</TD>
-
-</TR>
- <TR >
-<TD align=left valign=top width="15%" bgcolor="#FF9900">
-
-
-
-
-
-
-
-
-
-
-
-<TABLE >
-<TR>
-<TD bgcolor="#CC6600">
-<P>
-<B>General info</B>
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD>
-<P>
-
-<FONT size=-1><B><A HREF="/rene/gnu/whatis.htm">What is m4</A><BR>
-<A HREF="/rene/gnu/features.htm">Features</A><BR>
-<A HREF="/rene/gnu/uses.htm">Uses of m4</A></B></FONT>
-
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD height=5>
-
-</TD>
-
-</TR>
- <TR>
-<TD bgcolor="#CC6600">
-<P>
-<B>Documentation</B>
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD>
-<P>
-
-<FONT size=-1><B><A HREF="/rene/gnu/man/m4_toc.html">Manual</A></B></FONT>
-
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD height=5>
-
-</TD>
-
-</TR>
- <TR>
-<TD bgcolor="#CC6600">
-<P>
-<B>Source files</B>
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD>
-<P>
-
-<FONT size=-1><B><A HREF="/rene/gnu/readme.htm">README</A><BR>
-<A HREF="/rene/gnu/todo.htm">TODO</A><BR>
-<A HREF="/rene/gnu/news.htm">NEWS</A><BR>
-<A HREF="/rene/gnu/changelog.htm">ChangeLog</A><BR>
-<A HREF="/rene/gnu/thanks.htm">Contributors</A><BR>
-<A HREF="/rene/gnu/m4/">Browse it</A></B></FONT>
-
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD height=5>
-
-</TD>
-
-</TR>
- <TR>
-<TD bgcolor="#CC6600">
-<P>
-<B>The Future</B>
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD>
-<P>
-
-<FONT size=-1><B><A HREF="/rene/gnu/modules.htm">Modules</A><BR>
-<A HREF="/rene/gnu/visions.htm">Visions</A></B></FONT>
-
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD height=5>
-
-</TD>
-
-</TR>
- <TR>
-<TD bgcolor="#CC6600">
-<P>
-<B>Feedback</B>
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD>
-<P>
-
-<FONT size=-1><B><A HREF="/rene/gnu/lists.htm">Mailing-lists</A><BR>
-<A HREF="/rene/gnu/feedback.htm">Feedback</A><BR>
-
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD height=5>
-
-</TD>
-
-</TR>
- <TR>
-<TD bgcolor="#CC6600">
-<P>
-<B>Development</B>
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD>
-<P>
-
-<FONT size=-1><B><A HREF="/rene/gnu/download.htm">Download</A><BR>
-<A HREF="/rene/gnu/bugs.htm">Known bugs</A></B></FONT>
-
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD height=5>
-
-</TD>
-
-</TR>
- <TR>
-<TD bgcolor="#CC6600">
-<P>
-<B>Examples</B>
-</P>
-
-</TD>
-
-</TR>
- <TR>
-<TD>
-<P>
-
-<FONT size=-1><B><A HREF="/rene/gnu/thissite.htm">This site</A></B></FONT>
-
-</P>
-
-</TD>
-
-</TR>
-
-</TABLE>
-
-
-
-
-
-
-
-
-</TD>
- <TD align=left valign=top width="90%">
diff --git a/doc/examples/WWW/m4lib/COPYING b/doc/examples/WWW/m4lib/COPYING
deleted file mode 100644
index e0170d74..00000000
--- a/doc/examples/WWW/m4lib/COPYING
+++ /dev/null
@@ -1,8 +0,0 @@
-The files in this directory provide example uses of GNU M4.
-The following copyright notice applies to each of these
-description files.
-
-Copyright (C) 2006, 2010, 2013-2014, 2017 Free Software Foundation, Inc.
-This file is free software; the Free Software Foundation
-gives unlimited permission to copy and/or distribute it,
-with or without modifications, as long as this notice is preserved.
diff --git a/doc/examples/WWW/m4lib/bugs.m4 b/doc/examples/WWW/m4lib/bugs.m4
deleted file mode 100644
index 5d8e5f52..00000000
--- a/doc/examples/WWW/m4lib/bugs.m4
+++ /dev/null
@@ -1,53 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([Known bugs in GNU m4 \__m4_version__])
-
-\divert(1)
-\h2([Known bugs in GNU m4])
-
-\define([fixed], [\p([Fixed in version 1.4$1])])
-
-\define([notme], [\p([A <A
-HREF="mailto:m4-feedback@seindal.dk?subject=GNU m4: \defn([_item])"
->volunteer</A> is badly needed for this, as I have no way of testing
-this myself.])])
-
-\ul([
-
-\item([undivert], [undivert(0) might read from standard output],
-
-[\p([If calling \tt(undivert(0)) when diverting to a non-zero diversion
-will cause m4 to read from standard output in an attempt to bring back
-diversion 0, which is not possible.])
-
-\fixed(n)
-
-])
-
-\item([sigaltstack], [failure if sigaltstack or sigstack returns ENOSYS],
-
-[\p([If stack overflow detection is configured but the system doesn't
-support sigaltstack(2) or sigstack(2), m4 fails when the system call
-returns ENOSYS. It should silently revert to default behaviour.])
-
-\notme
-])
-
-])
-
-\p([See also the \link(todo.htm, TODO) file.])
-
-\print_items
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
-
-
-\item([], [],
-
-[\p([])
-
-])
-\undivert
diff --git a/doc/examples/WWW/m4lib/changelog.m4 b/doc/examples/WWW/m4lib/changelog.m4
deleted file mode 100644
index cdcab269..00000000
--- a/doc/examples/WWW/m4lib/changelog.m4
+++ /dev/null
@@ -1,18 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([ChangeLog])
-
-\divert(1)
-
-<PRE>\dnl
-\changesyntax([A<>])\dnl
-\changequote(,)\dnl
-\include(m4/ChangeLog)
-\changequote([,])\dnl
-\changesyntax([O<>])\dnl
-</PRE>
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/download.m4 b/doc/examples/WWW/m4lib/download.m4
deleted file mode 100644
index d9ee4095..00000000
--- a/doc/examples/WWW/m4lib/download.m4
+++ /dev/null
@@ -1,24 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([Download])
-
-\divert(1)
-
-\p([In the download area there are usually several version
-present. Please take only the latest.])
-
-\p([The files are name \tt(m4-1.4\i(X).tar.gz) where X is a letter.])
-
-\p([\link([ftp://ftp.seindal.dk/pub/rene/gnu/], [Download latest
-development version]).])
-
-\p([\link([ftp://ftp.seindal.dk/pub/rene/gnu/m4-1.4.tar.gz],[Download
-latest stable version]).])
-
-\p([\link([ftp://ftp.seindal.dk/pub/rene/gnu/djgpp/],[Download
-DOS/Windows port of latest stable version]).])
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/features.m4 b/doc/examples/WWW/m4lib/features.m4
deleted file mode 100644
index 57b68c9e..00000000
--- a/doc/examples/WWW/m4lib/features.m4
+++ /dev/null
@@ -1,58 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([New feaures since version 1.4])
-
-\divert(1)
-
-\p(Please look at the \link(news.htm, NEWS) and the \link(changelog.htm,
-ChangeLog) for all the gory details.)
-
-\dl(
-\dt(\b(GNU m4 uses GNU Automake and GNU Autoconf for configuration.))
-
-\dd(\p(This has been long overdue, and now hit is done thanks to Erick
-Branderhorst.))
-
-\dt(\b(GNU m4 uses GNU gettext for internationalisation.))
-
-\dd(\p(GNU m4 now speaks several languages. Translations for
-german, french, italian, japanese, dutch, polish, romenian and swedish
-have been made.))
-
-\dt(\b(Support for multiple precision arithmetic in eval.))
-
-\dd(\p(If appropriately configured, GNU m4 can now do multiple precision
-arithmetic in the built in macro 'eval'. If not configured, GNU m4
-will use the largest integer available for its calculations.))
-
-\dt(\b(An input syntax table to change how input is parsed.))
-
-\dd(\p(A new build in macro 'changesyntax' allows finer control over how input
-characters are parsed into input tokens.&nbsp; It is now possible to have
-several one character quote strings or comment delimiters, to change the
-format of macro calls, to use active characters like in TeX, and probably
-most useful, to change what input characters are treated as letters when
-looking for macro calls.)
-
-\p(See the \link(man/m4_7.html#SEC41, manual section) for more details.))
-
-\dt(\b(Support for loadable modules.))
-
-\dd(\p(GNU m4 now has support for dynamic loading of compiled modules at
-runtime. A module can define any number of new built in macros, which
-will be indistinguishable from the standard set of built in
-macros. Modules can also override existing built in macros.)
-)
-
-\dt(\b(Better control of sync-lines generation.))
-
-\dd(\p(The new built in macro 'syncoutput' allows better control of the
-generation of sync-lines. They can now be turned on or off at
-will.))
-
-)
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/feedback.m4 b/doc/examples/WWW/m4lib/feedback.m4
deleted file mode 100644
index f61d63e5..00000000
--- a/doc/examples/WWW/m4lib/feedback.m4
+++ /dev/null
@@ -1,20 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([Feedback])
-
-\divert(1)
-
-\p(Bug reports should be sent to \link(mailto:bug-m4@gnu.org,
-bug-m4@gnu.org).)
-
-\p(Generel discussion about GNU m4 should take place on
-\link(mailto:m4-forum@seindal.dk, m4-forum).)
-
-\p(Informal comments about this site and GNU m4 can be sent to
-\link(mailto:m4-feedback@seindal.dk, m4-feedback).)
-
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/html.m4 b/doc/examples/WWW/m4lib/html.m4
deleted file mode 100644
index 94ed69ed..00000000
--- a/doc/examples/WWW/m4lib/html.m4
+++ /dev/null
@@ -1,122 +0,0 @@
-\define([n], [
-])
-
-\define([concat], [\ifelse($#, 0, ,
- $#, 1, [$1],
- [$1 \concat(\shift($@))])])
-
-\define([toupper], [\translit([$*], [a-z], [A-Z])])
-
-\define([container],
-[\pushdef([_tag], \toupper([$1]))\dnl
-\ifelse($#, 1, [<\_tag></[\_tag]>],
- $#, 2, [<\_tag>$2</\_tag>],
- $#, 3, [<\_tag $2>$3</\_tag>],
- [<\_tag $2>\concat(\shift(\shift($@)))</\_tag>])\dnl
-\popdef([_tag])\dnl
-])
-
-\define([large_container],
-[\pushdef([_tag], \toupper([$1]))\dnl
-\ifelse($#, 1, [<\_tag></\_tag>\n],
- $#, 2, [<\_tag>\n[]$2\n</\_tag>\n],
- $#, 3, [<\_tag $2>\n[]$3\n</\_tag>\n],
- [<\_tag $2>\n\concat(\shift(\shift($@)))\n</\_tag>\n])\dnl
-\popdef([_tag])\dnl
-])
-
-\define([large_simple_container],
-[\pushdef([_tag], \toupper([$1]))\dnl
-<\_tag>\n\concat(\shift($@))\n</\_tag>\n\dnl
-\popdef([_tag])\dnl
-])
-
-\define([simple_container],
-[\pushdef([_tag], \toupper([$1]))\dnl
-<\_tag>\concat(\shift($@))</\_tag>\dnl
-\popdef([_tag])\dnl
-])
-
-\define([simple_tag],
-[\pushdef([_tag], \toupper([$1]))\dnl
-\ifelse([$2], [], [<\_tag>], [<\_tag $2>])\dnl
-\popdef([_tag])\dnl
-])
-
-\define([doctype], [\simple_tag([!DOCTYPE], $@)])
-
-\define([html], [\large_simple_container([$0], $@)])
-\define([head], [\large_simple_container([$0], $@)])
-\define([title], [\simple_container([$0], $@)])
-
-\define([meta], [\n<META NAME="[$1]" CONTENT="[$2]">])
-\define([http_equiv], [\n<META HTTP-EQUIV="[$1]" CONTENT="[$2]">])
-
-\define([body], [\large_container([$0], $@)])
-
-\define([center], [\large_simple_container([$0], $@)])
-\define([right], [\large_simple_container([$0], $@)])
-\define([left], [\large_simple_container([$0], $@)])
-\define([div], [\large_container([$0], $@)])
-
-\define([b], [\simple_container([$0], $@)])
-\define([i], [\simple_container([$0], $@)])
-\define([tt], [\simple_container([$0], $@)])
-
-\define([table], [\large_container([$0], $@)])
-\define([tr], [\large_container([$0], $@)])
-\define([td], [\large_container([$0], $@)])
-\define([th], [\large_container([$0], $@)])
-
-\define([link], [<A HREF="$1">\shift($*)</A>])
-\define([target], [<A NAME="$1">\shift($*)</A>])
-
-\define([font], [\n\container([$0], $@)\n])
-
-\define([h1], [\n\container([$0], $@)\n])
-\define([h2], [\n\container([$0], $@)\n])
-\define([h3], [\n\container([$0], $@)\n])
-\define([h4], [\n\container([$0], $@)\n])
-\define([h5], [\n\container([$0], $@)\n])
-\define([h6], [\n\container([$0], $@)\n])
-
-\define([p], [\large_simple_container([$0], $@)])
-
-\define([hr], [\simple_tag([$0], $@)])
-
-\define([ul], [\large_container([$0], $@)])
-\define([ol], [\large_container([$0], $@)])
-
-\define([li], [\simple_tag([$0], $@)])
-
-\define([blockquote], [\large_simple_container([$0], $@)])
-
-\define([dl], [\large_simple_container([$0], $@)])
-\define([dt], [\simple_container([$0], $@)])
-\define([dd], [\large_simple_container([$0], $@)])
-
-\define([br], [\simple_tag([$0], $@)])
-\define([hline], [\simple_tag([$0], $@)])
-
-\define([pre], [\simple_container([$0], $@)])
-
-
-
-\define([set_title], [\define([_TITLE], [$*])])
-\set_title(_TITLE)
-
-\define([set_author], [\define([_AUTHOR], [$*])])
-\set_author()
-
-\define([set_generator], [\define([_GENERATOR], [$*])])
-\set_generator([GNU m4 \__m4_version__])
-
-\define([set_keywords], [\define([_KEYWORDS], [$*])])
-\set_keywords()
-
-\define([set_body], [\define([_BODY], [$*])])
-\set_body()
-
-\define([meta_if_set],
- [\ifelse(\defn([_$1]), [], [], \meta([$1], \defn([_$1])))]\dnl
-)
diff --git a/doc/examples/WWW/m4lib/index.m4 b/doc/examples/WWW/m4lib/index.m4
deleted file mode 100644
index dbccc67b..00000000
--- a/doc/examples/WWW/m4lib/index.m4
+++ /dev/null
@@ -1,36 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([Development site])
-
-\divert(1)
-\h2([Current development version is \__m4_version__.])
-
-\p([Development versions contain new features and experiments that might
-or might not make it into the next official release. The current
-development version contains among other things (browse the
-\link([features.htm], [new features]) for more detail):])
-
-\ul([
- \li Uses GNU Automake and GNU Autoconf for configuration.
-
- \li Uses GNU gettext for internationalisation.
-
- \li Support for multiple precision arithmetic in eval.
-
- \li An input syntax table to change how input is parsed.
-
- \li Support for loadable modules.
-
- \li Better control of sync-lines generation.
-
- \li Various bug-fixes.
-])
-
-\p([A new release is expected ready for Spring 2000.])
-
-\p([GNU \tt(m4) 1.4 is from october 1994 and can be considered stable.])
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/layout.m4 b/doc/examples/WWW/m4lib/layout.m4
deleted file mode 100644
index e54002db..00000000
--- a/doc/examples/WWW/m4lib/layout.m4
+++ /dev/null
@@ -1,65 +0,0 @@
-\divert(-1);
-The semicolons are just to get GNU Emacs C mode to indent properly.
-
-\define([C_TEXT], [text="#000000"]);
-\define([C_LINK], [link="#0000EF"]);
-\define([C_ALINK], [vlink="#51188E"]);
-\define([C_VLINK], [alink="#FF0000"]);
-\define([C_BG1], [bgcolor="#FFCC99"]);
-\define([C_BG2], [bgcolor="#FF9900"]);
-\define([C_BG3], [bgcolor="#CC6600"]);
-
-\define([DO_HEADER],
- [\head([\title([GNU m4 - \defn([_TITLE])])],
- [\meta_if_set([AUTHOR])],
- [\meta_if_set([GENERATOR])],
- [\meta_if_set([KEYWORDS])],
- )]);
-
-\define([DO_BODY],
- [\body([\C_TEXT \C_BG1 \C_LINK \C_VLINK \C_ALINK],
- [\table([cellpadding=5 width="100%"],
- [\tr([align=left valign=bottom],
- [\td([align=center valign=middle colspan="3" width="100%" \C_BG2],
- [\h1([GNU m4])],
- [\h2(\defn([_TITLE]))],
- )],
- )],
- [\tr([],
- [\td([align=left valign=top width="15%" \C_BG2],
- [\include([menu.m4])],
- )],
- [\td([align=left valign=top width="90%"],
- [$*],
- )],
- )],
- )],
- )]
- );
-
-\define([DO_LAYOUT],
- [\doctype([html public "-//w3c//dtd html 4.0 transitional//en"])
-\html([\DO_HEADER], [\DO_BODY([$*])])]
- );
-
-\define([<], [&lt;]);
-\define([>], [&gt;]);
-
-\define([showlink], [\link($1, $1)]);
-\define([mailto], [\link(mailto:$1, $1)]);
-
-
-<!-- These macros are for having first a simple toc and later a more
-thorough description of each item -->
-
-\define([print_items], [\undivert(2)])
-
-\define([item], [\li \link([[#]$1], [$2.])
-\pushdef([_div], \divnum)\dnl
-\divert(2)\dnl
-\hr([align=center width="50%"])\dnl
-\h2([\target([$1], [$2])])\dnl
-$3\dnl
-\divert(\_div)\dnl
-\popdef([_div])\dnl
-])
diff --git a/doc/examples/WWW/m4lib/lists.m4 b/doc/examples/WWW/m4lib/lists.m4
deleted file mode 100644
index cc710eba..00000000
--- a/doc/examples/WWW/m4lib/lists.m4
+++ /dev/null
@@ -1,32 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([Mailing lists])
-
-\define([me], \link([mailto:rene@seindal.dk], [rene@seindal.dk]))
-
-\divert(1)
-
-\h3(There are two mailing lists for GNU m4)
-
-\dl(
-
-\dt(\b(\link(mailto:m4-forum@seindal.dk, m4-forum@seindal.dk)))
-
-\dd(\p(This list is intended for discussions between people interested
-and/or participating in the further development of m4.))
-
-\dt(\b(m4-announce@seindal.dk))
-
-\dd(\p(Announcements regarding GNU m4 will posted here.)
-\p(The volume will certainly be very low.))
-
-)
-
-\p(Currently these lists are maintained manually. Send a message to \me
-saying whether you want to subscribe or unsubscribe to any of these
-lists.)
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/menu.m4 b/doc/examples/WWW/m4lib/menu.m4
deleted file mode 100644
index 78c8edfd..00000000
--- a/doc/examples/WWW/m4lib/menu.m4
+++ /dev/null
@@ -1,74 +0,0 @@
-\pushdef([header], [\tr([\td([\C_BG3], [\p([\b([$1])])])])])
-
-\pushdef([separator], [\tr([\td([height=5], [])])])
-
-\pushdef([_row], [\link([$1], [$2])])
-
-\pushdef([_rows],
- [\ifelse($#, 0, [],
- $#, 1, [],
- $#, 2, [\_row([$1], [$2])],
- $#, 3, [\_row([$1], [$2])],
- [\_row([$1], [$2])\br\n\_rows(\shift(\shift($@)))])])
-
-\pushdef([rows], [\tr([\td([\p([\font([size=-1], [\b([\_rows($@)])])])])])])
-
-\table([],
- [\header([General info])],
- [\rows(
- [whatis.htm], [What is m4],
- [features.htm], [Features],
- [uses.htm], [Uses of m4],
- )],
- [\separator],
-
- [\header([Documentation])],
- [\rows(
- [man/m4_toc.html], [Manual],
- )],
- [\separator],
-
- [\header([Source files])],
- [\rows(
- [readme.htm], [README],
- [todo.htm], [TODO],
- [news.htm], [NEWS],
- [changelog.htm], [ChangeLog],
- [thanks.htm], [Contributors],
- [m4/], [Browse it],
- )],
- [\separator],
-
- [\header([The Future])],
- [\rows(
- [modules.htm], [Modules],
- [visions.htm], [Visions],
- )],
- [\separator],
-
- [\header([Feedback])],
- [\rows(
- [lists.htm], [Mailing-lists],
- [feedback.htm], [Feedback],
- [/forum/list.php3?num=2], [Discussion Forum],
- )],
- [\separator],
-
- [\header([Development])],
- [\rows(
- [download.htm], [Download],
- [bugs.htm], [Known bugs],
- )],
- [\separator],
-
- [\header([Examples])],
- [\rows(
- [thissite.htm], [This site],
- )],
-)
-
-\popdef([header])
-\popdef([rows])
-\popdef([_rows])
-\popdef([_row])
-\popdef([separator])
diff --git a/doc/examples/WWW/m4lib/modules.m4 b/doc/examples/WWW/m4lib/modules.m4
deleted file mode 100644
index b9c148f1..00000000
--- a/doc/examples/WWW/m4lib/modules.m4
+++ /dev/null
@@ -1,18 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([Modules])
-
-\divert(1)
-
-<PRE>\dnl
-\changesyntax([A<>])\dnl
-\changequote(,)\dnl
-\include(m4/modules/README)
-\changequote([,])\dnl
-\changesyntax([O<>])\dnl
-</PRE>
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/news.m4 b/doc/examples/WWW/m4lib/news.m4
deleted file mode 100644
index e5da0d89..00000000
--- a/doc/examples/WWW/m4lib/news.m4
+++ /dev/null
@@ -1,18 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([NEWS - History of user-visible changes])
-
-\divert(1)
-
-<PRE>\dnl
-\changesyntax([A<>])\dnl
-\changequote(,)\dnl
-\include(m4/NEWS)
-\changequote([,])\dnl
-\changesyntax([O<>])\dnl
-</PRE>
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/readme.m4 b/doc/examples/WWW/m4lib/readme.m4
deleted file mode 100644
index 1612c7d1..00000000
--- a/doc/examples/WWW/m4lib/readme.m4
+++ /dev/null
@@ -1,18 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([README])
-
-\divert(1)
-
-<PRE>\dnl
-\changesyntax([A<>])\dnl
-\changequote(,)\dnl
-\include(m4/README)
-\changequote([,])\dnl
-\changesyntax([O<>])\dnl
-</PRE>
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/setup.m4 b/doc/examples/WWW/m4lib/setup.m4
deleted file mode 100644
index 310b65f8..00000000
--- a/doc/examples/WWW/m4lib/setup.m4
+++ /dev/null
@@ -1,7 +0,0 @@
-divert(-1)
-changequote([,])
-changecom([<!--], [-->])
-changesyntax([@\])
-
-\include([html.m4])
-\include([layout.m4])
diff --git a/doc/examples/WWW/m4lib/test.m4 b/doc/examples/WWW/m4lib/test.m4
deleted file mode 100644
index 110cf12b..00000000
--- a/doc/examples/WWW/m4lib/test.m4
+++ /dev/null
@@ -1,29 +0,0 @@
-include(`setup.m4')
-
-\divert(1)
-
-\define([_ideas], [])
-
-\define([register_idea],
-[\define([H_$1], [$2])\dnl
-\define([T_$1], [$3])\dnl
-\define([_ideas], [\print_idea([$1])]\defn([_ideas]))])
-
-\define([print_idea], [
-\target([$1], [\h2([\indir([H_$1])])])
-\indir([T_$1])
-])
-
-\define([print_ideas], [\indir([_ideas])])
-
-\define([idea], [\li \p([\link([[#]$1], [$2.])])\register_idea([$1], [$2], [$3])])
-
-\idea([guile], [Guile as an extension language], [gfhjdsfsarhgew])
-\idea([pquote], [Persistent quotes],[asdffhfdghgdsfh])
-\idea([deps], [Dependencies generation],[afsdffasdf])
-
-\print_ideas
-
-\undivert(1)
-
-\defn([_ideas])
diff --git a/doc/examples/WWW/m4lib/thanks.m4 b/doc/examples/WWW/m4lib/thanks.m4
deleted file mode 100644
index 61928d07..00000000
--- a/doc/examples/WWW/m4lib/thanks.m4
+++ /dev/null
@@ -1,18 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([People who have contributed to m4])
-
-\divert(1)
-
-<PRE>\dnl
-\changesyntax([A<>])\dnl
-\changequote(,)\dnl
-\include(m4/THANKS)
-\changequote([,])\dnl
-\changesyntax([O<>])\dnl
-</PRE>
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/thissite.m4 b/doc/examples/WWW/m4lib/thissite.m4
deleted file mode 100644
index eecfa9cf..00000000
--- a/doc/examples/WWW/m4lib/thissite.m4
+++ /dev/null
@@ -1,42 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([This site])
-
-\divert(1)
-
-\p([This GNU m4 site is maintained by René Seindal,
-(\mailto(rene@seindal.dk)).])
-
-\p([All files are generated using GNU m4 \__m4_version__. You can view
-the \link(m4lib/, source files). They are very simple. They use some
-features from GNU m4 1.4l])
-
-\p([The basic M4 definitions of quotes, comments, escapes are in
-\showlink(m4lib/setup.m4). This is first included by all files to
-configure the enviroment correctly for the other files. To avoid have
-macros called by accident, an escape character is defined with
-changesyntax. \i(This is a new feature in m4 1.4l).])
-
-\p([Some fairly general macros to generate various HTML construct are
-found in \showlink(m4lib/html.m4). There are macros for simple tags,
-containers with and without attributes, links and a few utility macros.])
-
-\p([The visual aspects of the pages are in \showlink(m4lib/layout.m4).
-The macros herein generate the complete HTML structure for the pages.
-There are macros for making the header and the body of the document.])
-
-\p([The definition of the left hand menu is in \showlink(m4lib/menu.m4).
-I convinced GNU Emacs to do the indentation by switching to c-mode.])
-
-\p([The page body is passed to the layout definitions as an argument. As
-the text can be large, it is first diverted and the text passed to the
-layout macros is simply a call to undivert. That way a very large text
-can be passed around with very little cost. This page is made with
-\link(m4lib/thissite.m4, these definitions).])
-
-\p([There is a single file for each HTML file.])
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/tmpl.m4 b/doc/examples/WWW/m4lib/tmpl.m4
deleted file mode 100644
index 8262d293..00000000
--- a/doc/examples/WWW/m4lib/tmpl.m4
+++ /dev/null
@@ -1,11 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([])
-
-\divert(1)
-\h2([])
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/todo.m4 b/doc/examples/WWW/m4lib/todo.m4
deleted file mode 100644
index 7a22c151..00000000
--- a/doc/examples/WWW/m4lib/todo.m4
+++ /dev/null
@@ -1,18 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([TODO - Things still to be done])
-
-\divert(1)
-
-<PRE>\dnl
-\changesyntax([A<>])\dnl
-\changequote(,)\dnl
-\include(m4/TODO)
-\changequote([,])\dnl
-\changesyntax([O<>])\dnl
-</PRE>
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/uses.m4 b/doc/examples/WWW/m4lib/uses.m4
deleted file mode 100644
index e29acb7a..00000000
--- a/doc/examples/WWW/m4lib/uses.m4
+++ /dev/null
@@ -1,43 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([Current uses of m4])
-
-\divert(1)
-
-\p(The MTA sendmail uses \tt(m4) for generating configuration files.)
-
-\p(\link(http://www.gnu.org/software/autoconf/autoconf.html, GNU
-Autoconf) uses \tt(m4) to generate "configure" scripts, that are used
-for configuring \link(http://www.gnu.org/, GNU) software for a
-particular platform.)
-
-\p(Htm4l is a set of macros for generating HTML. Html4 is written by
-Terry Jones (terry@cliffs.ucsd.edu). See
-\showlink(http://cliffs.ucsd.edu/terry/htm4l/htm4l/main.html) for
-details. )
-
-\p(Various programs uses m4 to preprocess configuration files, for
-example the X11 window manager fvwm.)
-
-\p(There is an \link(http://www.ssc.com/lg/issue22/using_m4.html,
-article in the Linux Gazette) about writing HTML with GNU m4 written by
-\link(mailto:bhepple@bit.net.au, Bob Hepple) . More recent versions
-are kept at \link(http://www.bit.net.au/~bhepple, Bob's home site).
-The macros are used to maintain a large commercial site at
-\showlink(http://www.finder.com.au).)
-
-\p(Other examples of GNU m4 generated HTML pages, written by
-\link(mailto:max@alcyone.com, Erik Max Francis) can be found at the sites
-\showlink(http://www.alcyone.com/max/),
-\showlink(http://www.catcam.com/),
-\showlink(http://www.crank.net/) and
-\showlink(http://www.pollywannacracka.com/).
-)
-
-\p(\link(thissite.htm, These files are created with GNU m4 \__m4_version__).)
-
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/WWW/m4lib/visions.m4 b/doc/examples/WWW/m4lib/visions.m4
deleted file mode 100644
index ba238ca9..00000000
--- a/doc/examples/WWW/m4lib/visions.m4
+++ /dev/null
@@ -1,232 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([The Road Ahead])
-
-\define([originator],
-[\p([Idea contributed by [$1]]\ifelse($#, 2, [ (\mailto([$2]))])[.])])
-
-\define([noone], [\p([There is no-one working on this now. Do you want
-to <A HREF="mailto:m4-feedback@seindal.dk?subject=GNU m4: \defn([_item])" >volunteer</A>?])])
-
-
-\define([done], [\p([Done in version 1.4$1])])
-
-
-\divert(1)
-\h2([Ideas for future versions of GNU m4])
-
-\p([Here are some ideas and suggestion for the future of GNU m4, large
-and small. The order here is fairly random.])
-
-\ul([
-
-\item([guile], [Guile as an extension language],
-
-[\p([\link([http://www.red-bean.com/guile/], [Guile]) can be used as an
-extension language so complicated macros can be written in Scheme while
-still maintaining the m4 interface. It will require some changes to the
-base code, as guile cannot be used from a module.])
-
-\noone <!-- \originator([René Seindal], [rene@seindal]) -->
-])
-
-
-\item([utf8], [UTF-8 or wide characters],
-
-[\p([GNU m4 should be able to handle UTF-8 input or wide characters so
-it can be more usable for different environments.])
-
-\noone <!-- \originator([François Pinard]) -->
-])
-
-
-\item([pquote], [Syntax: persistent quotes],
-
-[\p([Persistent quotes is a way of getting text unharmed through m4's
-processing. While normal quotes are stripped when a quoted string is
-read, the persistent quotes are removed just before being output. This
-will ensure that the quoted text is always output verbatim.])
-
-\p([The bulk of the changes will be in the parser (in input.c function
-next_token). Persistent quotes cannot be nested, they must balance
-within a normally quoted string, but normal quotes need not balance
-within persistent quotes (neither within persistent quotes within normal
-quotes). The quotes should be removed before being shipped out (in
-macro.c).])
-
-\noone <!-- \originator([Keith Bostic]) -->
-])
-
-
-
-
-\item([comment2], [Syntax: removable comments],
-
-[\p([With the syntax table a category for discardable comments can be
-defined, causing that type of comments to be discarded.])
-
-\noone
-])
-
-
-
-
-\item([comment1], [Option: remove comments],
-
-[\p([There should be an option (--discard-comments) to get m4 to discard
-comments instead of passing them to the output.])
-
-\done(n)
-])
-
-
-
-\item([deps], [Option: show dependencies],
-
-[\p([There should be an options to generate makefile dependencies for an
-M4 input file.])
-
-\p([It is not enough to scan the files for includes, as file names can
-be generated and builtins renamed. To make it work, m4 will have to do
-a complete run of the input file, discard the output and print the
-dependencies instead.])
-
-\p([It cannot be made to work in all cases when input file names are
-generated on the fly.])
-
-\noone <!-- \originator([Erick Branderhorst]) -->
-])
-
-
-\item([safer], [Option: render GNU m4 safer],
-
-[\p([There should be a --safer option that disables all functions, that
-could compromise system security if used by root. It will have to
-include various functions, such as file inclusion, sub shells, module
-loading, ...])
-
-\noone <!-- \originator([Santiago Vila]) -->
-])
-
-
-
-\item([import], [Option: import environment],
-
-[\p([An option to defined each environment variable as a macro on
-startup would be useful in many cases.])
-
-\done(n) <!-- \originator([René Seindal]) -->
-])
-
-
-
-\item([m4expand], [Builtin: quote expanded text],
-
-[\p([A builtin to quote expanded text would be useful. Now it is not
-possible to quote the expansion of a macro; the macro itself has to
-provide the quotes. Some builtins return quoted strings, others
-don't.])
-
-\p([A possible solution is a build in macro that takes one argument. It
-expands this argument fully and returns the quoted expansion.])
-
-\p([It will require changes to input handling and macro expansion code.])
-
-\noone <!-- \originator([Axel Boldt]) -->
-])
-
-
-
-\item([perl], [Module: embedded perl],
-
-[\p([Perl could be embedded in m4, giving users a powerful programming
-language for writing macros. A single builtin "perleval" could do the
-job. First argument could be a perl function and the rest arguments.
-The return value of the function as a string would be the expansion.])
-
-\p([The perl interpreter should be set up when the module is loaded and
-closed down before m4 exits, using the appropriate hooks in the module
-interface.])
-
-\p([A perl module could potentially give users access to any facility
-perl has access to, such as databases.])
-
-\p([On systems with perl compiled as a shared library the size penalty
-would be minimal.])
-
-\p([(It might not be workable as a module, as it will need to link with non-shared libraries. Don't know how it can be fixed. (RS))])
-
-\noone <!-- \originator([René Seindal]) -->
-])
-
-
-
-\item([output], [Module: better output control],
-
-[\p([It has been suggested a couple of times that it should be possible
-to divert to named files, in order to create several output files.])
-
-\p([I think this a bit a misunderstanding. Diversion are inteded to be
-brought back later, ie, they are temporary and recoverable. Output
-text, on the other hand, once output it is lost (for m4). Therefore
-better output control should be made in a different way.])
-
-\p([My suggestion is a set of builtins defined by a module:])
-
-\pre([setoutput(file)
-appendoutput(file)
-pipeoutput(command)])
-
-\p([With these output can be directed better, diversion can be sent to
-different files, and groups of files can be built by a single m4 run.
-Calling \tt(setoutput) without arguments should resume output to
-standard output.])
-
-\p([(Admittedly, diversion 0 (standard output) has always been
-different, as it cannot be undiverted.)])
-
-\noone <!-- \originator([René Seindal]) -->
-])
-
-
-
-\item([require], [Module: require/provide functionality],
-
-[\p([Two new builtins \tt(require) and \tt(provide) could provide a
-handy interface to include. It has proven difficult to write these
-robustly as normal macros. As an example, the files \tt(test.m4) and
-\tt(../test.m4) could be the same file or different files depending on
-the search path.])
-
-\noone <!-- \originator([Terry Jones]) -->
-])
-
-
-])
-
-
-
-\p([See also the \link(todo.htm, TODO) file.])
-
-\print_items
-
-
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
-
-\divert(3)saljdfnaskdjfndsa\divert(-1)
-
-
-
-
-\item([], [],
-
-[\p([])
-
-\noone
-])
-
-\undivert
diff --git a/doc/examples/WWW/m4lib/whatis.m4 b/doc/examples/WWW/m4lib/whatis.m4
deleted file mode 100644
index 2fa1c426..00000000
--- a/doc/examples/WWW/m4lib/whatis.m4
+++ /dev/null
@@ -1,48 +0,0 @@
-include(`setup.m4')
-
-\set_author([René Seindal])
-\set_title([What is GNU m4])
-
-\divert(1)
-
-\p([GNU \tt(m4) is an implementation of the traditional Unix macro
-processor. GNU m4 is mostly compatible with the System V, Release 3
-version, and SVR4, although it has some extensions (for example,
-handling more than 9 positional parameters to macros). GNU \tt(m4)
-also has built-in functions for including files, running shell
-commands, doing arithmetic, etc.])
-
-\p([GNU \tt(m4) is a macro processor, in the sense that it copies its
-input to the output, expanding macros as it goes. Macros are either
-builtin or user-defined, and can take any number of arguments. Besides
-just doing macro expansion, m4 has builtin functions for including named
-files, running UNIX commands, doing integer arithmetic, manipulating
-text in various ways, recursion, etc... m4 can be used either as a
-front-end to a compiler, or as a macro processor in its own right.])
-
-\p([The m4 macro processor is widely available on all UNIXes. Usually,
-only a small percentage of users are aware of its existence. However,
-those who do often become commited users. The growing popularity of GNU
-Autoconf, which prerequires GNU m4 for generating the `configure'
-scripts, is an incentive for many to install it, while these people will
-not themselves program in m4.])
-
-\p([Some people found m4 to be fairly addictive. They first use m4 for
-simple problems, then take bigger and bigger challenges, learning how to
-write complex m4 sets of macros along the way. Once really addicted,
-users pursue writing of sophisticated m4 applications even to solve
-simple problems, devoting more time debugging their m4 scripts than
-doing real work. Beware that m4 may be dangerous for the health of
-compulsive programmers.])
-
-\p([Autoconf needs GNU m4 for generating `configure' scripts, but not for
-running them.])
-
-\p([GNU m4 is a Unix program. It is designed to work in a Unix-like
-environment. GNU m4 1.4 has, however, been ported to DJGPP, the GNU C
-compiler for DOS/Windows. These files are present in the
-\link(download.htm, download area).])
-
-\divert(0)\dnl
-\DO_LAYOUT([\undivert(1)])
-\divert(-1)
diff --git a/doc/examples/capitalize.m4 b/doc/examples/capitalize.m4
deleted file mode 100644
index d4e4a502..00000000
--- a/doc/examples/capitalize.m4
+++ /dev/null
@@ -1,12 +0,0 @@
-divert(`-1')
-# upcase(text)
-# downcase(text)
-# capitalize(text)
-# change case of text, simple version
-define(`upcase', `translit(`$*', `a-z', `A-Z')')
-define(`downcase', `translit(`$*', `A-Z', `a-z')')
-define(`_capitalize',
- `regexp(`$1', `^\(\w\)\(\w*\)',
- `upcase(`\1')`'downcase(`\2')')')
-define(`capitalize', `patsubst(`$1', `\w+', `_$0(`\&')')')
-divert`'dnl
diff --git a/doc/examples/capitalize2.m4 b/doc/examples/capitalize2.m4
deleted file mode 100644
index 154dc505..00000000
--- a/doc/examples/capitalize2.m4
+++ /dev/null
@@ -1,19 +0,0 @@
-divert(`-1')
-# upcase(text)
-# downcase(text)
-# capitalize(text)
-# change case of text, improved version
-define(`upcase', `translit(`$*', `a-z', `A-Z')')
-define(`downcase', `translit(`$*', `A-Z', `a-z')')
-define(`_arg1', `$1')
-define(`_to_alt', `changequote(`<<[', `]>>')')
-define(`_from_alt', `changequote(<<[`]>>, <<[']>>)')
-define(`_upcase_alt', `translit(<<[$*]>>, <<[a-z]>>, <<[A-Z]>>)')
-define(`_downcase_alt', `translit(<<[$*]>>, <<[A-Z]>>, <<[a-z]>>)')
-define(`_capitalize_alt',
- `regexp(<<[$1]>>, <<[^\(\w\)\(\w*\)]>>,
- <<[_upcase_alt(<<[<<[\1]>>]>>)_downcase_alt(<<[<<[\2]>>]>>)]>>)')
-define(`capitalize',
- `_arg1(_to_alt()patsubst(<<[<<[$*]>>]>>, <<[\w+]>>,
- _from_alt()`]>>_$0_alt(<<[\&]>>)<<['_to_alt())_from_alt())')
-divert`'dnl
diff --git a/doc/examples/comments.m4 b/doc/examples/comments.m4
deleted file mode 100644
index c1e3be0a..00000000
--- a/doc/examples/comments.m4
+++ /dev/null
@@ -1,7 +0,0 @@
-# An ordinary comment
-define(`foo', # A comment in a macro
-`Macro `foo' expansion')
-foo
-define(`comment', `*** Macro `comment' expansion ***')
-changecom(`@', `@')
-foo
diff --git a/doc/examples/curry.m4 b/doc/examples/curry.m4
deleted file mode 100644
index 00997c38..00000000
--- a/doc/examples/curry.m4
+++ /dev/null
@@ -1,7 +0,0 @@
-divert(`-1')
-# curry(macro, args)
-# Expand to a macro call that takes one argument, then invoke
-# macro(args, extra).
-define(`curry', `$1(shift($@,)_$0')
-define(`_curry', ``$1')')
-divert`'dnl
diff --git a/doc/examples/ddivert.m4 b/doc/examples/ddivert.m4
deleted file mode 100644
index e6e0017e..00000000
--- a/doc/examples/ddivert.m4
+++ /dev/null
@@ -1,4 +0,0 @@
-divert(1)Text diverted a first time.
-divert(0)undivert(1)dnl
-divert(1)Text diverted a second time.
-divert(0)undivert(1)dnl
diff --git a/doc/examples/debug.m4 b/doc/examples/debug.m4
deleted file mode 100644
index 16f4c74e..00000000
--- a/doc/examples/debug.m4
+++ /dev/null
@@ -1,4 +0,0 @@
-define(`countdown', `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Liftoff')')
-debugmode(`aeqc')
-traceon(`countdown')
-countdown(2)
diff --git a/doc/examples/esyscmd.m4 b/doc/examples/esyscmd.m4
deleted file mode 100644
index 3c856e02..00000000
--- a/doc/examples/esyscmd.m4
+++ /dev/null
@@ -1,6 +0,0 @@
-# Cannot use real hostname program because test would fail
-define(`hostname', esyscmd(`echo www.gnu.org'))dnl
-`hostname = >>'hostname`<<'
-define(`hostname',
-pushdef(`_tmp', `$1')_tmp(translit(esyscmd(`echo www.gnu.org'), `.', `,'))`'popdef(`_tmp'))dnl
-`hostname = >>'hostname`<<'
diff --git a/doc/examples/exp.m4 b/doc/examples/exp.m4
deleted file mode 100644
index e2bcf943..00000000
--- a/doc/examples/exp.m4
+++ /dev/null
@@ -1,3 +0,0 @@
-define(`countdown', `$1
-ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Done')')dnl
-countdown(7)
diff --git a/doc/examples/foreach.m4 b/doc/examples/foreach.m4
deleted file mode 100644
index 9be25b08..00000000
--- a/doc/examples/foreach.m4
+++ /dev/null
@@ -1,8 +0,0 @@
-divert(`-1')
-# foreach(x, (item_1, item_2, ..., item_n), stmt)
-# parenthesized list, simple version
-define(`foreach', `pushdef(`$1')_foreach($@)popdef(`$1')')
-define(`_arg1', `$1')
-define(`_foreach', `ifelse(`$2', `()', `',
- `define(`$1', _arg1$2)$3`'$0(`$1', (shift$2), `$3')')')
-divert`'dnl
diff --git a/doc/examples/foreach2.m4 b/doc/examples/foreach2.m4
deleted file mode 100644
index 74d00fb6..00000000
--- a/doc/examples/foreach2.m4
+++ /dev/null
@@ -1,10 +0,0 @@
-include(`quote.m4')dnl
-divert(`-1')
-# foreach(x, (item_1, item_2, ..., item_n), stmt)
-# parenthesized list, improved version
-define(`foreach', `pushdef(`$1')_$0(`$1',
- (dquote(dquote_elt$2)), `$3')popdef(`$1')')
-define(`_arg1', `$1')
-define(`_foreach', `ifelse(`$2', `(`')', `',
- `define(`$1', _arg1$2)$3`'$0(`$1', (dquote(shift$2)), `$3')')')
-divert`'dnl
diff --git a/doc/examples/foreachq.m4 b/doc/examples/foreachq.m4
deleted file mode 100644
index d34fb5b9..00000000
--- a/doc/examples/foreachq.m4
+++ /dev/null
@@ -1,9 +0,0 @@
-include(`quote.m4')dnl
-divert(`-1')
-# foreachq(x, `item_1, item_2, ..., item_n', stmt)
-# quoted list, simple version
-define(`foreachq', `pushdef(`$1')_foreachq($@)popdef(`$1')')
-define(`_arg1', `$1')
-define(`_foreachq', `ifelse(quote($2), `', `',
- `define(`$1', `_arg1($2)')$3`'$0(`$1', `shift($2)', `$3')')')
-divert`'dnl
diff --git a/doc/examples/foreachq2.m4 b/doc/examples/foreachq2.m4
deleted file mode 100644
index f57d3edf..00000000
--- a/doc/examples/foreachq2.m4
+++ /dev/null
@@ -1,10 +0,0 @@
-include(`quote.m4')dnl
-divert(`-1')
-# foreachq(x, `item_1, item_2, ..., item_n', stmt)
-# quoted list, improved version
-define(`foreachq', `pushdef(`$1')_$0($@)popdef(`$1')')
-define(`_arg1q', ``$1'')
-define(`_rest', `ifelse(`$#', `1', `', `dquote(shift($@))')')
-define(`_foreachq', `ifelse(`$2', `', `',
- `define(`$1', _arg1q($2))$3`'$0(`$1', _rest($2), `$3')')')
-divert`'dnl
diff --git a/doc/examples/foreachq3.m4 b/doc/examples/foreachq3.m4
deleted file mode 100644
index 5e656727..00000000
--- a/doc/examples/foreachq3.m4
+++ /dev/null
@@ -1,9 +0,0 @@
-divert(`-1')
-# foreachq(x, `item_1, item_2, ..., item_n', stmt)
-# quoted list, alternate improved version
-define(`foreachq', `ifelse(`$2', `', `',
- `pushdef(`$1')_$0(`$1', `$3', `', $2)popdef(`$1')')')
-define(`_foreachq', `ifelse(`$#', `3', `',
- `define(`$1', `$4')$2`'$0(`$1', `$2',
- shift(shift(shift($@))))')')
-divert`'dnl
diff --git a/doc/examples/foreachq4.m4 b/doc/examples/foreachq4.m4
deleted file mode 100644
index 3da64c92..00000000
--- a/doc/examples/foreachq4.m4
+++ /dev/null
@@ -1,13 +0,0 @@
-include(`forloop2.m4')dnl
-divert(`-1')
-# foreachq(x, `item_1, item_2, ..., item_n', stmt)
-# quoted list, version based on forloop
-define(`foreachq',
-`ifelse(`$2', `', `', `_$0(`$1', `$3', $2)')')
-define(`_foreachq',
-`pushdef(`$1', forloop(`$1', `3', `$#',
- `$0_(`1', `2', indir(`$1'))')`popdef(
- `$1')')indir(`$1', $@)')
-define(`_foreachq_',
-``define(`$$1', `$$3')$$2`''')
-divert`'dnl
diff --git a/doc/examples/forloop.m4 b/doc/examples/forloop.m4
deleted file mode 100644
index fdca2608..00000000
--- a/doc/examples/forloop.m4
+++ /dev/null
@@ -1,6 +0,0 @@
-divert(`-1')
-# forloop(var, from, to, stmt) - simple version
-define(`forloop', `pushdef(`$1', `$2')_forloop($@)popdef(`$1')')
-define(`_forloop',
- `$4`'ifelse($1, `$3', `', `define(`$1', incr($1))$0($@)')')
-divert`'dnl
diff --git a/doc/examples/forloop2.m4 b/doc/examples/forloop2.m4
deleted file mode 100644
index b7154e86..00000000
--- a/doc/examples/forloop2.m4
+++ /dev/null
@@ -1,12 +0,0 @@
-divert(`-1')
-# forloop(var, from, to, stmt) - improved version:
-# works even if VAR is not a strict macro name
-# performs sanity check that FROM is larger than TO
-# allows complex numerical expressions in TO and FROM
-define(`forloop', `ifelse(eval(`($2) <= ($3)'), `1',
- `pushdef(`$1')_$0(`$1', eval(`$2'),
- eval(`$3'), `$4')popdef(`$1')')')
-define(`_forloop',
- `define(`$1', `$2')$4`'ifelse(`$2', `$3', `',
- `$0(`$1', incr(`$2'), `$3', `$4')')')
-divert`'dnl
diff --git a/doc/examples/forloop3.m4 b/doc/examples/forloop3.m4
deleted file mode 100644
index 98db20f3..00000000
--- a/doc/examples/forloop3.m4
+++ /dev/null
@@ -1,13 +0,0 @@
-divert(`-1')
-# forloop_arg(from, to, macro) - invoke MACRO(value) for
-# each value between FROM and TO, without define overhead
-define(`forloop_arg', `ifelse(eval(`($1) <= ($2)'), `1',
- `_forloop(`$1', eval(`$2'), `$3(', `)')')')
-# forloop(var, from, to, stmt) - refactored to share code
-define(`forloop', `ifelse(eval(`($2) <= ($3)'), `1',
- `pushdef(`$1')_forloop(eval(`$2'), eval(`$3'),
- `define(`$1',', `)$4')popdef(`$1')')')
-define(`_forloop',
- `$3`$1'$4`'ifelse(`$1', `$2', `',
- `$0(incr(`$1'), `$2', `$3', `$4')')')
-divert`'dnl
diff --git a/doc/examples/fstab.m4 b/doc/examples/fstab.m4
deleted file mode 100644
index 8d10e176..00000000
--- a/doc/examples/fstab.m4
+++ /dev/null
@@ -1,6 +0,0 @@
-define(`concat', `translit(``$*'', ` ')')
-define(`fsent', `format(`%-25s %-16s nfs %-16s 0 0', `$1:$2', `$3', concat$4)')
-
-fsent(freja, /home/gevn, /home/gevn, (rw, soft, bg, grpid))
-fsent(freja, /home/freja, /home/freja, (rw, soft, grpid))
-fsent(rimfaxe, /home/rimfaxe, /home/rimfaxe, (rw, soft, bg))
diff --git a/doc/examples/hanoi.m4 b/doc/examples/hanoi.m4
deleted file mode 100644
index 32fd8a41..00000000
--- a/doc/examples/hanoi.m4
+++ /dev/null
@@ -1,17 +0,0 @@
-divert(-1)
-
-# move(from, to)
-define(`move', `Move one disk from `$1' to `$2'.
-')
-
-# _hanoi (cnt, from, to, aux)
-define(`_hanoi', `ifelse(eval(`$1'<=1), 1, `move($2, $3)',
-`$0(decr($1), $2, $4, $3)move($2, $3)$0(decr($1), $4, $3, $2)')')
-
-# hanoi (cnt)
-define(`hanoi', `_$0(`$1', source, destination, auxilliary)')
-
-# traceon(`move', `_hanoi', `decr')
-divert`'dnl
-
-hanoi(3)
diff --git a/doc/examples/incl-test.m4 b/doc/examples/incl-test.m4
deleted file mode 100644
index 323fa05b..00000000
--- a/doc/examples/incl-test.m4
+++ /dev/null
@@ -1,3 +0,0 @@
-dnl noauto
-`include test file.'
-define()
diff --git a/doc/examples/incl.m4 b/doc/examples/incl.m4
deleted file mode 100644
index ab9572eb..00000000
--- a/doc/examples/incl.m4
+++ /dev/null
@@ -1,3 +0,0 @@
-Include file start
-foo
-Include file end
diff --git a/doc/examples/include.m4 b/doc/examples/include.m4
deleted file mode 100644
index 8e9d9d2f..00000000
--- a/doc/examples/include.m4
+++ /dev/null
@@ -1,7 +0,0 @@
-Beginning.
-include(`NOFILE')
-Intermediate
-include(`incl-test.m4')
-After
-include(`NOFILE')
-very late
diff --git a/doc/examples/indir.m4 b/doc/examples/indir.m4
deleted file mode 100644
index 51d2b64f..00000000
--- a/doc/examples/indir.m4
+++ /dev/null
@@ -1,10 +0,0 @@
-define(`%%$$##', `>>>$0<<< cnt $#')
-
-# indir(`%%$$##', nonsense, nonsense)
-indir(`%%$$##', nonsense, nonsense)
-
-# indir(`indir', `%%$$##', nonsense)
-indir(`indir', `%%$$##', nonsense)
-
-# indir(`indir', `indir', `indir', `indir', `%%$$##')
-indir(`indir', `indir', `indir', `indir', `%%$$##')
diff --git a/doc/examples/join.m4 b/doc/examples/join.m4
deleted file mode 100644
index 8687ac70..00000000
--- a/doc/examples/join.m4
+++ /dev/null
@@ -1,15 +0,0 @@
-divert(`-1')
-# join(sep, args) - join each non-empty ARG into a single
-# string, with each element separated by SEP
-define(`join',
-`ifelse(`$#', `2', ``$2'',
- `ifelse(`$2', `', `', ``$2'_')$0(`$1', shift(shift($@)))')')
-define(`_join',
-`ifelse(`$#$2', `2', `',
- `ifelse(`$2', `', `', ``$1$2'')$0(`$1', shift(shift($@)))')')
-# joinall(sep, args) - join each ARG, including empty ones,
-# into a single string, with each element separated by SEP
-define(`joinall', ``$2'_$0(`$1', shift($@))')
-define(`_joinall',
-`ifelse(`$#', `2', `', ``$1$3'$0(`$1', shift(shift($@)))')')
-divert`'dnl
diff --git a/doc/examples/loop.m4 b/doc/examples/loop.m4
deleted file mode 100644
index b2fc64c4..00000000
--- a/doc/examples/loop.m4
+++ /dev/null
@@ -1,18 +0,0 @@
-dnl Stress test for recursion algorithms. Usage:
-dnl m4 -Ipath/to/examples [-Doptions] loop.m4
-dnl Options include:
-dnl -Dalt[=<n>] - test with foreachq<n> instead of foreachq2, default 3
-dnl -Dlimit=<num> - set upper limit of sequence to <num>, default 1000
-dnl -Dverbose - print the sequence to the screen, rather than discarding
-dnl -Ddebug[=<code>] - execute <code> after forloop but before foreach
-dnl -Dsleep=<num> - sleep for <num> seconds before exit, to allow time
-dnl to examine peak process memory usage
-include(`forloop2.m4')dnl
-include(`quote.m4')dnl
-ifelse(alt, `alt', `define(`alt', `2')', alt, `', `define(`alt', `3')')dnl
-include(`foreachq'alt`.m4')dnl
-ifdef(`limit', `', `define(`limit', `1000')')dnl
-ifdef(`verbose', `', `divert(`-1')')dnl
-ifdef(`debug', `', `define(`debug')')dnl
-foreachq(`i', dquote(1forloop(`i', `2', limit, `,i'))debug, ` i')
-ifdef(`sleep',`syscmd(`echo done>/dev/tty;sleep 'sleep)')dnl
diff --git a/doc/examples/misc.m4 b/doc/examples/misc.m4
deleted file mode 100644
index 979b51aa..00000000
--- a/doc/examples/misc.m4
+++ /dev/null
@@ -1,8 +0,0 @@
-divert(-1)
-define(`USER', `root')
-define(`TMP', maketemp(`/tmp/hejXXXXXX'))
-syscmd(`grep "^'USER`:" /etc/passwd | awk -F: "{print \$3}"' > TMP)
-define(`UID', include(TMP))
-syscmd(`rm -f' TMP)
-divert
-UID
diff --git a/doc/examples/modtest.m4 b/doc/examples/modtest.m4
deleted file mode 100644
index 17e6b02f..00000000
--- a/doc/examples/modtest.m4
+++ /dev/null
@@ -1,8 +0,0 @@
-dnl Copyright (C) 2006, 2010, 2013-2014, 2017 Free Software Foundation,
-dnl Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it
-dnl with or without modifications, as long as this notice is preserved.
-load(`modtest')
-test
-Dumpdef: dumpdef(`test').
diff --git a/doc/examples/multiquotes.m4 b/doc/examples/multiquotes.m4
deleted file mode 100644
index b56cfbd8..00000000
--- a/doc/examples/multiquotes.m4
+++ /dev/null
@@ -1,17 +0,0 @@
-traceon
-changequote([,])dnl
-changequote([``], [''])dnl
-````traceon''''
-define(``foo'', ````FOO'''')dnl
-dumpdef(``foo'')dnl
-changequote(``!'', ``!'')dnl
-!foo!
-foo
-dumpdef(!foo!)dnl
-define(!bar!, !BAR!)
-bar
-changequote(!>*>*>*>*>!, !<*<*<*<*<!)dnl five of each
->*>*>*>*>foo bar<*<*<*<*<
-foo bar
->*>*>*>*>*>*><*<*<*<*<*<*<
-dumpdef(>*>*>*>*>foo<*<*<*<*<, >*>*>*>*>bar<*<*<*<*<)dnl
diff --git a/doc/examples/patsubst.m4 b/doc/examples/patsubst.m4
deleted file mode 100644
index 9b4c7591..00000000
--- a/doc/examples/patsubst.m4
+++ /dev/null
@@ -1,8 +0,0 @@
-# traceon(`patsubst')
-patsubst(`GNUs not Unix.', `^', `OBS: ')
-patsubst(`GNUs not Unix.', `\<', `OBS: ')
-patsubst(`GNUs not Unix.', `\<\w', `\0=')
-patsubst(`GNUs not Unix.', `\w*', `(\0)')
-patsubst(`GNUs not Unix.', `\w+', `(\0)')
-patsubst(`GNUs not Unix.', `\w+')
-patsubst(`GNUs not '` Unix.', `[ ]+', ` ')
diff --git a/doc/examples/pushpop.m4 b/doc/examples/pushpop.m4
deleted file mode 100644
index d0f2ebb8..00000000
--- a/doc/examples/pushpop.m4
+++ /dev/null
@@ -1,25 +0,0 @@
-divert(-1)
-pushdef(`hej', `def 1.')
-dumpdef(`hej')
-pushdef(`hej', `def 2.')
-dumpdef(`hej')
-pushdef(`hej', `def 3.')
-dumpdef(`hej')
-pushdef(`hej', `def 4.')
-dumpdef(`hej')
-
-popdef(`hej')
-dumpdef(`hej')
-popdef(`hej')
-dumpdef(`hej')
-popdef(`hej')
-dumpdef(`hej')
-popdef(`hej')
-dumpdef(`hej')
-popdef(`hej')
-dumpdef(`hej')
-popdef(`hej')
-
-dumpdef(`mac2')
-popdef(`mac2')
-dumpdef(`mac2')
diff --git a/doc/examples/quote.m4 b/doc/examples/quote.m4
deleted file mode 100644
index fae52c3e..00000000
--- a/doc/examples/quote.m4
+++ /dev/null
@@ -1,9 +0,0 @@
-divert(`-1')
-# quote(args) - convert args to single-quoted string
-define(`quote', `ifelse(`$#', `0', `', ``$*'')')
-# dquote(args) - convert args to quoted list of quoted strings
-define(`dquote', ``$@'')
-# dquote_elt(args) - convert args to list of double-quoted strings
-define(`dquote_elt', `ifelse(`$#', `0', `', `$#', `1', ```$1''',
- ```$1'',$0(shift($@))')')
-divert`'dnl
diff --git a/doc/examples/regexp.m4 b/doc/examples/regexp.m4
deleted file mode 100644
index a4ca573e..00000000
--- a/doc/examples/regexp.m4
+++ /dev/null
@@ -1,12 +0,0 @@
-traceon(`regexp')dnl
-regexp(`hej med dig', `.*', `>>\0<<')
-regexp(`hej med dig', `\w*', `>>\0<<')
-regexp(`hej med dig', `.+', `>>\0<<')
-regexp(`hej med dig', `m\w+', `>>\0<<')
-regexp(`hej med dig', `m\(.*\)', `>>\0<< >>\1<<')
-
-regexp(`hej med dig', `.*')
-regexp(`hej med dig', `\w*')
-regexp(`hej med dig', `.+')
-regexp(`hej med dig', `m\w+')
-regexp(`hej med dig', `m\(.*\)')
diff --git a/doc/examples/reverse.m4 b/doc/examples/reverse.m4
deleted file mode 100644
index 7e2374e2..00000000
--- a/doc/examples/reverse.m4
+++ /dev/null
@@ -1,4 +0,0 @@
-define(`reverse', `ifelse(eval($# > 1), 1, `reverse(shift($@)), `$1'', ``$1'')')
-``'' => reverse.
-``hej'' => reverse(hej).
-``hej, med, dig'' => reverse(hej, med, dig).
diff --git a/doc/examples/shadow.m4 b/doc/examples/shadow.m4
deleted file mode 100644
index d82b8443..00000000
--- a/doc/examples/shadow.m4
+++ /dev/null
@@ -1,58 +0,0 @@
-dnl Copyright (C) 2006, 2010, 2013-2014, 2017 Free Software Foundation,
-dnl Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it
-dnl with or without modifications, as long as this notice is preserved.
-# no modules loaded yet
-test
-shadow
-
-# define our own macros for `test' and `shadow'
-define(`test', `local::`test'')
-define(`shadow', `local::`shadow'')
-test
-shadow
-
-# module Shadow defines `shadow' and `test' macros
-load(`shadow')
-dumpdef(`test')
-dumpdef(`shadow')
-test
-shadow
-
-# save the definition of `test' from the Shadow module
-define(`Shadow::test', defn(`test'))
-
-# module Test also defines a `test' macro
-load(`modtest')
-dumpdef(`test')
-dumpdef(`shadow')
-test
-shadow
-
-# Reloading Shadow shouldn't affect anything
-load(`shadow')
-dumpdef(`test')
-dumpdef(`shadow')
-test
-shadow
-
-# Unloading Test will unshadow the test definition in Shadow
-unload(`modtest')
-dumpdef(`test')
-dumpdef(`shadow')
-test
-shadow
-
-# Unloading Shadow once has no effect (we loaded it twice)
-unload(`shadow')
-dumpdef(`test')
-dumpdef(`shadow')
-test
-shadow
-
-# Unloading Shadow again will revert to copying `test' and the local
-# `shadow' macro.
-unload(`shadow')
-test
-shadow
diff --git a/doc/examples/stack.m4 b/doc/examples/stack.m4
deleted file mode 100644
index c1b98333..00000000
--- a/doc/examples/stack.m4
+++ /dev/null
@@ -1,16 +0,0 @@
-divert(`-1')
-# stack_foreach(macro, action)
-# Invoke ACTION with a single argument of each definition
-# from the definition stack of MACRO, starting with the oldest.
-define(`stack_foreach',
-`_stack_reverse(`$1', `tmp-$1')'dnl
-`_stack_reverse(`tmp-$1', `$1', `$2(defn(`$1'))')')
-# stack_foreach_lifo(macro, action)
-# Invoke ACTION with a single argument of each definition
-# from the definition stack of MACRO, starting with the newest.
-define(`stack_foreach_lifo',
-`_stack_reverse(`$1', `tmp-$1', `$2(defn(`$1'))')'dnl
-`_stack_reverse(`tmp-$1', `$1')')
-define(`_stack_reverse',
-`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0($@)')')
-divert`'dnl
diff --git a/doc/examples/stack_sep.m4 b/doc/examples/stack_sep.m4
deleted file mode 100644
index 767d15e2..00000000
--- a/doc/examples/stack_sep.m4
+++ /dev/null
@@ -1,17 +0,0 @@
-divert(`-1')
-# stack_foreach_sep(macro, pre, post, sep)
-# Invoke PRE`'defn`'POST with a single argument of each definition
-# from the definition stack of MACRO, starting with the oldest, and
-# separated by SEP between definitions.
-define(`stack_foreach_sep',
-`_stack_reverse_sep(`$1', `tmp-$1')'dnl
-`_stack_reverse_sep(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4`'')')
-# stack_foreach_sep_lifo(macro, pre, post, sep)
-# Like stack_foreach_sep, but starting with the newest definition.
-define(`stack_foreach_sep_lifo',
-`_stack_reverse_sep(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4`'')'dnl
-`_stack_reverse_sep(`tmp-$1', `$1')')
-define(`_stack_reverse_sep',
-`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
- `$1', `$2', `$4$3')')')
-divert`'dnl
diff --git a/doc/examples/stdlib.m4 b/doc/examples/stdlib.m4
deleted file mode 100644
index 14df4575..00000000
--- a/doc/examples/stdlib.m4
+++ /dev/null
@@ -1,45 +0,0 @@
-dnl Copyright (C) 2006, 2010, 2013-2014, 2017 Free Software Foundation,
-dnl Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it
-dnl with or without modifications, as long as this notice is preserved.
-load(`stdlib')
-
-`getenv - 'getenv(PATH)
-
-setenv TEST=??? setenv(`TEST', `???')
-getenv TEST - getenv(`TEST')
-
-setenv TEST=Second test setenv(`TEST', `Second test')
-getenv TEST - getenv(`TEST')
-
-unsetenv TEST unsetenv(`TEST')
-getenv TEST - getenv(`TEST')
-
-
-
-`getlogin - 'getlogin
-`getcwd = 'getcwd
-`getpid - 'getpid
-`getppid - 'getppid
-
-syscmd(`ps ajx|grep m4')
-
-`getuid - 'getuid
-
-user root - getpwnam(`root')
-user sync - getpwnam(`sync')
-user rene - getpwnam(`rene')
-
-uid 5 - getpwuid(5)
-me - getpwuid(getuid)
-
-`hostname = 'hostname
-
-`rand' - rand,rand,rand,rand
-`srand' srand
-`rand' - rand,rand,rand,rand
-`srand' srand
-`rand' - rand,rand,rand,rand
-
-`uname - ' uname
diff --git a/doc/examples/sysv-args.m4 b/doc/examples/sysv-args.m4
deleted file mode 100644
index 7c82beb0..00000000
--- a/doc/examples/sysv-args.m4
+++ /dev/null
@@ -1,14 +0,0 @@
-divert(-1)
-define(`nargs', `$#')
-define(`concat', `ifelse(1, $#, `$1', `$1` 'concat(shift($@))')')
-traceon(`concat', `nargs')
-divert
-
-nargs
-nargs()
-nargs(1,2,3,4,5,6)
-
-concat()
-concat(`hej', `med', `dig')
-concat(`hej', `med', `dig', `en gang igen')
-concat(an, awful, lot, of, argument, at, least, more, that, ten, silly, arguments)
diff --git a/doc/examples/time.m4 b/doc/examples/time.m4
deleted file mode 100644
index ae931049..00000000
--- a/doc/examples/time.m4
+++ /dev/null
@@ -1,21 +0,0 @@
-dnl Copyright (C) 2006, 2010, 2013-2014, 2017 Free Software Foundation,
-dnl Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it
-dnl with or without modifications, as long as this notice is preserved.
-load(`time')
-
-`currenttime' = currenttime
-`ctime' = ctime != ctime(eval(currenttime+60*60*24))
-gmtime = gmtime(currenttime)
-localtime = localtime(currenttime)
-define(`q', `$1,$2,$3,$4,$5,$6,$9')dnl
-
-currenttime
-eval(currenttime+60*60*24)
-localtime(eval(currenttime+60*60*24))
-q(localtime(eval(currenttime+60*60*24)))
-mktime = mktime(q(localtime(eval(currenttime+60*60*24))))
-
-%A %B %d, %Y = strftime(`%A %B %d, %Y', currenttime)
-%X on %x = strftime(`%X on %x', currenttime)
diff --git a/doc/examples/time2.m4 b/doc/examples/time2.m4
deleted file mode 100644
index 36840c4f..00000000
--- a/doc/examples/time2.m4
+++ /dev/null
@@ -1,19 +0,0 @@
-dnl Copyright (C) 2006, 2010, 2013-2014, 2017 Free Software Foundation,
-dnl Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it
-dnl with or without modifications, as long as this notice is preserved.
-`currenttime' = currenttime
-`ctime' = ctime != ctime(eval(currenttime+60*60*24))
-gmtime = gmtime(currenttime)
-localtime = localtime(currenttime)
-define(`q', `$1,$2,$3,$4,$5,$6,$9')dnl
-
-currenttime
-eval(currenttime+60*60*24)
-localtime(eval(currenttime+60*60*24))
-q(localtime(eval(currenttime+60*60*24)))
-mktime = mktime(q(localtime(eval(currenttime+60*60*24))))
-
-%A %B %d, %Y = strftime(`%A %B %d, %Y', currenttime)
-%X on %x = strftime(`%X on %x', currenttime)
diff --git a/doc/examples/trace.m4 b/doc/examples/trace.m4
deleted file mode 100644
index 92ce9816..00000000
--- a/doc/examples/trace.m4
+++ /dev/null
@@ -1,30 +0,0 @@
-divert(-1)
-
-# move(from, to)
-define(`move', `Move one disk from `$1' to `$2'.
-')
-
-# _hanoi (cnt, from, to, aux)
-define(`_hanoi', `ifelse(eval(`$1'<=1), 1, `move($2, $3)',
-`$0(decr($1), $2, $4, $3)move($2, $3)$0(decr($1), $4, $3, $2)')')
-
-# hanoi (cnt)
-define(`hanoi', `_$0(`$1', source, destination, auxilliary)')
-divert`'dnl
-
-# Debugmode t
-debugmode(`t')
-hanoi(2)
-
-# Debugmode taeq
-debugmode(`taeq')
-hanoi(2)
-
-# Debugmode OFF
-debugmode
-hanoi(2)
-
-# Debugmode ae
-debugmode(`ae')
-traceon(`move', `_hanoi')
-hanoi(2)
diff --git a/doc/examples/translit.m4 b/doc/examples/translit.m4
deleted file mode 100644
index 078d1726..00000000
--- a/doc/examples/translit.m4
+++ /dev/null
@@ -1,8 +0,0 @@
-# traceon(`translit')dnl
-translit(`GNUs not Unix', `a-z')
-translit(`GNUs not Unix', `a-z', `A-Z')
-translit(`GNUs not Unix', `A-Z', `a-z')
-translit(`GNUs not Unix', `A-Z')
-translit(`a-z', `a-')
-translit(`A-Z', `A-Z-', `-A-Z')
-translit(`GNUs not Unix', `Z-A', `a-z')
diff --git a/doc/examples/undivert.incl b/doc/examples/undivert.incl
deleted file mode 100644
index 408e0e20..00000000
--- a/doc/examples/undivert.incl
+++ /dev/null
@@ -1 +0,0 @@
-This is to be undiverted soon.
diff --git a/doc/examples/undivert.m4 b/doc/examples/undivert.m4
deleted file mode 100644
index 61dfb391..00000000
--- a/doc/examples/undivert.m4
+++ /dev/null
@@ -1,5 +0,0 @@
-define(`undiverted', `UNDIVERTED')
-# undiverted file.
-undivert(`undivert.incl')
-# included file.
-include(`undivert.incl')
diff --git a/doc/examples/wrap.m4 b/doc/examples/wrap.m4
deleted file mode 100644
index bbe7ae0b..00000000
--- a/doc/examples/wrap.m4
+++ /dev/null
@@ -1,10 +0,0 @@
-divert(-1)
-m4wrap(`Wrapper no. 1
-')
-
-m4wrap(`Wrapper no. 2
-m4wrap(`Wrapper no. 3
-m4wrap(`Wrapper no. 4
-')')')
-divert
-No. 33: The End.
diff --git a/doc/examples/wrapfifo.m4 b/doc/examples/wrapfifo.m4
deleted file mode 100644
index 95ff87a0..00000000
--- a/doc/examples/wrapfifo.m4
+++ /dev/null
@@ -1,10 +0,0 @@
-dnl Redefine m4wrap to have FIFO semantics.
-define(`_m4wrap_level', `0')dnl
-define(`m4wrap',
-`ifdef(`m4wrap'_m4wrap_level,
- `define(`m4wrap'_m4wrap_level,
- defn(`m4wrap'_m4wrap_level)`$1')',
- `builtin(`m4wrap', `define(`_m4wrap_level',
- incr(_m4wrap_level))dnl
-m4wrap'_m4wrap_level)dnl
-define(`m4wrap'_m4wrap_level, `$1')')')dnl
diff --git a/doc/examples/wraplifo.m4 b/doc/examples/wraplifo.m4
deleted file mode 100644
index bdbf3fb6..00000000
--- a/doc/examples/wraplifo.m4
+++ /dev/null
@@ -1,10 +0,0 @@
-dnl Redefine m4wrap to have LIFO semantics.
-define(`_m4wrap_level', `0')dnl
-define(`_m4wrap', defn(`m4wrap'))dnl
-define(`m4wrap',
-`ifdef(`m4wrap'_m4wrap_level,
- `define(`m4wrap'_m4wrap_level,
- `$1'defn(`m4wrap'_m4wrap_level))',
- `_m4wrap(`define(`_m4wrap_level', incr(_m4wrap_level))dnl
-m4wrap'_m4wrap_level)dnl
-define(`m4wrap'_m4wrap_level, `$1')')')dnl
diff --git a/doc/examples/wraplifo2.m4 b/doc/examples/wraplifo2.m4
deleted file mode 100644
index 5b450a76..00000000
--- a/doc/examples/wraplifo2.m4
+++ /dev/null
@@ -1,9 +0,0 @@
-dnl Redefine m4wrap to have LIFO semantics, improved example.
-include(`join.m4')dnl
-define(`_m4wrap', defn(`m4wrap'))dnl
-define(`_arg1', `$1')dnl
-define(`m4wrap',
-`ifdef(`_$0_text',
- `define(`_$0_text', joinall(` ', $@)defn(`_$0_text'))',
- `_$0(`_arg1(defn(`_$0_text')undefine(`_$0_text'))')dnl
-define(`_$0_text', joinall(` ', $@))')')dnl
diff --git a/doc/m4.texi b/doc/m4.texi
deleted file mode 100644
index 5108e20e..00000000
--- a/doc/m4.texi
+++ /dev/null
@@ -1,10411 +0,0 @@
-\input texinfo @c -*- texinfo -*-
-@comment ========================================================
-@comment %**start of header
-@setfilename m4.info
-@include version.texi
-@settitle GNU M4 @value{VERSION} macro processor
-@setchapternewpage odd
-@finalout
-
-@set beta
-
-@c @tabchar{}
-@c ----------
-@c The testsuite expects literal tab output in some examples, but
-@c literal tabs in texinfo leads to formatting issues.
-@macro tabchar
-@ @c
-@end macro
-
-@c @ovar{ARG}
-@c -------------------
-@c The ARG is an optional argument. To be used for macro arguments in
-@c their documentation (@defmac).
-@macro ovar{varname}
-@r{[}@var{\varname\}@r{]}@c
-@end macro
-
-@c @dvar{ARG, DEFAULT}
-@c -------------------
-@c The ARG is an optional argument, defaulting to DEFAULT. To be used
-@c for macro arguments in their documentation (@defmac).
-@macro dvar{varname, default}
-@r{[}@var{\varname\} = @samp{\default\}@r{]}@c
-@end macro
-
-@comment %**end of header
-@comment ========================================================
-
-@copying
-
-This manual (@value{UPDATED}) is for GNU M4 (version
-@value{VERSION}), a package containing an implementation of the m4 macro
-language.
-
-Copyright @copyright{} 1989-1994, 2004-2011, 2013-2014, 2017 Free
-Software Foundation, Inc.
-
-@quotation
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License,
-Version 1.3 or any later version published by the Free Software
-Foundation; with no Invariant Sections, no Front-Cover Texts, and no
-Back-Cover Texts. A copy of the license is included in the section
-entitled ``GNU Free Documentation License.''
-@end quotation
-@end copying
-
-@dircategory Text creation and manipulation
-@direntry
-* M4: (m4). A powerful macro processor.
-@end direntry
-
-@titlepage
-@title GNU M4, version @value{VERSION}
-@subtitle A powerful macro processor
-@subtitle Edition @value{EDITION}, @value{UPDATED}
-@author by Ren@'e Seindal, Fran@,{c}ois Pinard,
-@author Gary V. Vaughan, and Eric Blake
-@author (@email{bug-m4@@gnu.org})
-
-@page
-@vskip 0pt plus 1filll
-@insertcopying
-@end titlepage
-
-@contents
-
-@ifnottex
-@node Top
-@top GNU M4
-@insertcopying
-@end ifnottex
-
-GNU @code{m4} is an implementation of the traditional UNIX macro
-processor. It is mostly SVR4 compatible, although it has some
-extensions (for example, handling more than 9 positional parameters
-to macros). @code{m4} also has builtin functions for including
-files, running shell commands, doing arithmetic, etc. Autoconf needs
-GNU @code{m4} for generating @file{configure} scripts, but not for
-running them.
-
-GNU @code{m4} was originally written by Ren@'e Seindal, with
-subsequent changes by Fran@,{c}ois Pinard and other volunteers
-on the Internet. All names and email addresses can be found in the
-files @file{m4-@value{VERSION}/@/AUTHORS} and
-@file{m4-@value{VERSION}/@/THANKS} from the GNU M4
-distribution.
-
-@ifclear beta
-This is release @value{VERSION}. It is now considered stable: future
-releases on this branch are only meant to fix bugs, increase speed, or
-improve documentation.
-@end ifclear
-
-@ifset beta
-This is BETA release @value{VERSION}. This is a development release,
-and as such, is prone to bugs, crashes, unforeseen features, incomplete
-documentation@dots{}, therefore, use at your own peril. In case of
-problems, please do not hesitate to report them (see the
-@file{m4-@value{VERSION}/@/README} file in the distribution).
-@xref{Experiments}.
-@end ifset
-
-@menu
-* Preliminaries:: Introduction and preliminaries
-* Invoking m4:: Invoking @code{m4}
-* Syntax:: Lexical and syntactic conventions
-
-* Macros:: How to invoke macros
-* Definitions:: How to define new macros
-* Conditionals:: Conditionals, loops, and recursion
-
-* Debugging:: How to debug macros and input
-
-* Input Control:: Input control
-* File Inclusion:: File inclusion
-* Diversions:: Diverting and undiverting output
-
-* Modules:: Extending M4 with dynamic runtime modules
-
-* Text handling:: Macros for text handling
-* Arithmetic:: Macros for doing arithmetic
-* Shell commands:: Macros for running shell commands
-* Miscellaneous:: Miscellaneous builtin macros
-* Frozen files:: Fast loading of frozen state
-
-* Compatibility:: Compatibility with other versions of @code{m4}
-* Answers:: Correct version of some examples
-
-* Copying This Package:: How to make copies of the overall M4 package
-* Copying This Manual:: How to make copies of this manual
-* Indices:: Indices of concepts and macros
-
-@detailmenu
- --- The Detailed Node Listing ---
-
-Introduction and preliminaries
-
-* Intro:: Introduction to @code{m4}
-* History:: Historical references
-* Bugs:: Problems and bugs
-* Manual:: Using this manual
-
-Invoking @code{m4}
-
-* Operation modes:: Command line options for operation modes
-* Preprocessor features:: Command line options for preprocessor features
-* Limits control:: Command line options for limits control
-* Frozen state:: Command line options for frozen state
-* Debugging options:: Command line options for debugging
-* Command line files:: Specifying input files on the command line
-
-Lexical and syntactic conventions
-
-* Names:: Macro names
-* Quoted strings:: Quoting input to @code{m4}
-* Comments:: Comments in @code{m4} input
-* Other tokens:: Other kinds of input tokens
-* Input processing:: How @code{m4} copies input to output
-* Regular expression syntax:: How @code{m4} interprets regular expressions
-
-How to invoke macros
-
-* Invocation:: Macro invocation
-* Inhibiting Invocation:: Preventing macro invocation
-* Macro Arguments:: Macro arguments
-* Quoting Arguments:: On Quoting Arguments to macros
-* Macro expansion:: Expanding macros
-
-How to define new macros
-
-* Define:: Defining a new macro
-* Arguments:: Arguments to macros
-* Pseudo Arguments:: Special arguments to macros
-* Undefine:: Deleting a macro
-* Defn:: Renaming macros
-* Pushdef:: Temporarily redefining macros
-* Renamesyms:: Renaming macros with regular expressions
-
-* Indir:: Indirect call of macros
-* Builtin:: Indirect call of builtins
-* M4symbols:: Getting the defined macro names
-
-Conditionals, loops, and recursion
-
-* Ifdef:: Testing if a macro is defined
-* Ifelse:: If-else construct, or multibranch
-* Shift:: Recursion in @code{m4}
-* Forloop:: Iteration by counting
-* Foreach:: Iteration by list contents
-* Stacks:: Working with definition stacks
-* Composition:: Building macros with macros
-
-How to debug macros and input
-
-* Dumpdef:: Displaying macro definitions
-* Trace:: Tracing macro calls
-* Debugmode:: Controlling debugging options
-* Debuglen:: Limiting debug output
-* Debugfile:: Saving debugging output
-
-Input control
-
-* Dnl:: Deleting whitespace in input
-* Changequote:: Changing the quote characters
-* Changecom:: Changing the comment delimiters
-* Changeresyntax:: Changing the regular expression syntax
-* Changesyntax:: Changing the lexical structure of the input
-* M4wrap:: Saving text until end of input
-
-File inclusion
-
-* Include:: Including named files
-* Search Path:: Searching for include files
-
-Diverting and undiverting output
-
-* Divert:: Diverting output
-* Undivert:: Undiverting output
-* Divnum:: Diversion numbers
-* Cleardivert:: Discarding diverted text
-
-Extending M4 with dynamic runtime modules
-
-* M4modules:: Listing loaded modules
-* Standard Modules:: Standard bundled modules
-
-Macros for text handling
-
-* Len:: Calculating length of strings
-* Index macro:: Searching for substrings
-* Regexp:: Searching for regular expressions
-* Substr:: Extracting substrings
-* Translit:: Translating characters
-* Patsubst:: Substituting text by regular expression
-* Format:: Formatting strings (printf-like)
-
-Macros for doing arithmetic
-
-* Incr:: Decrement and increment operators
-* Eval:: Evaluating integer expressions
-* Mpeval:: Multiple precision arithmetic
-
-Macros for running shell commands
-
-* Platform macros:: Determining the platform
-* Syscmd:: Executing simple commands
-* Esyscmd:: Reading the output of commands
-* Sysval:: Exit status
-* Mkstemp:: Making temporary files
-* Mkdtemp:: Making temporary directories
-
-Miscellaneous builtin macros
-
-* Errprint:: Printing error messages
-* Location:: Printing current location
-* M4exit:: Exiting from @code{m4}
-* Syncoutput:: Turning on and off sync lines
-
-Fast loading of frozen state
-
-* Using frozen files:: Using frozen files
-* Frozen file format 1:: Frozen file format 1
-* Frozen file format 2:: Frozen file format 2
-
-Compatibility with other versions of @code{m4}
-
-* Extensions:: Extensions in GNU M4
-* Incompatibilities:: Other incompatibilities
-* Experiments:: Experimental features in GNU M4
-
-Correct version of some examples
-
-* Improved exch:: Solution for @code{exch}
-* Improved forloop:: Solution for @code{forloop}
-* Improved foreach:: Solution for @code{foreach}
-* Improved copy:: Solution for @code{copy}
-* Improved m4wrap:: Solution for @code{m4wrap}
-* Improved cleardivert:: Solution for @code{cleardivert}
-* Improved capitalize:: Solution for @code{capitalize}
-* Improved fatal_error:: Solution for @code{fatal_error}
-
-How to make copies of the overall M4 package
-
-* GNU General Public License:: License for copying the M4 package
-
-How to make copies of this manual
-
-* GNU Free Documentation License:: License for copying this manual
-
-Indices of concepts and macros
-
-* Macro index:: Index for all @code{m4} macros
-* Concept index:: Index for many concepts
-
-@end detailmenu
-@end menu
-
-@node Preliminaries
-@chapter Introduction and preliminaries
-
-This first chapter explains what GNU @code{m4} is, where @code{m4}
-comes from, how to read and use this documentation, how to call the
-@code{m4} program, and how to report bugs about it. It concludes by
-giving tips for reading the remainder of the manual.
-
-The following chapters then detail all the features of the @code{m4}
-language, as shipped in the GNU M4 package.
-
-@menu
-* Intro:: Introduction to @code{m4}
-* History:: Historical references
-* Bugs:: Problems and bugs
-* Manual:: Using this manual
-@end menu
-
-@node Intro
-@section Introduction to @code{m4}
-
-@cindex overview of @code{m4}
-@code{m4} is a macro processor, in the sense that it copies its
-input to the output, expanding macros as it goes. Macros are either
-builtin or user-defined, and can take any number of arguments.
-Besides just doing macro expansion, @code{m4} has builtin functions
-for including named files, running shell commands, doing integer
-arithmetic, manipulating text in various ways, performing recursion,
-etc.@dots{} @code{m4} can be used either as a front-end to a compiler,
-or as a macro processor in its own right.
-
-The @code{m4} macro processor is widely available on all UNIXes, and has
-been standardized by POSIX.
-Usually, only a small percentage of users are aware of its existence.
-However, those who find it often become committed users. The
-popularity of GNU Autoconf, which requires GNU
-@code{m4} for @emph{generating} @file{configure} scripts, is an incentive
-for many to install it, while these people will not themselves
-program in @code{m4}. GNU @code{m4} is mostly compatible with the
-System V, Release 4 version, except for some minor differences.
-@xref{Compatibility}, for more details.
-
-Some people find @code{m4} to be fairly addictive. They first use
-@code{m4} for simple problems, then take bigger and bigger challenges,
-learning how to write complex sets of @code{m4} macros along the way.
-Once really addicted, users pursue writing of sophisticated @code{m4}
-applications even to solve simple problems, devoting more time
-debugging their @code{m4} scripts than doing real work. Beware that
-@code{m4} may be dangerous for the health of compulsive programmers.
-
-@node History
-@section Historical references
-
-@cindex history of @code{m4}
-@cindex GNU M4, history of
-Macro languages were invented early in the history of computing. In the
-1950s Alan Perlis suggested that the macro language be independent of the
-language being processed. Techniques such as conditional and recursive
-macros, and using macros to define other macros, were described by Doug
-McIlroy of Bell Labs in ``Macro Instruction Extensions of Compiler
-Languages'', @emph{Communications of the ACM} 3, 4 (1960), 214--20,
-@url{http://dx.doi.org/10.1145/367177.367223}.
-
-An important precursor of @code{m4} was GPM; see C. Strachey,
-@c The title uses lower case and has no space between "macro" and "generator".
-``A general purpose macrogenerator'', @emph{Computer Journal} 8, 3
-(1965), 225--41, @url{http://dx.doi.org/10.1093/comjnl/8.3.225}. GPM is
-also succinctly described in David Gries's book @emph{Compiler
-Construction for Digital Computers}, Wiley (1971). Strachey was a
-brilliant programmer: GPM fit into 250 machine instructions!
-
-Inspired by GPM while visiting Strachey's Lab in 1968, McIlroy wrote a
-model preprocessor in that fit into a page of Snobol 3 code, and McIlroy
-and Robert Morris developed a series of further models at Bell Labs.
-Andrew D. Hall followed up with M6, a general purpose macro processor
-used to port the Fortran source code of the Altran computer algebra
-system; see Hall's ``The M6 Macro Processor'', Computing Science
-Technical Report #2, Bell Labs (1972),
-@url{http://cm.bell-labs.com/cm/cs/cstr/2.pdf}. M6's source code
-consisted of about 600 Fortran statements. Its name was the first of
-the @code{m4} line.
-
-The Brian Kernighan and P.J. Plauger book @emph{Software Tools},
-Addison-Wesley (1976), describes and implements a Unix
-macro-processor language, which inspired Dennis Ritchie to write
-@code{m3}, a macro processor for the AP-3 minicomputer.
-
-Kernighan and Ritchie then joined forces to develop the original
-@code{m4}, described in ``The M4 Macro Processor'', Bell Laboratories
-(1977), @url{http://wolfram.schneider.org/bsd/7thEdManVol2/m4/m4.pdf}.
-It had only 21 builtin macros.
-
-While @code{GPM} was more @emph{pure}, @code{m4} is meant to deal with
-the true intricacies of real life: macros can be recognized without
-being pre-announced, skipping whitespace or end-of-lines is easier,
-more constructs are builtin instead of derived, etc.
-
-Originally, the Kernighan and Plauger macro-processor, and then
-@code{m3}, formed the engine for the Rational FORTRAN preprocessor,
-that is, the @code{Ratfor} equivalent of @code{cpp}. Later, @code{m4}
-was used as a front-end for @code{Ratfor}, @code{C} and @code{Cobol}.
-
-Ren@'e Seindal released his implementation of @code{m4}, GNU
-@code{m4},
-in 1990, with the aim of removing the artificial limitations in many
-of the traditional @code{m4} implementations, such as maximum line
-length, macro size, or number of macros.
-
-The late Professor A. Dain Samples described and implemented a further
-evolution in the form of @code{M5}: ``User's Guide to the M5 Macro
-Language: 2nd edition'', Electronic Announcement on comp.compilers
-newsgroup (1992).
-
-Fran@,{c}ois Pinard took over maintenance of GNU @code{m4} in
-1992, until 1994 when he released GNU @code{m4} 1.4, which was
-the stable release for 10 years. It was at this time that GNU
-Autoconf decided to require GNU @code{m4} as its underlying
-engine, since all other implementations of @code{m4} had too many
-limitations.
-
-More recently, in 2004, Paul Eggert released 1.4.1 and 1.4.2 which
-addressed some long standing bugs in the venerable 1.4 release. Then in
-2005, Gary V. Vaughan collected together the many patches to
-GNU @code{m4} 1.4 that were floating around the net and
-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. Eric continued with some portability fixes for 1.4.11 and
-1.4.12 in 2008, 1.4.13 in 2009, 1.4.14 and 1.4.15 in 2010, and 1.4.16
-in 2011. Following a long hiatus, Gary released 1.4.17 after upgrading
-to the latest autotools (and gnulib) along with all the small fixes they
-had accumulated.
-
-Additionally, in 2008, Eric rewrote the scanning engine to reduce
-recursive evaluation from quadratic to linear complexity. This was
-released as M4 1.6 in 2009. The 1.x branch series remains open for bug
-fixes.
-
-Meanwhile, development was underway for new features for @code{m4},
-such as dynamic module loading and additional builtins, practically
-rewriting the entire code base. This development has spurred
-improvements to other GNU software, such as GNU
-Libtool. GNU M4 2.0 is the result of this effort.
-
-@node Bugs
-@section Problems and bugs
-
-@cindex reporting bugs
-@cindex bug reports
-@cindex suggestions, reporting
-If you have problems with GNU M4 or think you've found a bug,
-please report it. Before reporting a bug, make sure you've actually
-found a real bug. Carefully reread the documentation and see if it
-really says you can do what you're trying to do. If it's not clear
-whether you should be able to do something or not, report that too; it's
-a bug in the documentation!
-
-Before reporting a bug or trying to fix it yourself, try to isolate it
-to the smallest possible input file that reproduces the problem. Then
-send us the input file and the exact results @code{m4} gave you. Also
-say what you expected to occur; this will help us decide whether the
-problem was really in the documentation.
-
-Once you've got a precise problem, send e-mail to
-@email{bug-m4@@gnu.org}. Please include the version number of @code{m4}
-you are using. You can get this information with the command
-@kbd{m4 --version}. You can also run @kbd{make check} to generate the
-file @file{tests/@/testsuite.log}, useful for including in your report.
-
-Non-bug suggestions are always welcome as well. If you have questions
-about things that are unclear in the documentation or are just obscure
-features, please report them too.
-
-@node Manual
-@section Using this manual
-
-@cindex examples, understanding
-This manual contains a number of examples of @code{m4} input and output,
-and a simple notation is used to distinguish input, output and error
-messages from @code{m4}. Examples are set out from the normal text, and
-shown in a fixed width font, like this
-
-@comment ignore
-@example
-This is an example of an example!
-@end example
-
-To distinguish input from output, all output from @code{m4} is prefixed
-by the string @samp{@result{}}, and all error messages by the string
-@samp{@error{}}. When showing how command line options affect matters,
-the command line is shown with a prompt @samp{$ @kbd{like this}},
-otherwise, you can assume that a simple @kbd{m4} invocation will work.
-Thus:
-
-@comment ignore
-@example
-$ @kbd{command line to invoke m4}
-Example of input line
-@result{}Output line from m4
-@error{}and an error message
-@end example
-
-The sequence @samp{^D} in an example indicates the end of the input
-file. The sequence @samp{@key{NL}} refers to the newline character.
-The majority of these examples are self-contained, and you can run them
-with similar results. In fact, the testsuite that is bundled in the
-GNU M4 package consists in part of the examples
-in this document! Some of the examples assume that your current
-directory is located where you unpacked the installation, so if you plan
-on following along, you may find it helpful to do this now:
-
-@comment ignore
-@example
-$ @kbd{cd m4-@value{VERSION}}
-@end example
-
-As each of the predefined macros in @code{m4} is described, a prototype
-call of the macro will be shown, giving descriptive names to the
-arguments, e.g.,
-
-@deffn {Composite (none)} example (@var{string}, @dvar{count, 1}, @
- @ovar{argument}@dots{})
-This is a sample prototype. There is not really a macro named
-@code{example}, but this documents that if there were, it would be a
-Composite macro, rather than a Builtin, and would be provided by the
-module @code{none}.
-
-It requires at least one argument, @var{string}. Remember that in
-@code{m4}, there must not be a space between the macro name and the
-opening parenthesis, unless it was intended to call the macro without
-any arguments. The brackets around @var{count} and @var{argument} show
-that these arguments are optional. If @var{count} is omitted, the macro
-behaves as if count were @samp{1}, whereas if @var{argument} is omitted,
-the macro behaves as if it were the empty string. A blank argument is
-not the same as an omitted argument. For example, @samp{example(`a')},
-@samp{example(`a',`1')}, and @samp{example(`a',`1',)} would behave
-identically with @var{count} set to @samp{1}; while @samp{example(`a',)}
-and @samp{example(`a',`')} would explicitly pass the empty string for
-@var{count}. The ellipses (@samp{@dots{}}) show that the macro
-processes additional arguments after @var{argument}, rather than
-ignoring them.
-@end deffn
-
-Each builtin definition will list, in parentheses, the module that must
-be loaded to use that macro. The standard modules include
-@samp{m4} (which is always available), @samp{gnu} (for GNU specific
-m4 extensions), and @samp{traditional} (for compatibility with System V
-m4). @xref{Modules}.
-
-@cindex numbers
-All macro arguments in @code{m4} are strings, but some are given
-special interpretation, e.g., as numbers, file names, regular
-expressions, etc. The documentation for each macro will state how the
-parameters are interpreted, and what happens if the argument cannot be
-parsed according to the desired interpretation. Unless specified
-otherwise, a parameter specified to be a number is parsed as a decimal,
-even if the argument has leading zeros; and parsing the empty string as
-a number results in 0 rather than an error, although a warning will be
-issued.
-
-This document consistently writes and uses @dfn{builtin}, without a
-hyphen, as if it were an English word. This is how the @code{builtin}
-primitive is spelled within @code{m4}.
-
-@node Invoking m4
-@chapter Invoking @code{m4}
-
-@cindex command line
-@cindex invoking @code{m4}
-The format of the @code{m4} command is:
-
-@comment ignore
-@example
-@code{m4} @r{[}@var{option}@dots{}@r{]} @r{[}@var{file}@dots{}@r{]}
-@end example
-
-@cindex command line, options
-@cindex options, command line
-@cindex @env{POSIXLY_CORRECT}
-All options begin with @samp{-}, or if long option names are used, with
-@samp{--}. A long option name need not be written completely, any
-unambiguous prefix is sufficient. POSIX requires @code{m4} to
-recognize arguments intermixed with files, even when
-@env{POSIXLY_CORRECT} is set in the environment. Most options take
-effect at startup regardless of their position, but some are documented
-below as taking effect after any files that occurred earlier in the
-command line. The argument @option{--} is a marker to denote the end of
-options.
-
-With short options, options that do not take arguments may be combined
-into a single command line argument with subsequent options, options
-with mandatory arguments may be provided either as a single command line
-argument or as two arguments, and options with optional arguments must
-be provided as a single argument. In other words,
-@kbd{m4 -QPDfoo -d a -d+f} is equivalent to
-@kbd{m4 -Q -P -D foo -d ./a -d+f}, although the latter form is
-considered canonical.
-
-With long options, options with mandatory arguments may be provided with
-an equal sign (@samp{=}) in a single argument, or as two arguments, and
-options with optional arguments must be provided as a single argument.
-In other words, @kbd{m4 --def foo --debug a} is equivalent to
-@kbd{m4 --define=foo --debug= -- ./a}, although the latter form is
-considered canonical (not to mention more robust, in case a future
-version of @code{m4} introduces an option named @option{--default}).
-
-@code{m4} understands the following options, grouped by functionality.
-
-@menu
-* Operation modes:: Command line options for operation modes
-* Preprocessor features:: Command line options for preprocessor features
-* Limits control:: Command line options for limits control
-* Frozen state:: Command line options for frozen state
-* Debugging options:: Command line options for debugging
-* Command line files:: Specifying input files on the command line
-@end menu
-
-@node Operation modes
-@section Command line options for operation modes
-
-Several options control the overall operation of @code{m4}:
-
-@table @code
-@item --help
-Print a help summary on standard output, then immediately exit
-@code{m4} without reading any input files or performing any other
-actions.
-
-@item --version
-Print the version number of the program on standard output, then
-immediately exit @code{m4} without reading any input files or
-performing any other actions.
-
-@item -b
-@itemx --batch
-Makes this invocation of @code{m4} non-interactive. This means that
-output will be buffered, and an interrupt or pipe write error will halt
-execution. If neither
-@option{-b} nor @option{-i} are specified, this is activated by default
-when any input files are specified, or when either standard input or
-standard error is not a terminal. Note that this means that @kbd{m4}
-alone might be interactive, but @kbd{m4 -} is not, even though both
-commands process only standard input. If both @option{-b} and
-@option{-i} are specified, only the last one takes effect.
-
-@item -c
-@itemx --discard-comments
-Discard all comments instead of copying them to the output.
-
-@item -E
-@itemx --fatal-warnings
-@cindex errors, fatal
-@cindex fatal errors
-Controls the effect of warnings. If unspecified, then execution
-continues and exit status is unaffected when a warning is printed. If
-specified exactly once, warnings become fatal; when one is issued,
-execution continues, but the exit status will be non-zero. If specified
-multiple times, then execution halts with non-zero status the first time
-a warning is issued. The introduction of behavior levels is new to M4
-1.4.9; for behavior consistent with earlier versions, you should specify
-@option{-E} twice.
-
-
-For backwards compatibility reasons, using @option{-E} behaves as if an
-implicit @option{--debug=-d} option is also present. This is so that
-scripts written for older M4 versions will not fail if they used
-constructs that were previously silently allowed, but would now trigger
-a warning.
-
-@example
-$ @kbd{m4}
-defn(`oops')
-@error{}m4:stdin:1: warning: defn: undefined macro 'oops'
-@result{}
-^D
-@end example
-
-@comment ignore
-@example
-$ @kbd{echo $?}
-@result{}0
-@end example
-
-@comment options: -E
-@example
-$ @kbd{m4 -E}
-defn(`oops')
-@result{}
-^D
-@end example
-
-@comment ignore
-@example
-$ @kbd{echo $?}
-@result{}0
-@end example
-
-@comment options: -E -d
-@comment status: 1
-@example
-$ @kbd{m4 -E -d}
-defn(`oops')
-@error{}m4:stdin:1: warning: defn: undefined macro 'oops'
-@result{}
-^D
-@end example
-
-@comment ignore
-@example
-$ @kbd{echo $?}
-@result{}1
-@end example
-
-@item -i
-@itemx --interactive
-@itemx -e
-Makes this invocation of @code{m4} interactive. This means that all
-output will be unbuffered, interrupts will be ignored, and behavior on
-pipe write errors is inherited from the parent process. If neither
-@option{-b} nor @option{-i} are specified, this is activated by default
-when no input files are specified, and when both standard input and
-standard error are terminals (similar to the way that /bin/sh determines
-when to be interactive). If both @option{-b} and @option{-i} are
-specified, only the last one takes effect. The spelling @option{-e}
-exists for compatibility with other @code{m4} implementations, and
-issues a warning because it may be withdrawn in a future version of
-GNU M4.
-
-@item -P
-@itemx --prefix-builtins
-Internally modify @emph{all} builtin macro names so they all start with
-the prefix @samp{m4_}. For example, using this option, one should write
-@samp{m4_define} instead of @samp{define}, and @samp{@w{m4___file__}}
-instead of @samp{@w{__file__}}. This option has no effect if @option{-R}
-is also specified.
-
-@item -Q
-@itemx --quiet
-@itemx --silent
-Suppress warnings, such as missing or superfluous arguments in macro
-calls, or treating the empty string as zero. Error messages are still
-printed. The distinction between error and warning is fuzzy, and if
-you encounter a situation where the message output did not match your
-expectations, please report that as a bug. This option is implied if
-@env{POSIXLY_CORRECT} is set in the environment.
-
-@item -r@r{[}@var{resyntax-spec}@r{]}
-@itemx --regexp-syntax@r{[}=@var{resyntax-spec}@r{]}
-Set the regular expression syntax according to @var{resyntax-spec}.
-When this option is not given, or @var{resyntax-spec} is omitted,
-GNU M4 uses the flavor @code{GNU_M4}, which provides
-emacs-compatible regular expressions. @xref{Changeresyntax}, for more
-details on the format and meaning of @var{resyntax-spec}. This option
-may be given more than once, and order with respect to file names is
-significant.
-
-@item --safer
-Cripple the following builtins, since each can perform potentially
-unsafe actions: @code{maketemp}, @code{mkstemp} (@pxref{Mkstemp}),
-@code{mkdtemp} (@pxref{Mkdtemp}), @code{debugfile} (@pxref{Debugfile}),
-@code{syscmd} (@pxref{Syscmd}), and @code{esyscmd} (@pxref{Esyscmd}).
-An attempt to use any of these macros will result in an error. This
-option is intended to make it safer to preprocess an input file of
-unknown origin.
-
-@item -W
-@itemx --warnings
-Enable warnings. Warnings are on by default unless
-@env{POSIXLY_CORRECT} was set in the environment; this option exists to
-allow overriding @option{--silent}.
-@comment FIXME should we accept -Wall, -Wnone, -Wcategory,
-@comment -Wno-category...?
-@end table
-
-@node Preprocessor features
-@section Command line options for preprocessor features
-
-@cindex macro definitions, on the command line
-@cindex command line, macro definitions on the
-@cindex preprocessor features
-Several options allow @code{m4} to behave more like a preprocessor.
-Macro definitions and deletions can be made on the command line, the
-search path can be altered, and the output file can track where the
-input came from. These features occur with the following options:
-
-@table @code
-@item -B @var{directory}
-@itemx --prepend-include=@var{directory}
-Make @code{m4} search @var{directory} for included files, prior to
-searching the current working directory. @xref{Search Path}, for more
-details. This option may be given more than once. Some other
-implementations of @code{m4} use @option{-B @var{number}} to change their
-hard-coded limits, but that is unnecessary in GNU where the
-only limit is your hardware capability. So although it is unlikely that
-you will want to include a relative directory whose name is purely
-numeric, GNU @code{m4} will warn you about this potential
-compatibility issue; you can avoid the warning by using the long
-spelling, or by using @samp{./@var{number}} if you really meant it.
-
-@item -D @var{name}@r{[}=@var{value}@r{]}
-@itemx --define=@var{name}@r{[}=@var{value}@r{]}
-This enters @var{name} into the symbol table. If @samp{=@var{value}} is
-missing, the value is taken to be the empty string. The @var{value} can
-be any string, and the macro can be defined to take arguments, just as
-if it was defined from within the input. This option may be given more
-than once; order with respect to file names is significant, and
-redefining the same @var{name} loses the previous value.
-
-@item --import-environment
-Imports every variable in the environment as a macro. This is done
-before @option{-D} and @option{-U}, so they can override the
-environment.
-
-@item -I @var{directory}
-@itemx --include=@var{directory}
-Make @code{m4} search @var{directory} for included files that are not
-found in the current working directory. @xref{Search Path}, for more
-details. This option may be given more than once.
-
-@item --popdef=@var{name}
-This deletes the top-most meaning @var{name} might have. Obviously,
-only predefined macros can be deleted in this way. This option may be
-given more than once; popping a @var{name} that does not have a
-definition is silently ignored. Order is significant with respect to
-file names.
-
-@item -p @var{name}@r{[}=@var{value}@r{]}
-@itemx --pushdef=@var{name}@r{[}=@var{value}@r{]}
-This enters @var{name} into the symbol table. If @samp{=@var{value}} is
-missing, the value is taken to be the empty string. The @var{value} can
-be any string, and the macro can be defined to take arguments, just as
-if it was defined from within the input. This option may be given more
-than once; order with respect to file names is significant, and
-redefining the same @var{name} adds another definition to its stack.
-
-@item -s
-@itemx --synclines
-Short for @option{--syncoutput=1}, turning on synchronization lines
-(sometimes called @dfn{synclines}).
-
-@item --syncoutput@r{[}=@var{state}@r{]}
-@cindex synchronization lines
-@cindex location, input
-@cindex input location
-Control the generation of synchronization lines from the command line.
-Synchronization lines are for use by the C preprocessor or other
-similar tools. Order is significant with respect to file names. This
-option is useful, for example, when @code{m4} is used as a
-front end to a compiler. Source file name and line number information
-is conveyed by directives of the form @samp{#line @var{linenum}
-"@var{file}"}, which are inserted as needed into the middle of the
-output. Such directives mean that the following line originated or was
-expanded from the contents of input file @var{file} at line
-@var{linenum}. The @samp{"@var{file}"} part is often omitted when
-the file name did not change from the previous directive.
-
-Synchronization directives are always given on complete lines by
-themselves. When a synchronization discrepancy occurs in the middle of
-an output line, the associated synchronization directive is delayed
-until the next newline that does not occur in the middle of a quoted
-string or comment. @xref{Syncoutput}, for runtime control. @var{state}
-is interpreted the same as the argument to @code{syncoutput}; if
-@var{state} is omitted, or @option{--syncoutput} is not used,
-synchronization lines are disabled.
-
-@item -U @var{name}
-@itemx --undefine=@var{name}
-This deletes any predefined meaning @var{name} might have. Obviously,
-only predefined macros can be deleted in this way. This option may be
-given more than once; undefining a @var{name} that does not have a
-definition is silently ignored. Order is significant with respect to
-file names.
-@end table
-
-@node Limits control
-@section Command line options for limits control
-
-There are some limits within @code{m4} that can be tuned. For
-compatibility, @code{m4} also accepts some options that control limits
-in other implementations, but which are automatically unbounded (limited
-only by your hardware and operating system constraints) in GNU
-@code{m4}.
-
-@table @code
-@item -g
-@itemx --gnu
-Enable all the extensions in this implementation. This is on by
-default unless @env{POSIXLY_CORRECT} is set in the environment; it
-exists to allow overriding @option{--traditional}.
-
-@item -G
-@itemx --posix
-@itemx --traditional
-Suppress all the extensions made in this implementation, compared to the
-System V version. @xref{Compatibility}, for a list of these. This
-loads the @samp{traditional} module in place of the @samp{gnu} module.
-It is implied if @env{POSIXLY_CORRECT} is set in the environment.
-
-@item -L @var{num}
-@itemx --nesting-limit=@var{num}
-@cindex nesting limit
-@cindex limit, nesting
-Artificially limit the nesting of macro calls to @var{num} levels,
-stopping program execution if this limit is ever exceeded. When not
-specified, nesting is limited to 1024 levels. A value of zero means
-unlimited; but then heavily nested code could potentially cause a stack
-overflow. @var{num} can have an optional scaling suffix.
-@comment FIXME - need a node on what scaling suffixes are supported (see
-@comment [info coreutils 'block size'] for ideas), and need to consider
-@comment whether builtins should also understand scaling suffixes:
-@comment eval, mpeval, perhaps format
-
-The precise effect of this option might be more correctly associated
-with textual nesting than dynamic recursion. It has been useful
-when some complex @code{m4} input was generated by mechanical means.
-Most users would never need this option. If shown to be obtrusive,
-this option (which is still experimental) might well disappear.
-
-@cindex rescanning
-This option does @emph{not} have the ability to break endless
-rescanning loops, since these do not necessarily consume much memory
-or stack space. Through clever usage of rescanning loops, one can
-request complex, time-consuming computations from @code{m4} with useful
-results. Putting limitations in this area would break @code{m4} power.
-There are many pathological cases: @w{@samp{define(`a', `a')a}} is
-only the simplest example (but @pxref{Compatibility}). Expecting GNU
-@code{m4} to detect these would be a little like expecting a compiler
-system to detect and diagnose endless loops: it is a quite @emph{hard}
-problem in general, if not undecidable!
-
-@item -H @var{num}
-@itemx --hashsize=@var{num}
-@itemx --word-regexp=@var{regexp}
-These options are present only for compatibility with previous versions
-of GNU @code{m4}. They do nothing except issue a warning, because the
-symbol table size is not fixed anymore, and because the new
-@code{changesyntax} feature is more efficient than the withdrawn
-experimental @code{changeword}. These options will eventually disappear
-in future releases.
-
-@item -S @var{num}
-@itemx -T @var{num}
-These options are present for compatibility with System V @code{m4}, but
-do nothing in this implementation. They may disappear in future
-releases, and issue a warning to that effect.
-@end table
-
-@node Frozen state
-@section Command line options for frozen state
-
-GNU @code{m4} comes with a feature of freezing internal state
-(@pxref{Frozen files}). This can be used to speed up @code{m4}
-execution when reusing a common initialization script.
-
-@table @code
-@item -F @var{file}
-@itemx --freeze-state=@var{file}
-Once execution is finished, write out the frozen state on the specified
-@var{file}. It is conventional, but not required, for @var{file} to end
-in @samp{.m4f}.
-
-@item -R @var{file}
-@itemx --reload-state=@var{file}
-Before execution starts, recover the internal state from the specified
-frozen @var{file}. The options @option{-D}, @option{-U}, @option{-t},
-@option{-m}, @option{-r}, and @option{--import-environment} take effect
-after state is reloaded, but before the input files are read.
-@end table
-
-@node Debugging options
-@section Command line options for debugging
-
-Finally, there are several options for aiding in debugging @code{m4}
-scripts.
-
-@table @code
-@item -d@r{[}@r{[}-@r{|}+@r{]}@var{flags}@r{]}
-@itemx --debug@r{[}=@r{[}-@r{|}+@r{]}@var{flags}@r{]}
-@itemx --debugmode@r{[}=@r{[}-@r{|}+@r{]}@var{flags}@r{]}
-Set the debug-level according to the flags @var{flags}. The debug-level
-controls the format and amount of information presented by the debugging
-functions. @xref{Debugmode}, for more details on the format and
-meaning of @var{flags}. If omitted, @var{flags} defaults to
-@samp{+adeq}. If the option occurs multiple times, @var{flags} starting
-with @samp{-} or @samp{+} are cumulative, while @var{flags} starting
-with a letter override all earlier settings. The debug-level starts
-with @samp{d} enabled and all other flags disabled. To disable all
-previously set flags, specify an explicit @var{flags} of @samp{-V}. For
-backward compatibility reasons, the option @option{--fatal-warnings}
-implies @samp{--debug=-d} as part of its effects. The spelling
-@option{--debug} is recognized as an unambiguous option for
-compatibility with earlier versions of GNU M4, but for
-consistency with the builtin name, you can also use the spelling
-@option{--debugmode}. Order is significant with respect to file names.
-
-The cumulative effect of the various options in this example is
-equivalent to a single invocation of @code{debugmode(`adlqx')}:
-
-@comment options: -d-V -d+lx --debug --debugmode=-e
-@example
-$ @kbd{m4 -d+lx --debug --debugmode=-e}
-traceon(`len')
-@result{}
-len(`123')
-@error{}m4trace:2: -1- id 2: len(`123')
-@result{}3
-@end example
-
-@item --debugfile@r{[}=@var{file}@r{]}
-@itemx -o @var{file}
-@itemx --error-output=@var{file}
-Redirect debug messages and trace output to the
-named @var{file}. Warnings, error messages, and @code{errprint} output
-are still printed to standard error. Output from @code{dumpdef} goes to
-this file when the debug level @code{o} is not set (@pxref{Debugmode}).
-If these options are not used, or
-if @var{file} is unspecified (only possible for @option{--debugfile}),
-debug output goes to standard error; if @var{file} is the empty string,
-debug output is discarded. @xref{Debugfile}, for more details. The
-option @option{--debugfile} may be given more than once, and order is
-significant with respect to file names. The spellings @option{-o} and
-@option{--error-output} are misleading and
-inconsistent with other GNU tools; using those spellings will
-evoke a warning, and they may be withdrawn or change semantics in a
-future release.
-
-@item -l @var{num}
-@itemx --debuglen=@var{num}
-@itemx --arglength=@var{num}
-Restrict the size of the output generated by macro tracing or by
-@code{dumpdef} to @var{num} characters per string. If unspecified or
-zero, output is unlimited. @xref{Debuglen}, for more details.
-@var{num} can have an optional scaling suffix. The spelling
-@option{--arglength} is deprecated, since it does not match the
-@code{debuglen} macro; using it will evoke a warning, and it may be
-withdrawn in a future release.
-@comment FIXME - Should we add an option that controls whether output
-@comment strings are sanitized with escape sequences, so that dumpdef is
-@comment truly one line per macro?
-@comment FIXME - see comment on --nesting-limit about NUM.
-
-@item -t @var{name}
-@itemx --trace=@var{name}
-@itemx --traceon=@var{name}
-This enables tracing for the macro @var{name}, at any point where it is
-defined. @var{name} need not be defined when this option is given.
-This option may be given more than once, and order is significant with
-respect to file names. @xref{Trace}, for more details.
-
-@item --traceoff=@var{name}
-This disables tracing for the macro @var{name}, at any point where it is
-defined. @var{name} need not be defined when this option is given.
-This option may be given more than once, and order is significant with
-respect to file names. @xref{Trace}, for more details.
-@end table
-
-@node Command line files
-@section Specifying input files on the command line
-
-@cindex command line, file names on the
-@cindex file names, on the command line
-The remaining arguments on the command line are taken to be input file
-names or module names (@pxref{Modules}). Whether or not any modules
-are loaded from command line arguments, when no actual input file names
-are given, then standard input is read. A file name of @file{-} can be
-used to denote standard input. It is conventional, but not required,
-for input file names to end in @samp{.m4} and for module names to end
-in @samp{.la}. The input files and modules are attended to in the
-sequence given.
-
-Standard input can be read more than once, so the file name @file{-}
-may appear multiple times on the command line; this makes a difference
-when input is from a terminal or other special file type. It is an
-error if an input file ends in the middle of argument collection, a
-comment, or a quoted string.
-@comment FIXME - it would be nicer if we let these three things
-@comment continue across file boundaries, provided that we warn in
-@comment interactive use when switching to stdin in a non-default parse
-@comment state.
-
-Various options, such as @option{--define} (@option{-D}), @option{--undefine}
-(@option{-U}), @option{--synclines} (@option{-s}), @option{--trace}
-(@option{-t}), and @option{--regexp-syntax} (@option{-r}), only take
-effect after processing input from any file names that occur earlier
-on the command line. For example, assume the file @file{foo} contains:
-
-@comment file: foo
-@example
-$ @kbd{cat foo}
-bar
-@end example
-
-The text @samp{bar} can then be redefined over multiple uses of
-@file{foo}:
-
-@comment options: -Dbar=hello foo -Dbar=world foo
-@example
-$ @kbd{m4 -Dbar=hello foo -Dbar=world foo}
-@result{}hello
-@result{}world
-@end example
-
-@cindex command line, module names on the
-@cindex module names, on the command line
-The use of loadable runtime modules in any sense is a GNU M4
-extension, so if @option{-G} is also passed or if the @env{POSIXLY_CORRECT}
-environment variable is set, even otherwise valid module names will be
-treated as though they were input file names (and no doubt cause havoc as
-M4 tries to scan and expand the contents as if it were written in @code{m4}).
-
-If none of the input files invoked @code{m4exit} (@pxref{M4exit}), the
-exit status of @code{m4} will be 0 for success, 1 for general failure
-(such as problems with reading an input file), and 63 for version
-mismatch (@pxref{Using frozen files}).
-
-If you need to read a file whose name starts with a @file{-}, you can
-specify it as @samp{./-file}, or use @option{--} to mark the end of
-options.
-
-@ignore
-@comment Test that 'm4 file/' detects that file is not a directory; we
-@comment can assume that the current directory contains a Makefile.
-@comment mingw fails with EINVAL rather than ENOTDIR.
-
-@comment status: 1
-@comment xerr: ignore
-@comment options: Makefile/
-@example
-@error{}m4: cannot open file 'Makefile/': No such file or directory
-@end example
-
-@comment Test that closed stderr does not cause a crash. Not all
-@comment systems have the same message for EBADF.
-
-@comment xerr: ignore
-@example
-ifdef(`__unix__', ,
- `errprint(` skipping: syscmd does not have unix semantics
-')m4exit(`77')')dnl
-syscmd(`echo | cat >&- 2>/dev/null')ifelse(sysval, `0',
- `errprint(` skipping: system does not allow closing stdout
-')m4exit(`77')')dnl
-changequote(`[', `]')dnl
-syscmd([echo | ']__program__[' >&-])dnl
-@error{}m4: write error: Bad file descriptor
-sysval
-@result{}1
-@end example
-
-@example
-ifdef(`__unix__', ,
- `errprint(` skipping: syscmd does not have unix semantics
-')m4exit(`77')')dnl
-syscmd(`echo | cat >&- 2>/dev/null')ifelse(sysval, `0',
- `errprint(` skipping: system does not allow closing stdout
-')m4exit(`77')')dnl
-changequote(`[', `]')dnl
-syscmd([echo 'esyscmd(echo hi >&2 && echo err"print(bye
-)d"nl)dnl' > tmp.m4 \
- && ']__program__[' tmp.m4 <&- >&- \
- && rm tmp.m4])sysval
-@error{}hi
-@error{}bye
-@result{}0
-@end example
-
-@comment Test that we obey POSIX semantics with -D interspersed with
-@comment files, even with POSIXLY_CORRECT (BSD getopt gets it wrong).
-
-$ @kbd{m4 }
-@example
-ifdef(`__unix__', ,
- `errprint(` skipping: syscmd does not have unix semantics
-')m4exit(`77')')dnl
-changequote(`[', `]')dnl
-syscmd([POSIXLY_CORRECT=1 ']__program__[' -Dbar=hello foo -Dbar=world foo])dnl
-@result{}hello
-@result{}world
-sysval
-@result{}0
-@end example
-@end ignore
-
-@node Syntax
-@chapter Lexical and syntactic conventions
-
-@cindex input tokens
-@cindex tokens
-As @code{m4} reads its input, it separates it into @dfn{tokens}. A
-token is either a name, a quoted string, or any single character, that
-is not a part of either a name or a string. Input to @code{m4} can also
-contain comments. GNU @code{m4} does not yet understand
-multibyte locales; all operations are byte-oriented rather than
-character-oriented (although if your locale uses a single byte
-encoding, such as @sc{ISO-8859-1}, you will not notice a difference).
-However, @code{m4} is eight-bit clean, so you can
-use non-@sc{ascii} characters in quoted strings (@pxref{Changequote}),
-comments (@pxref{Changecom}), and macro names (@pxref{Indir}), with the
-exception of the @sc{nul} character (the zero byte @samp{'\0'}).
-
-@comment FIXME - each builtin needs to document how it handles NUL, then
-@comment update the above paragraph to mention that NUL is now handled
-@comment transparently.
-
-@menu
-* Names:: Macro names
-* Quoted strings:: Quoting input to @code{m4}
-* Comments:: Comments in @code{m4} input
-* Other tokens:: Other kinds of input tokens
-* Input processing:: How @code{m4} copies input to output
-* Regular expression syntax:: How @code{m4} interprets regular expressions
-@end menu
-
-@node Names
-@section Macro names
-
-@cindex names
-@cindex words
-A name is any sequence of letters, digits, and the character @samp{_}
-(underscore), where the first character is not a digit. @code{m4} will
-use the longest such sequence found in the input. If a name has a
-macro definition, it will be subject to macro expansion
-(@pxref{Macros}). Names are case-sensitive.
-
-Examples of legal names are: @samp{foo}, @samp{_tmp}, and @samp{name01}.
-
-The definitions of letters, digits and other input characters can be
-changed at any time, using the builtin macro @code{changesyntax}.
-@xref{Changesyntax}, for more information.
-
-@node Quoted strings
-@section Quoting input to @code{m4}
-
-@cindex quoted string
-@cindex string, quoted
-A quoted string is a sequence of characters surrounded by quote
-strings, defaulting to
-@samp{`} (grave-accent, also known as back-tick, with UCS value U0060)
-and @samp{'} (apostrophe, also known as single-quote, with UCS value
-U0027), where the nested begin and end quotes within the
-string are balanced. The value of a string token is the text, with one
-level of quotes stripped off. Thus
-
-@comment ignore
-@example
-`'
-@result{}
-@end example
-
-@noindent
-is the empty string, and double-quoting turns into single-quoting.
-
-@comment ignore
-@example
-``quoted''
-@result{}`quoted'
-@end example
-
-The quote characters can be changed at any time, using the builtin macros
-@code{changequote} (@pxref{Changequote}) or @code{changesyntax}
-(@pxref{Changesyntax}).
-
-@node Comments
-@section Comments in @code{m4} input
-
-@cindex comments
-Comments in @code{m4} are normally delimited by the characters @samp{#}
-and newline. All characters between the comment delimiters are ignored,
-but the entire comment (including the delimiters) is passed through to
-the output, unless you supply the @option{--discard-comments} or
-@option{-c} option at the command line (@pxref{Operation modes, ,
-Invoking m4}). When discarding comments, the comment delimiters are
-discarded, even if the close-comment string is a newline.
-
-Comments cannot be nested, so the first newline after a @samp{#} ends
-the comment. The commenting effect of the begin-comment string
-can be inhibited by quoting it.
-
-@example
-$ @kbd{m4}
-`quoted text' # `commented text'
-@result{}quoted text # `commented text'
-`quoting inhibits' `#' `comments'
-@result{}quoting inhibits # comments
-@end example
-
-@comment options: -c
-@example
-$ @kbd{m4 -c}
-`quoted text' # `commented text'
-`quoting inhibits' `#' `comments'
-@result{}quoted text quoting inhibits # comments
-@end example
-
-The comment delimiters can be changed to any string at any time, using
-the builtin macros @code{changecom} (@pxref{Changecom}) or
-@code{changesyntax} (@pxref{Changesyntax}).
-
-@node Other tokens
-@section Other kinds of input tokens
-
-@cindex tokens, special
-Any character, that is neither a part of a name, nor of a quoted string,
-nor a comment, is a token by itself. When not in the context of macro
-expansion, all of these tokens are just copied to output. However,
-during macro expansion, whitespace characters (space, tab, newline,
-formfeed, carriage return, vertical tab), parentheses (@samp{(} and
-@samp{)}), comma (@samp{,}), and dollar (@samp{$}) have additional
-roles, explained later. Which characters actually perform these roles
-can be adjusted with @code{changesyntax} (@pxref{Changesyntax}).
-
-@node Input processing
-@section How @code{m4} copies input to output
-
-As @code{m4} reads the input token by token, it will copy each token
-directly to the output immediately.
-
-The exception is when it finds a word with a macro definition. In that
-case @code{m4} will calculate the macro's expansion, possibly reading
-more input to get the arguments. It then inserts the expansion in front
-of the remaining input. In other words, the resulting text from a macro
-call will be read and parsed into tokens again.
-
-@code{m4} expands a macro as soon as possible. If it finds a macro call
-when collecting the arguments to another, it will expand the second call
-first. This process continues until there are no more macro calls to
-expand and all the input has been consumed.
-
-For a running example, examine how @code{m4} handles this input:
-
-@comment ignore
-@example
-format(`Result is %d', eval(`2**15'))
-@end example
-
-@noindent
-First, @code{m4} sees that the token @samp{format} is a macro name, so
-it collects the tokens @samp{(}, @samp{`Result is %d'}, @samp{,},
-and @samp{@w{ }}, before encountering another potential macro. Sure
-enough, @samp{eval} is a macro name, so the nested argument collection
-picks up @samp{(}, @samp{`2**15'}, and @samp{)}, invoking the eval macro
-with the lone argument of @samp{2**15}. The expansion of
-@samp{eval(2**15)} is @samp{32768}, which is then rescanned as the five
-tokens @samp{3}, @samp{2}, @samp{7}, @samp{6}, and @samp{8}; and
-combined with the next @samp{)}, the format macro now has all its
-arguments, as if the user had typed:
-
-@comment ignore
-@example
-format(`Result is %d', 32768)
-@end example
-
-@noindent
-The format macro expands to @samp{Result is 32768}, and we have another
-round of scanning for the tokens @samp{Result}, @samp{@w{ }},
-@samp{is}, @samp{@w{ }}, @samp{3}, @samp{2}, @samp{7}, @samp{6}, and
-@samp{8}. None of these are macros, so the final output is
-
-@comment ignore
-@example
-@result{}Result is 32768
-@end example
-
-As a more complicated example, we will contrast an actual code example
-from the Gnulib project@footnote{Derived from a patch in
-@uref{http://lists.gnu.org/archive/html/bug-gnulib/@/2007-01/@/msg00389.html},
-and a followup patch in
-@uref{http://lists.gnu.org/archive/html/bug-gnulib/@/2007-02/@/msg00000.html}},
-showing both a buggy approach and the desired results. The user desires
-to output a shell assignment statement that takes its argument and turns
-it into a shell variable by converting it to uppercase and prepending a
-prefix. The original attempt looks like this:
-
-@example
-changequote([,])dnl
-define([gl_STRING_MODULE_INDICATOR],
- [
- dnl comment
- GNULIB_]translit([$1],[a-z],[A-Z])[=1
- ])dnl
- gl_STRING_MODULE_INDICATOR([strcase])
-@result{} @w{ }
-@result{} GNULIB_strcase=1
-@result{} @w{ }
-@end example
-
-Oops -- the argument did not get capitalized. And although the manual
-is not able to easily show it, both lines that appear empty actually
-contain two trailing spaces. By stepping through the parse, it is easy
-to see what happened. First, @code{m4} sees the token
-@samp{changequote}, which it recognizes as a macro, followed by
-@samp{(}, @samp{[}, @samp{,}, @samp{]}, and @samp{)} to form the
-argument list. The macro expands to the empty string, but changes the
-quoting characters to something more useful for generating shell code
-(unbalanced @samp{`} and @samp{'} appear all the time in shell scripts,
-but unbalanced @samp{[]} tend to be rare). Also in the first line,
-@code{m4} sees the token @samp{dnl}, which it recognizes as a builtin
-macro that consumes the rest of the line, resulting in no output for
-that line.
-
-The second line starts a macro definition. @code{m4} sees the token
-@samp{define}, which it recognizes as a macro, followed by a @samp{(},
-@samp{[gl_STRING_MODULE_INDICATOR]}, and @samp{,}. Because an unquoted
-comma was encountered, the first argument is known to be the expansion
-of the single-quoted string token, or @samp{gl_STRING_MODULE_INDICATOR}.
-Next, @code{m4} sees @samp{@key{NL}}, @samp{ }, and @samp{ }, but this
-whitespace is discarded as part of argument collection. Then comes a
-rather lengthy single-quoted string token, @samp{[@key{NL}@ @ @ @ dnl
-comment@key{NL}@ @ @ @ GNULIB_]}. This is followed by the token
-@samp{translit}, which @code{m4} recognizes as a macro name, so a nested
-macro expansion has started.
-
-The arguments to the @code{translit} are found by the tokens @samp{(},
-@samp{[$1]}, @samp{,}, @samp{[a-z]}, @samp{,}, @samp{[A-Z]}, and finally
-@samp{)}. All three string arguments are expanded (or in other words,
-the quotes are stripped), and since neither @samp{$} nor @samp{1} need
-capitalization, the result of the macro is @samp{$1}. This expansion is
-rescanned, resulting in the two literal characters @samp{$} and
-@samp{1}.
-
-Scanning of the outer macro resumes, and picks up with
-@samp{[=1@key{NL}@ @ ]}, and finally @samp{)}. The collected pieces of
-expanded text are concatenated, with the end result that the macro
-@samp{gl_STRING_MODULE_INDICATOR} is now defined to be the sequence
-@samp{@key{NL}@ @ @ @ dnl comment@key{NL}@ @ @ @ GNULIB_$1=1@key{NL}@ @ }.
-Once again, @samp{dnl} is recognized and avoids a newline in the output.
-
-The final line is then parsed, beginning with @samp{ } and @samp{ }
-that are output literally. Then @samp{gl_STRING_MODULE_INDICATOR} is
-recognized as a macro name, with an argument list of @samp{(},
-@samp{[strcase]}, and @samp{)}. Since the definition of the macro
-contains the sequence @samp{$1}, that sequence is replaced with the
-argument @samp{strcase} prior to starting the rescan. The rescan sees
-@samp{@key{NL}} and four spaces, which are output literally, then
-@samp{dnl}, which discards the text @samp{ comment@key{NL}}. Next
-comes four more spaces, also output literally, and the token
-@samp{GNULIB_strcase}, which resulted from the earlier parameter
-substitution. Since that is not a macro name, it is output literally,
-followed by the literal tokens @samp{=}, @samp{1}, @samp{@key{NL}}, and
-two more spaces. Finally, the original @samp{@key{NL}} seen after the
-macro invocation is scanned and output literally.
-
-Now for a corrected approach. This rearranges the use of newlines and
-whitespace so that less whitespace is output (which, although harmless
-to shell scripts, can be visually unappealing), and fixes the quoting
-issues so that the capitalization occurs when the macro
-@samp{gl_STRING_MODULE_INDICATOR} is invoked, rather then when it is
-defined. It also adds another layer of quoting to the first argument of
-@code{translit}, to ensure that the output will be rescanned as a string
-rather than a potential uppercase macro name needing further expansion.
-
-@example
-changequote([,])dnl
-define([gl_STRING_MODULE_INDICATOR],
- [dnl comment
- GNULIB_[]translit([[$1]], [a-z], [A-Z])=1dnl
-])dnl
- gl_STRING_MODULE_INDICATOR([strcase])
-@result{} GNULIB_STRCASE=1
-@end example
-
-The parsing of the first line is unchanged. The second line sees the
-name of the macro to define, then sees the discarded @samp{@key{NL}}
-and two spaces, as before. But this time, the next token is
-@samp{[dnl comment@key{NL}@ @ GNULIB_[]translit([[$1]], [a-z],
-[A-Z])=1dnl@key{NL}]}, which includes nested quotes, followed by
-@samp{)} to end the macro definition and @samp{dnl} to skip the
-newline. No early expansion of @code{translit} occurs, so the entire
-string becomes the definition of the macro.
-
-The final line is then parsed, beginning with two spaces that are
-output literally, and an invocation of
-@code{gl_STRING_MODULE_INDICATOR} with the argument @samp{strcase}.
-Again, the @samp{$1} in the macro definition is substituted prior to
-rescanning. Rescanning first encounters @samp{dnl}, and discards
-@samp{ comment@key{NL}}. Then two spaces are output literally. Next
-comes the token @samp{GNULIB_}, but that is not a macro, so it is
-output literally. The token @samp{[]} is an empty string, so it does
-not affect output. Then the token @samp{translit} is encountered.
-
-This time, the arguments to @code{translit} are parsed as @samp{(},
-@samp{[[strcase]]}, @samp{,}, @samp{ }, @samp{[a-z]}, @samp{,}, @samp{ },
-@samp{[A-Z]}, and @samp{)}. The two spaces are discarded, and the
-translit results in the desired result @samp{[STRCASE]}. This is
-rescanned, but since it is a string, the quotes are stripped and the
-only output is a literal @samp{STRCASE}.
-Then the scanner sees @samp{=} and @samp{1}, which are output
-literally, followed by @samp{dnl} which discards the rest of the
-definition of @code{gl_STRING_MODULE_INDICATOR}. The newline at the
-end of output is the literal @samp{@key{NL}} that appeared after the
-invocation of the macro.
-
-The order in which @code{m4} expands the macros can be further explored
-using the trace facilities of GNU @code{m4} (@pxref{Trace}).
-
-@node Regular expression syntax
-@section How @code{m4} interprets regular expressions
-
-There are several contexts where @code{m4} parses an argument as a
-regular expression. This section describes the various flavors of
-regular expressions. @xref{Changeresyntax}.
-
-@include regexprops-generic.texi
-
-@node Macros
-@chapter How to invoke macros
-
-This chapter covers macro invocation, macro arguments and how macro
-expansion is treated.
-
-@menu
-* Invocation:: Macro invocation
-* Inhibiting Invocation:: Preventing macro invocation
-* Macro Arguments:: Macro arguments
-* Quoting Arguments:: On Quoting Arguments to macros
-* Macro expansion:: Expanding macros
-@end menu
-
-@node Invocation
-@section Macro invocation
-
-@cindex macro invocation
-@cindex invoking macros
-Macro invocations has one of the forms
-
-@comment ignore
-@example
-name
-@end example
-
-@noindent
-which is a macro invocation without any arguments, or
-
-@comment ignore
-@example
-name(arg1, arg2, @dots{}, arg@var{n})
-@end example
-
-@noindent
-which is a macro invocation with @var{n} arguments. Macros can have any
-number of arguments. All arguments are strings, but different macros
-might interpret the arguments in different ways.
-
-The opening parenthesis @emph{must} follow the @var{name} directly, with
-no spaces in between. If it does not, the macro is called with no
-arguments at all.
-
-For a macro call to have no arguments, the parentheses @emph{must} be
-left out. The macro call
-
-@comment ignore
-@example
-name()
-@end example
-
-@noindent
-is a macro call with one argument, which is the empty string, not a call
-with no arguments.
-
-@node Inhibiting Invocation
-@section Preventing macro invocation
-
-An innovation of the @code{m4} language, compared to some of its
-predecessors (like Strachey's @code{GPM}, for example), is the ability
-to recognize macro calls without resorting to any special, prefixed
-invocation character. While generally useful, this feature might
-sometimes be the source of spurious, unwanted macro calls. So, GNU
-@code{m4} offers several mechanisms or techniques for inhibiting the
-recognition of names as macro calls.
-
-@cindex GNU extensions
-@cindex blind macro
-@cindex macro, blind
-First of all, many builtin macros cannot meaningfully be called without
-arguments. As a GNU extension, for any of these macros,
-whenever an opening parenthesis does not immediately follow their name,
-the builtin macro call is not triggered. This solves the most usual
-cases, like for @samp{include} or @samp{eval}. Later in this document,
-the sentence ``This macro is recognized only with parameters'' refers to
-this specific provision of GNU M4, also known as a blind
-builtin macro. For the builtins defined by POSIX that bear
-this disclaimer, POSIX specifically states that invoking those
-builtins without arguments is unspecified, because many other
-implementations simply invoke the builtin as though it were given one
-empty argument instead.
-
-@example
-$ @kbd{m4}
-eval
-@result{}eval
-eval(`1')
-@result{}1
-@end example
-
-There is also a command line option (@option{--prefix-builtins}, or
-@option{-P}, @pxref{Operation modes, , Invoking m4}) that renames all
-builtin macros with a prefix of @samp{m4_} at startup. The option has
-no effect whatsoever on user defined macros. For example, with this option,
-one has to write @code{m4_dnl} and even @code{m4_m4exit}. It also has
-no effect on whether a macro requires parameters.
-
-@comment options: -P
-@example
-$ @kbd{m4 -P}
-eval
-@result{}eval
-eval(`1')
-@result{}eval(1)
-m4_eval
-@result{}m4_eval
-m4_eval(`1')
-@result{}1
-@end example
-
-Another alternative is to redefine problematic macros to a name less
-likely to cause conflicts, using @ref{Definitions}. Or the parsing
-engine can be changed to redefine what constitutes a valid macro name,
-using @ref{Changesyntax}.
-
-Of course, the simplest way to prevent a name from being interpreted
-as a call to an existing macro is to quote it. The remainder of
-this section studies a little more deeply how quoting affects macro
-invocation, and how quoting can be used to inhibit macro invocation.
-
-Even if quoting is usually done over the whole macro name, it can also
-be done over only a few characters of this name (provided, of course,
-that the unquoted portions are not also a macro). It is also possible
-to quote the empty string, but this works only @emph{inside} the name.
-For example:
-
-@example
-`divert'
-@result{}divert
-`d'ivert
-@result{}divert
-di`ver't
-@result{}divert
-div`'ert
-@result{}divert
-@end example
-
-@noindent
-all yield the string @samp{divert}. While in both:
-
-@example
-`'divert
-@result{}
-divert`'
-@result{}
-@end example
-
-@noindent
-the @code{divert} builtin macro will be called, which expands to the
-empty string.
-
-@cindex rescanning
-The output of macro evaluations is always rescanned. In the following
-example, the input @samp{x`'y} yields the string @samp{bCD}, exactly as
-if @code{m4}
-has been given @w{@samp{substr(ab`'cde, `1', `3')}} as input:
-
-@example
-define(`cde', `CDE')
-@result{}
-define(`x', `substr(ab')
-@result{}
-define(`y', `cde, `1', `3')')
-@result{}
-x`'y
-@result{}bCD
-@end example
-
-Unquoted strings on either side of a quoted string are subject to
-being recognized as macro names. In the following example, quoting the
-empty string allows for the second @code{macro} to be recognized as such:
-
-@example
-define(`macro', `m')
-@result{}
-macro(`m')macro
-@result{}mmacro
-macro(`m')`'macro
-@result{}mm
-@end example
-
-Quoting may prevent recognizing as a macro name the concatenation of a
-macro expansion with the surrounding characters. In this example:
-
-@example
-define(`macro', `di$1')
-@result{}
-macro(`v')`ert'
-@result{}divert
-macro(`v')ert
-@result{}
-@end example
-
-@noindent
-the input will produce the string @samp{divert}. When the quotes were
-removed, the @code{divert} builtin was called instead.
-
-@node Macro Arguments
-@section Macro arguments
-
-@cindex macros, arguments to
-@cindex arguments to macros
-When a name is seen, and it has a macro definition, it will be expanded
-as a macro.
-
-If the name is followed by an opening parenthesis, the arguments will be
-collected before the macro is called. If too few arguments are
-supplied, the missing arguments are taken to be the empty string.
-However, some builtins are documented to behave differently for a
-missing optional argument than for an explicit empty string. If there
-are too many arguments, the excess arguments are ignored. Unquoted
-leading whitespace is stripped off all arguments, but whitespace
-generated by a macro expansion or occurring after a macro that expanded
-to an empty string remains intact. Whitespace includes space, tab,
-newline, carriage return, vertical tab, and formfeed.
-
-@example
-define(`macro', `$1')
-@result{}
-macro( unquoted leading space lost)
-@result{}unquoted leading space lost
-macro(` quoted leading space kept')
-@result{} quoted leading space kept
-macro(
- divert `unquoted space kept after expansion')
-@result{} unquoted space kept after expansion
-macro(macro(`
-')`whitespace from expansion kept')
-@result{}
-@result{}whitespace from expansion kept
-macro(`unquoted trailing whitespace kept'
-)
-@result{}unquoted trailing whitespace kept
-@result{}
-@end example
-
-@cindex warnings, suppressing
-@cindex suppressing warnings
-Normally @code{m4} will issue warnings if a builtin macro is called
-with an inappropriate number of arguments, but it can be suppressed with
-the @option{--quiet} command line option (or @option{--silent}, or
-@option{-Q}, @pxref{Operation modes, , Invoking m4}). For user
-defined macros, there is no check of the number of arguments given.
-
-@example
-$ @kbd{m4}
-index(`abc')
-@error{}m4:stdin:1: warning: index: too few arguments: 1 < 2
-@result{}0
-index(`abc',)
-@result{}0
-index(`abc', `b', `0', `ignored')
-@error{}m4:stdin:3: warning: index: extra arguments ignored: 4 > 3
-@result{}1
-@end example
-
-@comment options: -Q
-@example
-$ @kbd{m4 -Q}
-index(`abc')
-@result{}0
-index(`abc',)
-@result{}0
-index(`abc', `b', `', `ignored')
-@result{}1
-@end example
-
-Macros are expanded normally during argument collection, and whatever
-commas, quotes and parentheses that might show up in the resulting
-expanded text will serve to define the arguments as well. Thus, if
-@var{foo} expands to @samp{, b, c}, the macro call
-
-@comment ignore
-@example
-bar(a foo, d)
-@end example
-
-@noindent
-is a macro call with four arguments, which are @samp{a }, @samp{b},
-@samp{c} and @samp{d}. To understand why the first argument contains
-whitespace, remember that unquoted leading whitespace is never part
-of an argument, but trailing whitespace always is.
-
-It is possible for a macro's definition to change during argument
-collection, in which case the expansion uses the definition that was in
-effect at the time the opening @samp{(} was seen.
-
-@example
-define(`f', `1')
-@result{}
-f(define(`f', `2'))
-@result{}1
-f
-@result{}2
-@end example
-
-It is an error if the end of file occurs while collecting arguments.
-
-@comment status: 1
-@example
-hello world
-@result{}hello world
-define(
-^D
-@error{}m4:stdin:2: define: end of file in argument list
-@end example
-
-@node Quoting Arguments
-@section On Quoting Arguments to macros
-
-@cindex quoted macro arguments
-@cindex macros, quoted arguments to
-@cindex arguments, quoted macro
-Each argument has unquoted leading whitespace removed. Within each
-argument, all unquoted parentheses must match. For example, if
-@var{foo} is a macro,
-
-@comment ignore
-@example
-foo(() (`(') `(')
-@end example
-
-@noindent
-is a macro call, with one argument, whose value is @samp{() (() (}.
-Commas separate arguments, except when they occur inside quotes,
-comments, or unquoted parentheses. @xref{Pseudo Arguments}, for
-examples.
-
-It is common practice to quote all arguments to macros, unless you are
-sure you want the arguments expanded. Thus, in the above
-example with the parentheses, the `right' way to do it is like this:
-
-@comment ignore
-@example
-foo(`() (() (')
-@end example
-
-@cindex quoting rule of thumb
-@cindex rule of thumb, quoting
-It is, however, in certain cases necessary (because nested expansion
-must occur to create the arguments for the outer macro) or convenient
-(because it uses fewer characters) to leave out quotes for some
-arguments, and there is nothing wrong in doing it. It just makes life a
-bit harder, if you are not careful to follow a consistent quoting style.
-For consistency, this manual follows the rule of thumb that each layer
-of parentheses introduces another layer of single quoting, except when
-showing the consequences of quoting rules. This is done even when the
-quoted string cannot be a macro, such as with integers when you have not
-changed the syntax via @code{changesyntax} (@pxref{Changesyntax}).
-
-The quoting rule of thumb of one level of quoting per parentheses has a
-nice property: when a macro name appears inside parentheses, you can
-determine when it will be expanded. If it is not quoted, it will be
-expanded prior to the outer macro, so that its expansion becomes the
-argument. If it is single-quoted, it will be expanded after the outer
-macro. And if it is double-quoted, it will be used as literal text
-instead of a macro name.
-
-@example
-define(`active', `ACT, IVE')
-@result{}
-define(`show', `$1 $1')
-@result{}
-show(active)
-@result{}ACT ACT
-show(`active')
-@result{}ACT, IVE ACT, IVE
-show(``active'')
-@result{}active active
-@end example
-
-@node Macro expansion
-@section Macro expansion
-
-@cindex macros, expansion of
-@cindex expansion of macros
-When the arguments, if any, to a macro call have been collected, the
-macro is expanded, and the expansion text is pushed back onto the input
-(unquoted), and reread. The expansion text from one macro call might
-therefore result in more macros being called, if the calls are included,
-completely or partially, in the first macro calls' expansion.
-
-Taking a very simple example, if @var{foo} expands to @samp{bar}, and
-@var{bar} expands to @samp{Hello world}, the input
-
-@comment options: -Dbar='Hello world' -Dfoo=bar
-@example
-$ @kbd{m4 -Dbar="Hello world" -Dfoo=bar}
-foo
-@result{}Hello world
-@end example
-
-@noindent
-will expand first to @samp{bar}, and when this is reread and
-expanded, into @samp{Hello world}.
-
-@node Definitions
-@chapter How to define new macros
-
-@cindex macros, how to define new
-@cindex defining new macros
-Macros can be defined, redefined and deleted in several different ways.
-Also, it is possible to redefine a macro without losing a previous
-value, and bring back the original value at a later time.
-
-@menu
-* Define:: Defining a new macro
-* Arguments:: Arguments to macros
-* Pseudo Arguments:: Special arguments to macros
-* Undefine:: Deleting a macro
-* Defn:: Renaming macros
-* Pushdef:: Temporarily redefining macros
-* Renamesyms:: Renaming macros with regular expressions
-
-* Indir:: Indirect call of macros
-* Builtin:: Indirect call of builtins
-* M4symbols:: Getting the defined macro names
-@end menu
-
-@node Define
-@section Defining a macro
-
-The normal way to define or redefine macros is to use the builtin
-@code{define}:
-
-@deffn {Builtin (m4)} define (@var{name}, @ovar{expansion})
-Defines @var{name} to expand to @var{expansion}. If
-@var{expansion} is not given, it is taken to be empty.
-
-The expansion of @code{define} is void.
-The macro @code{define} is recognized only with parameters.
-@end deffn
-@comment Other implementations, such as Solaris, can define a macro
-@comment with a builtin token attached to text:
-@comment define(foo, a`'defn(`divnum')b)
-@comment defn(`foo') => ab
-@comment dumpdef(`foo') => foo: a<divnum>b
-@comment len(defn(`foo')) => 3
-@comment index(defn(`foo'), defn(`divnum')) => 1
-@comment foo => a0b
-@comment It may be worth making some changes to support this behavior,
-@comment or something similar to it.
-@comment
-@comment But be sure it has sane semantics, with potentially deferred
-@comment expansion of builtins. For example, this should not warn
-@comment about trying to access the definition of an undefined macro:
-@comment define(`foo', `ifdef(`$1', 'defn(`defn')`)')foo(`oops')
-@comment Also, think how to handle conflicting argument counts:
-@comment define(`bar', defn(`dnl', `len'))
-
-The following example defines the macro @var{foo} to expand to the text
-@samp{Hello World.}.
-
-@example
-define(`foo', `Hello world.')
-@result{}
-foo
-@result{}Hello world.
-@end example
-
-The empty line in the output is there because the newline is not
-a part of the macro definition, and it is consequently copied to
-the output. This can be avoided by use of the macro @code{dnl}.
-@xref{Dnl}, for details.
-
-The first argument to @code{define} should be quoted; otherwise, if the
-macro is already defined, you will be defining a different macro. This
-example shows the problems with underquoting, since we did not want to
-redefine @code{one}:
-
-@example
-define(foo, one)
-@result{}
-define(foo, two)
-@result{}
-one
-@result{}two
-@end example
-
-@cindex GNU extensions
-GNU @code{m4} normally replaces only the @emph{topmost}
-definition of a macro if it has several definitions from @code{pushdef}
-(@pxref{Pushdef}). Some other implementations of @code{m4} replace all
-definitions of a macro with @code{define}. @xref{Incompatibilities},
-for more details.
-
-As a GNU extension, the first argument to @code{define} does
-not have to be a simple word.
-It can be any text string, even the empty string. A macro with a
-non-standard name cannot be invoked in the normal way, as the name is
-not recognized. It can only be referenced by the builtins @code{Indir}
-(@pxref{Indir}) and @code{Defn} (@pxref{Defn}).
-
-@cindex arrays
-Arrays and associative arrays can be simulated by using non-standard
-macro names.
-
-@deffn Composite array (@var{index})
-@deffnx Composite array_set (@var{index}, @ovar{value})
-Provide access to entries within an array. @code{array} reads the entry
-at location @var{index}, and @code{array_set} assigns @var{value} to
-location @var{index}.
-@end deffn
-
-@example
-define(`array', `defn(format(``array[%d]'', `$1'))')
-@result{}
-define(`array_set', `define(format(``array[%d]'', `$1'), `$2')')
-@result{}
-array_set(`4', `array element no. 4')
-@result{}
-array_set(`17', `array element no. 17')
-@result{}
-array(`4')
-@result{}array element no. 4
-array(eval(`10 + 7'))
-@result{}array element no. 17
-@end example
-
-Change the @samp{%d} to @samp{%s} and it is an associative array.
-
-@node Arguments
-@section Arguments to macros
-
-@cindex macros, arguments to
-@cindex arguments to macros
-Macros can have arguments. The @var{n}th argument is denoted by
-@code{$n} in the expansion text, and is replaced by the @var{n}th actual
-argument, when the macro is expanded. Replacement of arguments happens
-before rescanning, regardless of how many nesting levels of quoting
-appear in the expansion. Here is an example of a macro with
-two arguments.
-
-@deffn Composite exch (@var{arg1}, @var{arg2})
-Expands to @var{arg2} followed by @var{arg1}, effectively exchanging
-their order.
-@end deffn
-
-@example
-define(`exch', `$2, $1')
-@result{}
-exch(`arg1', `arg2')
-@result{}arg2, arg1
-@end example
-
-This can be used, for example, if you like the arguments to
-@code{define} to be reversed.
-
-@example
-define(`exch', `$2, $1')
-@result{}
-define(exch(``expansion text'', ``macro''))
-@result{}
-macro
-@result{}expansion text
-@end example
-
-@xref{Quoting Arguments}, for an explanation of the double quotes.
-(You should try and improve this example so that clients of @code{exch}
-do not have to double quote; or @pxref{Improved exch, , Answers}).
-
-@cindex GNU extensions
-GNU @code{m4} allows the number following the @samp{$} to
-consist of one
-or more digits, allowing macros to have any number of arguments. This
-is not so in UNIX implementations of @code{m4}, which only recognize
-one digit.
-@comment FIXME - See Austin group XCU ERN 111. POSIX says that $11 must
-@comment be the first argument concatenated with 1, and instead reserves
-@comment ${11} for implementation use. Once this is implemented, the
-@comment documentation needs to reflect how these extended arguments
-@comment are handled, as well as backwards compatibility issues with
-@comment 1.4.x. Also, consider adding further extensions such as
-@comment ${1-default}, which expands to `default' if $1 is empty.
-
-As a special case, the zeroth argument, @code{$0}, is always the name
-of the macro being expanded.
-
-@example
-define(`test', ``Macro name: $0'')
-@result{}
-test
-@result{}Macro name: test
-@end example
-
-If you want quoted text to appear as part of the expansion text,
-remember that quotes can be nested in quoted strings. Thus, in
-
-@example
-define(`foo', `This is macro `foo'.')
-@result{}
-foo
-@result{}This is macro foo.
-@end example
-
-@noindent
-The @samp{foo} in the expansion text is @emph{not} expanded, since it is
-a quoted string, and not a name.
-
-@node Pseudo Arguments
-@section Special arguments to macros
-
-@cindex special arguments to macros
-@cindex macros, special arguments to
-@cindex arguments to macros, special
-There is a special notation for the number of actual arguments supplied,
-and for all the actual arguments.
-
-The number of actual arguments in a macro call is denoted by @code{$#}
-in the expansion text.
-
-@deffn Composite nargs (@dots{})
-Expands to a count of the number of arguments supplied.
-@end deffn
-
-@example
-define(`nargs', `$#')
-@result{}
-nargs
-@result{}0
-nargs()
-@result{}1
-nargs(`arg1', `arg2', `arg3')
-@result{}3
-nargs(`commas can be quoted, like this')
-@result{}1
-nargs(arg1#inside comments, commas do not separate arguments
-still arg1)
-@result{}1
-nargs((unquoted parentheses, like this, group arguments))
-@result{}1
-@end example
-
-Remember that @samp{#} defaults to the comment character; if you forget
-quotes to inhibit the comment behavior, your macro definition may not
-end where you expected.
-
-@example
-dnl Attempt to define a macro to just `$#'
-define(underquoted, $#)
-oops)
-@result{}
-underquoted
-@result{}0)
-@result{}oops
-@end example
-
-The notation @code{$*} can be used in the expansion text to denote all
-the actual arguments, unquoted, with commas in between. For example
-
-@example
-define(`echo', `$*')
-@result{}
-echo(arg1, arg2, arg3 , arg4)
-@result{}arg1,arg2,arg3 ,arg4
-@end example
-
-Often each argument should be quoted, and the notation @code{$@@} handles
-that. It is just like @code{$*}, except that it quotes each argument.
-A simple example of that is:
-
-@example
-define(`echo', `$@@')
-@result{}
-echo(arg1, arg2, arg3 , arg4)
-@result{}arg1,arg2,arg3 ,arg4
-@end example
-
-Where did the quotes go? Of course, they were eaten, when the expanded
-text were reread by @code{m4}. To show the difference, try
-
-@example
-define(`echo1', `$*')
-@result{}
-define(`echo2', `$@@')
-@result{}
-define(`foo', `This is macro `foo'.')
-@result{}
-echo1(foo)
-@result{}This is macro This is macro foo..
-echo1(`foo')
-@result{}This is macro foo.
-echo2(foo)
-@result{}This is macro foo.
-echo2(`foo')
-@result{}foo
-@end example
-
-@noindent
-@xref{Trace}, if you do not understand this. As another example of the
-difference, remember that comments encountered in arguments are passed
-untouched to the macro, and that quoting disables comments.
-
-@example
-define(`echo1', `$*')
-@result{}
-define(`echo2', `$@@')
-@result{}
-define(`foo', `bar')
-@result{}
-echo1(#foo'foo
-foo)
-@result{}#foo'foo
-@result{}bar
-echo2(#foo'foo
-foo)
-@result{}#foobar
-@result{}bar'
-@end example
-
-A @samp{$} sign in the expansion text, that is not followed by anything
-@code{m4} understands, is simply copied to the macro expansion, as any
-other text is.
-
-@example
-define(`foo', `$$$ hello $$$')
-@result{}
-foo
-@result{}$$$ hello $$$
-@end example
-
-@cindex rescanning
-@cindex literal output
-@cindex output, literal
-If you want a macro to expand to something like @samp{$12}, the
-judicious use of nested quoting can put a safe character between the
-@code{$} and the next character, relying on the rescanning to remove the
-nested quote. This will prevent @code{m4} from interpreting the
-@code{$} sign as a reference to an argument.
-
-@example
-define(`foo', `no nested quote: $1')
-@result{}
-foo(`arg')
-@result{}no nested quote: arg
-define(`foo', `nested quote around $: `$'1')
-@result{}
-foo(`arg')
-@result{}nested quote around $: $1
-define(`foo', `nested empty quote after $: $`'1')
-@result{}
-foo(`arg')
-@result{}nested empty quote after $: $1
-define(`foo', `nested quote around next character: $`1'')
-@result{}
-foo(`arg')
-@result{}nested quote around next character: $1
-define(`foo', `nested quote around both: `$1'')
-@result{}
-foo(`arg')
-@result{}nested quote around both: arg
-@end example
-
-@node Undefine
-@section Deleting a macro
-
-@cindex macros, how to delete
-@cindex deleting macros
-@cindex undefining macros
-A macro definition can be removed with @code{undefine}:
-
-@deffn {Builtin (m4)} undefine (@var{name}@dots{})
-For each argument, remove the macro @var{name}. The macro names must
-necessarily be quoted, since they will be expanded otherwise. If an
-argument is not a defined macro, then the @samp{d} debug level controls
-whether a warning is issued (@pxref{Debugmode}).
-
-The expansion of @code{undefine} is void.
-The macro @code{undefine} is recognized only with parameters.
-@end deffn
-
-@example
-foo bar blah
-@result{}foo bar blah
-define(`foo', `some')define(`bar', `other')define(`blah', `text')
-@result{}
-foo bar blah
-@result{}some other text
-undefine(`foo')
-@result{}
-foo bar blah
-@result{}foo other text
-undefine(`bar', `blah')
-@result{}
-foo bar blah
-@result{}foo bar blah
-@end example
-
-Undefining a macro inside that macro's expansion is safe; the macro
-still expands to the definition that was in effect at the @samp{(}.
-
-@example
-define(`f', ``$0':$1')
-@result{}
-f(f(f(undefine(`f')`hello world')))
-@result{}f:f:f:hello world
-f(`bye')
-@result{}f(bye)
-@end example
-
-As of M4 1.6, @code{undefine} can warn if @var{name} is not a macro, by
-using @code{debugmode} (@pxref{Debugmode}) or the command line option
-@option{-d} (@option{--debugmode}, @pxref{Debugging options, , Invoking
-m4}).
-
-@example
-$ @kbd{m4}
-undefine(`a')
-@error{}m4:stdin:1: warning: undefine: undefined macro 'a'
-@result{}
-debugmode(`-d')
-@result{}
-undefine(`a')
-@result{}
-@end example
-
-@node Defn
-@section Renaming macros
-
-@cindex macros, how to rename
-@cindex renaming macros
-@cindex macros, displaying definitions
-@cindex definitions, displaying macro
-It is possible to rename an already defined macro. To do this, you need
-the builtin @code{defn}:
-
-@deffn {Builtin (m4)} defn (@var{name}@dots{})
-Expands to the @emph{quoted definition} of each @var{name}. If an
-argument is not a defined macro, the expansion for that argument is
-empty, and the @samp{d} debug level controls whether a warning is issued
-(@pxref{Debugmode}).
-
-If @var{name} is a user-defined macro, the quoted definition is simply
-the quoted expansion text. If, instead, @var{name} is a builtin, the
-expansion is a special token, which points to the builtin's internal
-definition. This token meaningful primarily as the second argument to
-@code{define} (and @code{pushdef}), and is silently converted to an
-empty string in many other contexts.
-
-The macro @code{defn} is recognized only with parameters.
-@end deffn
-
-Its normal use is best understood through an example, which shows how to
-rename @code{undefine} to @code{zap}:
-
-@example
-define(`zap', defn(`undefine'))
-@result{}
-zap(`undefine')
-@result{}
-undefine(`zap')
-@result{}undefine(zap)
-@end example
-
-In this way, @code{defn} can be used to copy macro definitions, and also
-definitions of builtin macros. Even if the original macro is removed,
-the other name can still be used to access the definition.
-
-The fact that macro definitions can be transferred also explains why you
-should use @code{$0}, rather than retyping a macro's name in its
-definition:
-
-@example
-define(`foo', `This is `$0'')
-@result{}
-define(`bar', defn(`foo'))
-@result{}
-bar
-@result{}This is bar
-@end example
-
-Macros used as string variables should be referred through @code{defn},
-to avoid unwanted expansion of the text:
-
-@example
-define(`string', `The macro dnl is very useful
-')
-@result{}
-string
-@result{}The macro@w{ }
-defn(`string')
-@result{}The macro dnl is very useful
-@result{}
-@end example
-
-@cindex rescanning
-However, it is important to remember that @code{m4} rescanning is purely
-textual. If an unbalanced end-quote string occurs in a macro
-definition, the rescan will see that embedded quote as the termination
-of the quoted string, and the remainder of the macro's definition will
-be rescanned unquoted. Thus it is a good idea to avoid unbalanced
-end-quotes in macro definitions or arguments to macros.
-
-@example
-define(`foo', a'a)
-@result{}
-define(`a', `A')
-@result{}
-define(`echo', `$@@')
-@result{}
-foo
-@result{}A'A
-defn(`foo')
-@result{}aA'
-echo(foo)
-@result{}AA'
-@end example
-
-On the other hand, it is possible to exploit the fact that @code{defn}
-can concatenate multiple macros prior to the rescanning phase, in order
-to join the definitions of macros that, in isolation, have unbalanced
-quotes. This is particularly useful when one has used several macros to
-accumulate text that M4 should rescan as a whole. In the example below,
-note how the use of @code{defn} on @code{l} in isolation opens a string,
-which is not closed until the next line; but used on @code{l} and
-@code{r} together results in nested quoting.
-
-@example
-define(`l', `<[>')define(`r', `<]>')
-@result{}
-changequote(`[', `]')
-@result{}
-defn([l])defn([r])
-])
-@result{}<[>]defn([r])
-@result{})
-defn([l], [r])
-@result{}<[>][<]>
-@end example
-
-@cindex builtins, special tokens
-@cindex tokens, builtin macro
-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.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 GNU M4 versions, as well
-as other @code{m4} implementations, vary on how such tokens are treated.
-
-@example
-$ @kbd{m4 -d}
-defn(`defn')
-@result{}
-define(defn(`divnum'), `cannot redefine a builtin token')
-@error{}m4:stdin:2: warning: define: invalid macro name ignored
-@result{}
-divnum
-@result{}0
-len(defn(`divnum'))
-@result{}0
-define(`echo', `$@@')
-@result{}
-define(`mydivnum', shift(echo(`', defn(`divnum'))))
-@result{}
-mydivnum
-@result{}0
-define(`', `empty-$1')
-@result{}
-defn(defn(`divnum'))
-@error{}m4:stdin:9: warning: defn: invalid macro name ignored
-@result{}
-pushdef(defn(`divnum'), `oops')
-@error{}m4:stdin:10: warning: pushdef: invalid macro name ignored
-@result{}
-traceon(defn(`divnum'))
-@error{}m4:stdin:11: warning: traceon: invalid macro name ignored
-@result{}
-indir(defn(`divnum'), `string')
-@error{}m4:stdin:12: warning: indir: invalid macro name ignored
-@result{}
-indir(`', `string')
-@result{}empty-string
-traceoff(defn(`divnum'))
-@error{}m4:stdin:14: warning: traceoff: invalid macro name ignored
-@result{}
-popdef(defn(`divnum'))
-@error{}m4:stdin:15: warning: popdef: invalid macro name ignored
-@result{}
-dumpdef(defn(`divnum'))
-@error{}m4:stdin:16: warning: dumpdef: invalid macro name ignored
-@result{}
-undefine(defn(`divnum'))
-@error{}m4:stdin:17: warning: undefine: invalid macro name ignored
-@result{}
-dumpdef(`')
-@error{}:@tabchar{}`empty-$1'
-@result{}
-m4symbols(defn(`divnum'))
-@error{}m4:stdin:19: warning: m4symbols: invalid macro name ignored
-@result{}
-define(`foo', `define(`$1', $2)')dnl
-foo(`bar', defn(`divnum'))
-@result{}
-bar
-@result{}0
-@end example
-
-As of M4 1.6, @code{defn} can warn if @var{name} is not a macro, by
-using @code{debugmode} (@pxref{Debugmode}) or the command line option
-@option{-d} (@option{--debugmode}, @pxref{Debugging options, , Invoking
-m4}). Also, @code{defn} with multiple arguments can join text with
-builtin tokens. However, when defining a macro via @code{define} or
-@code{pushdef}, a warning is issued and the builtin token ignored if the
-builtin token does not occur in isolation. A future version of
-GNU M4 may lift this restriction.
-
-@example
-$ @kbd{m4 -d}
-defn(`foo')
-@error{}m4:stdin:1: warning: defn: undefined macro 'foo'
-@result{}
-debugmode(`-d')
-@result{}
-defn(`foo')
-@result{}
-define(`a', `A')define(`AA', `b')
-@result{}
-traceon(`defn', `define')
-@result{}
-defn(`a', `divnum', `a')
-@error{}m4trace: -1- defn(`a', `divnum', `a') -> ``A'<divnum>`A''
-@result{}AA
-define(`mydivnum', defn(`divnum', `divnum'))mydivnum
-@error{}m4trace: -2- defn(`divnum', `divnum') -> `<divnum><divnum>'
-@error{}m4:stdin:7: warning: define: cannot concatenate builtins
-@error{}m4trace: -1- define(`mydivnum', `<divnum><divnum>') -> `'
-@result{}
-traceoff(`defn', `define')dumpdef(`mydivnum')
-@error{}mydivnum:@tabchar{}`'
-@result{}
-define(`mydivnum', defn(`divnum')defn(`divnum'))mydivnum
-@error{}m4:stdin:9: warning: define: cannot concatenate builtins
-@result{}
-define(`mydivnum', defn(`divnum')`a')mydivnum
-@error{}m4:stdin:10: warning: define: cannot concatenate builtins
-@result{}A
-define(`mydivnum', `a'defn(`divnum'))mydivnum
-@error{}m4:stdin:11: warning: define: cannot concatenate builtins
-@result{}A
-define(`q', ``$@@'')
-@result{}
-define(`foo', q(`a', defn(`divnum')))foo
-@error{}m4:stdin:13: warning: define: cannot concatenate builtins
-@result{}a,
-ifdef(`foo', `yes', `no')
-@result{}yes
-@end example
-
-@node Pushdef
-@section Temporarily redefining macros
-
-@cindex macros, temporary redefinition of
-@cindex temporary redefinition of macros
-@cindex redefinition of macros, temporary
-@cindex definition stack
-@cindex pushdef stack
-@cindex stack, macro definition
-It is possible to redefine a macro temporarily, reverting to the
-previous definition at a later time. This is done with the builtins
-@code{pushdef} and @code{popdef}:
-
-@deffn {Builtin (m4)} pushdef (@var{name}, @ovar{expansion})
-@deffnx {Builtin (m4)} popdef (@var{name}@dots{})
-Analogous to @code{define} and @code{undefine}.
-
-These macros work in a stack-like fashion. A macro is temporarily
-redefined with @code{pushdef}, which replaces an existing definition of
-@var{name}, while saving the previous definition, before the new one is
-installed. If there is no previous definition, @code{pushdef} behaves
-exactly like @code{define}.
-
-If a macro has several definitions (of which only one is accessible),
-the topmost definition can be removed with @code{popdef}. If there is
-no previous definition, @code{popdef} behaves like @code{undefine}, and
-if there is no definition at all, the @samp{d} debug level controls
-whether a warning is issued (@pxref{Debugmode}).
-
-The expansion of both @code{pushdef} and @code{popdef} is void.
-The macros @code{pushdef} and @code{popdef} are recognized only with
-parameters.
-@end deffn
-
-@example
-define(`foo', `Expansion one.')
-@result{}
-foo
-@result{}Expansion one.
-pushdef(`foo', `Expansion two.')
-@result{}
-foo
-@result{}Expansion two.
-pushdef(`foo', `Expansion three.')
-@result{}
-pushdef(`foo', `Expansion four.')
-@result{}
-popdef(`foo')
-@result{}
-foo
-@result{}Expansion three.
-popdef(`foo', `foo')
-@result{}
-foo
-@result{}Expansion one.
-popdef(`foo')
-@result{}
-foo
-@result{}foo
-@end example
-
-If a macro with several definitions is redefined with @code{define}, the
-topmost definition is @emph{replaced} with the new definition. If it is
-removed with @code{undefine}, @emph{all} the definitions are removed,
-and not only the topmost one. However, POSIX allows other
-implementations that treat @code{define} as replacing an entire stack
-of definitions with a single new definition, so to be portable to other
-implementations, it may be worth explicitly using @code{popdef} and
-@code{pushdef} rather than relying on the GNU behavior of
-@code{define}.
-
-@example
-define(`foo', `Expansion one.')
-@result{}
-foo
-@result{}Expansion one.
-pushdef(`foo', `Expansion two.')
-@result{}
-foo
-@result{}Expansion two.
-define(`foo', `Second expansion two.')
-@result{}
-foo
-@result{}Second expansion two.
-undefine(`foo')
-@result{}
-foo
-@result{}foo
-@end example
-
-@cindex local variables
-@cindex variables, local
-Local variables within macros are made with @code{pushdef} and
-@code{popdef}. At the start of the macro a new definition is pushed,
-within the macro it is manipulated and at the end it is popped,
-revealing the former definition.
-
-It is possible to temporarily redefine a builtin with @code{pushdef}
-and @code{defn}.
-
-As of M4 1.6, @code{popdef} can warn if @var{name} is not a macro, by
-using @code{debugmode} (@pxref{Debugmode}) or the command line option
-@option{-d} (@option{--debugmode}, @pxref{Debugging options, , Invoking
-m4}).
-
-@example
-define(`a', `1')
-@result{}
-popdef
-@result{}popdef
-popdef(`a', `a')
-@error{}m4:stdin:3: warning: popdef: undefined macro 'a'
-@result{}
-debugmode(`-d')
-@result{}
-popdef(`a')
-@result{}
-@end example
-
-@node Renamesyms
-@section Renaming macros with regular expressions
-
-@cindex regular expressions
-@cindex macros, how to rename
-@cindex renaming macros
-@cindex GNU extensions
-Sometimes it is desirable to rename multiple symbols without having to
-use a long sequence of calls to @code{define}. The @code{renamesyms}
-builtin allows this:
-
-@deffn {Builtin (gnu)} renamesyms (@var{regexp}, @var{replacement}, @
- @ovar{resyntax})
-Global renaming of macros is done by @code{renamesyms}, which selects
-all macros with names that match @var{regexp}, and renames each match
-according to @var{replacement}. It is unspecified what happens if the
-rename causes multiple macros to map to the same name.
-@comment FIXME - right now, collisions cause a core dump on some platforms:
-@comment define(bar,1)define(baz,2)renamesyms(^ba., baa)dumpdef(`baa')
-
-If @var{resyntax} is given, the particular flavor of regular
-expression understood with respect to @var{regexp} can be changed from
-the current default. @xref{Changeresyntax}, for details of the values
-that can be given for this argument.
-
-A macro that does not have a name that matches @var{regexp} is left
-with its original name. If only part of the name matches, any part of
-the name that is not covered by @var{regexp} is copied to the
-replacement name. Whenever a match is found in the name, the search
-proceeds from the end of the match, so no character in the original
-name can be substituted twice. If @var{regexp} matches a string of
-zero length, the start position for the continued search is
-incremented to avoid infinite loops.
-
-Where a replacement is to be made, @var{replacement} replaces the
-matched text in the original name, with @samp{\@var{n}} substituted by
-the text matched by the @var{n}th parenthesized sub-expression of
-@var{regexp}, and @samp{\&} being the text matched by the entire
-regular expression.
-
-The expansion of @code{renamesyms} is void.
-The macro @code{renamesyms} is recognized only with parameters.
-This macro was added in M4 2.0.
-@end deffn
-
-The following example starts with a rename similar to the
-@option{--prefix-builtins} option (or @option{-P}), prefixing every
-macro with @code{m4_}. However, note that @option{-P} only renames M4
-builtin macros, even if other macros were defined previously, while
-@code{renamesyms} will rename any macros that match when it runs,
-including text macros. The rest of the example demonstrates the
-behavior of unanchored regular expressions in symbol renaming.
-
-@comment options: -Dfoo=bar -P
-@example
-$ @kbd{m4 -Dfoo=bar -P}
-foo
-@result{}bar
-m4_foo
-@result{}m4_foo
-m4_defn(`foo')
-@result{}bar
-@end example
-
-@example
-$ @kbd{m4}
-define(`foo', `bar')
-@result{}
-renamesyms(`^.*$', `m4_\&')
-@result{}
-foo
-@result{}foo
-m4_foo
-@result{}bar
-m4_defn(`m4_foo')
-@result{}bar
-m4_renamesyms(`f', `g')
-@result{}
-m4_igdeg(`m4_goo', `m4_goo')
-@result{}bar
-@end example
-
-If @var{resyntax} is given, @var{regexp} must be given according to
-the syntax chosen, though the default regular expression syntax
-remains unchanged for other invocations. Here is a more realistic
-example that performs a similar renaming on macros, except that it
-ignores macros with names that begin with @samp{_}, and avoids creating
-macros with names that begin with @samp{m4_m4}.
-
-@example
-renamesyms(`^[^_]\w*$', `m4_\&')
-@result{}
-m4_renamesyms(`^m4_m4(\w*)$', `m4_\1', `POSIX_EXTENDED')
-@result{}
-m4_wrap(__line__
-)
-@result{}
-^D
-@result{}3
-@end example
-
-When a symbol has multiple definitions, thanks to @code{pushdef}, the
-entire stack is renamed.
-
-@example
-pushdef(`foo', `1')pushdef(`foo', `2')
-@result{}
-renamesyms(`^foo$', `bar')
-@result{}
-bar
-@result{}2
-popdef(`bar')bar
-@result{}1
-popdef(`bar')bar
-@result{}bar
-@end example
-
-@node Indir
-@section Indirect call of macros
-
-@cindex indirect call of macros
-@cindex call of macros, indirect
-@cindex macros, indirect call of
-@cindex GNU extensions
-Any macro can be called indirectly with @code{indir}:
-
-@deffn {Builtin (gnu)} indir (@var{name}, @ovar{args@dots{}})
-Results in a call to the macro @var{name}, which is passed the rest of
-the arguments @var{args}. If @var{name} is not defined, the expansion
-is void, and the @samp{d} debug level controls whether a warning is
-issued (@pxref{Debugmode}).
-
-The macro @code{indir} is recognized only with parameters.
-@end deffn
-
-This can be used to call macros with computed or ``invalid''
-names (@code{define} allows such names to be defined):
-
-@example
-define(`$$internal$macro', `Internal macro (name `$0')')
-@result{}
-$$internal$macro
-@result{}$$internal$macro
-indir(`$$internal$macro')
-@result{}Internal macro (name $$internal$macro)
-@end example
-
-The point is, here, that larger macro packages can have private macros
-defined, that will not be called by accident. They can @emph{only} be
-called through the builtin @code{indir}.
-
-One other point to observe is that argument collection occurs before
-@code{indir} invokes @var{name}, so if argument collection changes the
-value of @var{name}, that will be reflected in the final expansion.
-This is different than the behavior when invoking macros directly,
-where the definition that was in effect before argument collection is
-used.
-
-@example
-$ @kbd{m4 -d}
-define(`f', `1')
-@result{}
-f(define(`f', `2'))
-@result{}1
-indir(`f', define(`f', `3'))
-@result{}3
-indir(`f', undefine(`f'))
-@error{}m4:stdin:4: warning: indir: undefined macro 'f'
-@result{}
-debugmode(`-d')
-@result{}
-indir(`f')
-@result{}
-@end example
-
-When handed the result of @code{defn} (@pxref{Defn}) as one of its
-arguments, @code{indir} defers to the invoked @var{name} for whether a
-token representing a builtin is recognized or flattened to the empty
-string.
-
-@example
-$ @kbd{m4 -d}
-indir(defn(`defn'), `divnum')
-@error{}m4:stdin:1: warning: indir: invalid macro name ignored
-@result{}
-indir(`define', defn(`defn'), `divnum')
-@error{}m4:stdin:2: warning: define: invalid macro name ignored
-@result{}
-indir(`define', `foo', defn(`divnum'))
-@result{}
-foo
-@result{}0
-indir(`divert', defn(`foo'))
-@error{}m4:stdin:5: warning: divert: empty string treated as 0
-@result{}
-@end example
-
-Warning messages issued on behalf of an indirect macro use an
-unambiguous representation of the macro name, using escape sequences
-similar to C strings, and with colons also quoted.
-
-@example
-define(`%%:\
-odd', defn(`divnum'))
-@result{}
-indir(`%%:\
-odd', `extra')
-@error{}m4:stdin:3: warning: %%\:\\\nodd: extra arguments ignored: 1 > 0
-@result{}0
-@end example
-
-@node Builtin
-@section Indirect call of builtins
-
-@cindex indirect call of builtins
-@cindex call of builtins, indirect
-@cindex builtins, indirect call of
-@cindex GNU extensions
-Builtin macros can be called indirectly with @code{builtin}:
-
-@deffn {Builtin (gnu)} builtin (@var{name}, @ovar{args@dots{}})
-@deffnx {Builtin (gnu)} builtin (@code{defn(`builtin')}, @var{name1})
-Results in a call to the builtin @var{name}, which is passed the
-rest of the arguments @var{args}. If @var{name} does not name a
-builtin, the expansion is void, and the @samp{d} debug level controls
-whether a warning is issued (@pxref{Debugmode}).
-
-As a special case, if @var{name} is exactly the special token
-representing the @code{builtin} macro, as obtained by @code{defn}
-(@pxref{Defn}), then @var{args} must consist of a single @var{name1},
-and the expansion is the special token representing the builtin macro
-named by @var{name1}.
-
-The macro @code{builtin} is recognized only with parameters.
-@end deffn
-
-This can be used even if @var{name} has been given another definition
-that has covered the original, or been undefined so that no macro
-maps to the builtin.
-
-@example
-pushdef(`define', `hidden')
-@result{}
-undefine(`undefine')
-@result{}
-define(`foo', `bar')
-@result{}hidden
-foo
-@result{}foo
-builtin(`define', `foo', defn(`divnum'))
-@result{}
-foo
-@result{}0
-builtin(`define', `foo', `BAR')
-@result{}
-foo
-@result{}BAR
-undefine(`foo')
-@result{}undefine(foo)
-foo
-@result{}BAR
-builtin(`undefine', `foo')
-@result{}
-foo
-@result{}foo
-@end example
-
-The @var{name} argument only matches the original name of the builtin,
-even when the @option{--prefix-builtins} option (or @option{-P},
-@pxref{Operation modes, , Invoking m4}) is in effect. This is different
-from @code{indir}, which only tracks current macro names.
-
-@comment options: -P
-@example
-$ @kbd{m4 -P}
-m4_builtin(`divnum')
-@result{}0
-m4_builtin(`m4_divnum')
-@error{}m4:stdin:2: warning: m4_builtin: undefined builtin 'm4_divnum'
-@result{}
-m4_indir(`divnum')
-@error{}m4:stdin:3: warning: m4_indir: undefined macro 'divnum'
-@result{}
-m4_indir(`m4_divnum')
-@result{}0
-m4_debugmode(`-d')
-@result{}
-m4_builtin(`m4_divnum')
-@result{}
-@end example
-
-Note that @code{indir} and @code{builtin} can be used to invoke builtins
-without arguments, even when they normally require parameters to be
-recognized; but it will provoke a warning, and the expansion will behave
-as though empty strings had been passed as the required arguments.
-
-@example
-builtin
-@result{}builtin
-builtin()
-@error{}m4:stdin:2: warning: builtin: undefined builtin ''
-@result{}
-builtin(`builtin')
-@error{}m4:stdin:3: warning: builtin: too few arguments: 0 < 1
-@result{}
-builtin(`builtin',)
-@error{}m4:stdin:4: warning: builtin: undefined builtin ''
-@result{}
-builtin(`builtin', ``'
-')
-@error{}m4:stdin:5: warning: builtin: undefined builtin '`\'\n'
-@result{}
-indir(`index')
-@error{}m4:stdin:7: warning: index: too few arguments: 0 < 2
-@result{}0
-@end example
-
-Normally, once a builtin macro is undefined, the only way to retrieve
-its functionality is by defining a new macro that expands to
-@code{builtin} under the hood. But this extra layer of expansion is
-slightly inefficient, not to mention the fact that it is not robust to
-changes in the current quoting scheme due to @code{changequote}
-(@pxref{Changequote}). On the other hand, defining a macro to the
-special token produced by @code{defn} (@pxref{Defn}) is very efficient,
-and avoids the need for quoting within the macro definition; but
-@code{defn} only works if the desired macro is already defined by some
-other name. So @code{builtin} provides a special case where it is
-possible to retrieve the same special token representing a builtin as
-what @code{defn} would provide, were the desired macro still defined.
-This feature is activated by passing @code{defn(`builtin')} as the first
-argument to builtin. Normally, passing a special token representing a
-macro as @var{name} results in a warning and an empty expansion, but in
-this case, if the second argument @var{name1} names a valid builtin,
-there is no warning and the expansion is the appropriate special
-token. In fact, with just the @code{builtin} macro accessible, it is
-possible to reconstitute the entire startup state of @code{m4}.
-
-In the example below, compare the number of macro invocations performed
-by @code{defn1} and @code{defn2}, and the differences once quoting is
-changed.
-
-@example
-$ @kbd{m4 -d}
-undefine(`defn')
-@result{}
-define(`foo', `bar')
-@result{}
-define(`defn1', `builtin(`defn', $@@)')
-@result{}
-define(`defn2', builtin(builtin(`defn', `builtin'), `defn'))
-@result{}
-dumpdef(`defn1', `defn2')
-@error{}defn1:@tabchar{}`builtin(`defn', $@@)'
-@error{}defn2:@tabchar{}<defn>
-@result{}
-traceon
-@result{}
-defn1(`foo')
-@error{}m4trace: -1- defn1(`foo') -> `builtin(`defn', `foo')'
-@error{}m4trace: -1- builtin(`defn', `foo') -> ``bar''
-@result{}bar
-defn2(`foo')
-@error{}m4trace: -1- defn2(`foo') -> ``bar''
-@result{}bar
-traceoff
-@error{}m4trace: -1- traceoff -> `'
-@result{}
-changequote(`[', `]')
-@result{}
-defn1([foo])
-@error{}m4:stdin:11: warning: builtin: undefined builtin '`defn\''
-@result{}
-defn2([foo])
-@result{}bar
-define([defn1], [builtin([defn], $@@)])
-@result{}
-defn1([foo])
-@result{}bar
-changequote
-@result{}
-defn1(`foo')
-@error{}m4:stdin:16: warning: builtin: undefined builtin '[defn]'
-@result{}
-@end example
-
-@node M4symbols
-@section Getting the defined macro names
-
-@cindex macro names, listing
-@cindex listing macro names
-@cindex currently defined macros
-@cindex GNU extensions
-The name of the currently defined macros can be accessed by
-@code{m4symbols}:
-
-@deffn {Builtin (gnu)} m4symbols (@ovar{names@dots{}})
-Without arguments, @code{m4symbols} expands to a sorted list of quoted
-strings, separated by commas. This contrasts with @code{dumpdef}
-(@pxref{Dumpdef}), whose output cannot be accessed by @code{m4}
-programs.
-
-When given arguments, @code{m4symbols} returns the sorted subset of the
-@var{names} currently defined, and silently ignores the rest.
-This macro was added in M4 2.0.
-@end deffn
-
-@example
-m4symbols(`ifndef', `ifdef', `define', `undef')
-@result{}define,ifdef
-@end example
-
-@node Conditionals
-@chapter Conditionals, loops, and recursion
-
-Macros, expanding to plain text, perhaps with arguments, are not quite
-enough. We would like to have macros expand to different things, based
-on decisions taken at run-time. For that, we need some kind of conditionals.
-Also, we would like to have some kind of loop construct, so we could do
-something a number of times, or while some condition is true.
-
-@menu
-* Ifdef:: Testing if a macro is defined
-* Ifelse:: If-else construct, or multibranch
-* Shift:: Recursion in @code{m4}
-* Forloop:: Iteration by counting
-* Foreach:: Iteration by list contents
-* Stacks:: Working with definition stacks
-* Composition:: Building macros with macros
-@end menu
-
-@node Ifdef
-@section Testing if a macro is defined
-
-@cindex conditionals
-There are two different builtin conditionals in @code{m4}. The first is
-@code{ifdef}:
-
-@deffn {Builtin (m4)} ifdef (@var{name}, @var{string-1}, @ovar{string-2})
-If @var{name} is defined as a macro, @code{ifdef} expands to
-@var{string-1}, otherwise to @var{string-2}. If @var{string-2} is
-omitted, it is taken to be the empty string (according to the normal
-rules).
-
-The macro @code{ifdef} is recognized only with parameters.
-@end deffn
-
-@example
-ifdef(`foo', ``foo' is defined', ``foo' is not defined')
-@result{}foo is not defined
-define(`foo', `')
-@result{}
-ifdef(`foo', ``foo' is defined', ``foo' is not defined')
-@result{}foo is defined
-ifdef(`no_such_macro', `yes', `no', `extra argument')
-@error{}m4:stdin:4: warning: ifdef: extra arguments ignored: 4 > 3
-@result{}no
-@end example
-
-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.
-
-@example
-define(`', `empty')
-@result{}
-ifdef(defn(`defn'), `yes', `no')
-@error{}m4:stdin:2: warning: ifdef: invalid macro name ignored
-@result{}no
-define(`foo', ifdef(`divnum', defn(`divnum'), `undefined'))
-@result{}
-foo
-@result{}0
-@end example
-
-@node Ifelse
-@section If-else construct, or multibranch
-
-@cindex comparing strings
-@cindex discarding input
-@cindex input, discarding
-The other conditional, @code{ifelse}, is much more powerful. It can be
-used as a way to introduce a long comment, as an if-else construct, or
-as a multibranch, depending on the number of arguments supplied:
-
-@deffn {Builtin (m4)} ifelse (@var{comment})
-@deffnx {Builtin (m4)} ifelse (@var{string-1}, @var{string-2}, @var{equal}, @
- @ovar{not-equal})
-@deffnx {Builtin (m4)} ifelse (@var{string-1}, @var{string-2}, @var{equal-1}, @
- @var{string-3}, @var{string-4}, @var{equal-2}, @dots{}, @ovar{not-equal})
-Used with only one argument, the @code{ifelse} simply discards it and
-produces no output.
-
-If called with three or four arguments, @code{ifelse} expands into
-@var{equal}, if @var{string-1} and @var{string-2} are equal (character
-for character), otherwise it expands to @var{not-equal}. A final fifth
-argument is ignored, after triggering a warning.
-
-If called with six or more arguments, and @var{string-1} and
-@var{string-2} are equal, @code{ifelse} expands into @var{equal-1},
-otherwise the first three arguments are discarded and the processing
-starts again.
-
-The macro @code{ifelse} is recognized only with parameters.
-@end deffn
-
-Using only one argument is a common @code{m4} idiom for introducing a
-block comment, as an alternative to repeatedly using @code{dnl}. This
-special usage is recognized by GNU @code{m4}, so that in this
-case, the warning about missing arguments is never triggered.
-
-@example
-ifelse(`some comments')
-@result{}
-ifelse(`foo', `bar')
-@error{}m4:stdin:2: warning: ifelse: too few arguments: 2 < 3
-@result{}
-@end example
-
-Using three or four arguments provides decision points.
-
-@example
-ifelse(`foo', `bar', `true')
-@result{}
-ifelse(`foo', `foo', `true')
-@result{}true
-define(`foo', `bar')
-@result{}
-ifelse(foo, `bar', `true', `false')
-@result{}true
-ifelse(foo, `foo', `true', `false')
-@result{}false
-@end example
-
-@cindex macro, blind
-@cindex blind macro
-Notice how the first argument was used unquoted; it is common to compare
-the expansion of a macro with a string. With this macro, you can now
-reproduce the behavior of blind builtins, where the macro is recognized
-only with arguments.
-
-@example
-define(`foo', `ifelse(`$#', `0', ``$0'', `arguments:$#')')
-@result{}
-foo
-@result{}foo
-foo()
-@result{}arguments:1
-foo(`a', `b', `c')
-@result{}arguments:3
-@end example
-
-For an example of a way to make defining blind macros easier, see
-@ref{Composition}.
-
-@cindex multibranches
-@cindex switch statement
-@cindex case statement
-The macro @code{ifelse} can take more than four arguments. If given more
-than four arguments, @code{ifelse} works like a @code{case} or @code{switch}
-statement in traditional programming languages. If @var{string-1} and
-@var{string-2} are equal, @code{ifelse} expands into @var{equal-1}, otherwise
-the procedure is repeated with the first three arguments discarded. This
-calls for an example:
-
-@example
-ifelse(`foo', `bar', `third', `gnu', `gnats')
-@error{}m4:stdin:1: warning: ifelse: extra arguments ignored: 5 > 4
-@result{}gnu
-ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth')
-@result{}
-ifelse(`foo', `bar', `third', `gnu', `gnats', `sixth', `seventh')
-@result{}seventh
-ifelse(`foo', `bar', `3', `gnu', `gnats', `6', `7', `8')
-@error{}m4:stdin:4: warning: ifelse: extra arguments ignored: 8 > 7
-@result{}7
-@end example
-
-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.
-
-@example
-ifelse(defn(`defn'), `', `yes', `no')
-@result{}no
-ifelse(defn(`defn'), defn(`divnum'), `yes', `no')
-@result{}no
-ifelse(defn(`defn'), defn(`defn'), `yes', `no')
-@result{}yes
-define(`foo', ifelse(`', `', defn(`divnum')))
-@result{}
-foo
-@result{}0
-@end example
-
-Naturally, the normal case will be slightly more advanced than these
-examples. A common use of @code{ifelse} is in macros implementing loops
-of various kinds.
-
-@node Shift
-@section Recursion in @code{m4}
-
-@cindex recursive macros
-@cindex macros, recursive
-There is no direct support for loops in @code{m4}, but macros can be
-recursive. There is no limit on the number of recursion levels, other
-than those enforced by your hardware and operating system.
-
-@cindex loops
-Loops can be programmed using recursion and the conditionals described
-previously.
-
-There is a builtin macro, @code{shift}, which can, among other things,
-be used for iterating through the actual arguments to a macro:
-
-@deffn {Builtin (m4)} shift (@var{arg1}, @dots{})
-Takes any number of arguments, and expands to all its arguments except
-@var{arg1}, separated by commas, with each argument quoted.
-
-The macro @code{shift} is recognized only with parameters.
-@end deffn
-
-@example
-shift
-@result{}shift
-shift(`bar')
-@result{}
-shift(`foo', `bar', `baz')
-@result{}bar,baz
-@end example
-
-An example of the use of @code{shift} is this macro:
-
-@cindex reversing arguments
-@cindex arguments, reversing
-@deffn Composite reverse (@dots{})
-Takes any number of arguments, and reverses their order.
-@end deffn
-
-It is implemented as:
-
-@example
-define(`reverse', `ifelse(`$#', `0', , `$#', `1', ``$1'',
- `reverse(shift($@@)), `$1'')')
-@result{}
-reverse
-@result{}
-reverse(`foo')
-@result{}foo
-reverse(`foo', `bar', `gnats', `and gnus')
-@result{}and gnus, gnats, bar, foo
-@end example
-
-While not a very interesting macro, it does show how simple loops can be
-made with @code{shift}, @code{ifelse} and recursion. It also shows
-that @code{shift} is usually used with @samp{$@@}. Another example of
-this is an implementation of a short-circuiting conditional operator.
-
-@cindex short-circuiting conditional
-@cindex conditional, short-circuiting
-@deffn Composite cond (@var{test-1}, @var{string-1}, @var{equal-1}, @
- @ovar{test-2}, @ovar{string-2}, @ovar{equal-2}, @dots{}, @ovar{not-equal})
-Similar to @code{ifelse}, where an equal comparison between the first
-two strings results in the third, otherwise the first three arguments
-are discarded and the process repeats. The difference is that each
-@var{test-<n>} is expanded only when it is encountered. This means that
-every third argument to @code{cond} is normally given one more level of
-quoting than the corresponding argument to @code{ifelse}.
-@end deffn
-
-Here is the implementation of @code{cond}, along with a demonstration of
-how it can short-circuit the side effects in @code{side}. Notice how
-all the unquoted side effects happen regardless of how many comparisons
-are made with @code{ifelse}, compared with only the relevant effects
-with @code{cond}.
-
-@example
-define(`cond',
-`ifelse(`$#', `1', `$1',
- `ifelse($1, `$2', `$3',
- `$0(shift(shift(shift($@@))))')')')dnl
-define(`side', `define(`counter', incr(counter))$1')dnl
-define(`example1',
-`define(`counter', `0')dnl
-ifelse(side(`$1'), `yes', `one comparison: ',
- side(`$1'), `no', `two comparisons: ',
- side(`$1'), `maybe', `three comparisons: ',
- `side(`default answer: ')')counter')dnl
-define(`example2',
-`define(`counter', `0')dnl
-cond(`side(`$1')', `yes', `one comparison: ',
- `side(`$1')', `no', `two comparisons: ',
- `side(`$1')', `maybe', `three comparisons: ',
- `side(`default answer: ')')counter')dnl
-example1(`yes')
-@result{}one comparison: 3
-example1(`no')
-@result{}two comparisons: 3
-example1(`maybe')
-@result{}three comparisons: 3
-example1(`feeling rather indecisive today')
-@result{}default answer: 4
-example2(`yes')
-@result{}one comparison: 1
-example2(`no')
-@result{}two comparisons: 2
-example2(`maybe')
-@result{}three comparisons: 3
-example2(`feeling rather indecisive today')
-@result{}default answer: 4
-@end example
-
-@cindex joining arguments
-@cindex arguments, joining
-@cindex concatenating arguments
-Another common task that requires iteration is joining a list of
-arguments into a single string.
-
-@deffn Composite join (@ovar{separator}, @ovar{args@dots{}})
-@deffnx Composite joinall (@ovar{separator}, @ovar{args@dots{}})
-Generate a single-quoted string, consisting of each @var{arg} separated
-by @var{separator}. While @code{joinall} always outputs a
-@var{separator} between arguments, @code{join} avoids the
-@var{separator} for an empty @var{arg}.
-@end deffn
-
-Here are some examples of its usage, based on the implementation
-@file{m4-@value{VERSION}/@/doc/examples/@/join.m4} distributed in this
-package:
-
-@comment examples
-@example
-$ @kbd{m4 -I examples}
-include(`join.m4')
-@result{}
-join,join(`-'),join(`-', `'),join(`-', `', `')
-@result{},,,
-joinall,joinall(`-'),joinall(`-', `'),joinall(`-', `', `')
-@result{},,,-
-join(`-', `1')
-@result{}1
-join(`-', `1', `2', `3')
-@result{}1-2-3
-join(`', `1', `2', `3')
-@result{}123
-join(`-', `', `1', `', `', `2', `')
-@result{}1-2
-joinall(`-', `', `1', `', `', `2', `')
-@result{}-1---2-
-join(`,', `1', `2', `3')
-@result{}1,2,3
-define(`nargs', `$#')dnl
-nargs(join(`,', `1', `2', `3'))
-@result{}1
-@end example
-
-Examining the implementation shows some interesting points about several
-m4 programming idioms.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`join.m4')dnl
-@result{}divert(`-1')
-@result{}# join(sep, args) - join each non-empty ARG into a single
-@result{}# string, with each element separated by SEP
-@result{}define(`join',
-@result{}`ifelse(`$#', `2', ``$2'',
-@result{} `ifelse(`$2', `', `', ``$2'_')$0(`$1', shift(shift($@@)))')')
-@result{}define(`_join',
-@result{}`ifelse(`$#$2', `2', `',
-@result{} `ifelse(`$2', `', `', ``$1$2'')$0(`$1', shift(shift($@@)))')')
-@result{}# joinall(sep, args) - join each ARG, including empty ones,
-@result{}# into a single string, with each element separated by SEP
-@result{}define(`joinall', ``$2'_$0(`$1', shift($@@))')
-@result{}define(`_joinall',
-@result{}`ifelse(`$#', `2', `', ``$1$3'$0(`$1', shift(shift($@@)))')')
-@result{}divert`'dnl
-@end example
-
-First, notice that this implementation creates helper macros
-@code{_join} and @code{_joinall}. This division of labor makes it
-easier to output the correct number of @var{separator} instances:
-@code{join} and @code{joinall} are responsible for the first argument,
-without a separator, while @code{_join} and @code{_joinall} are
-responsible for all remaining arguments, always outputting a separator
-when outputting an argument.
-
-Next, observe how @code{join} decides to iterate to itself, because the
-first @var{arg} was empty, or to output the argument and swap over to
-@code{_join}. If the argument is non-empty, then the nested
-@code{ifelse} results in an unquoted @samp{_}, which is concatenated
-with the @samp{$0} to form the next macro name to invoke. The
-@code{joinall} implementation is simpler since it does not have to
-suppress empty @var{arg}; it always executes once then defers to
-@code{_joinall}.
-
-Another important idiom is the idea that @var{separator} is reused for
-each iteration. Each iteration has one less argument, but rather than
-discarding @samp{$1} by iterating with @code{$0(shift($@@))}, the macro
-discards @samp{$2} by using @code{$0(`$1', shift(shift($@@)))}.
-
-Next, notice that it is possible to compare more than one condition in a
-single @code{ifelse} test. The test of @samp{$#$2} against @samp{2}
-allows @code{_join} to iterate for two separate reasons---either there
-are still more than two arguments, or there are exactly two arguments
-but the last argument is not empty.
-
-Finally, notice that these macros require exactly two arguments to
-terminate recursion, but that they still correctly result in empty
-output when given no @var{args} (i.e., zero or one macro argument). On
-the first pass when there are too few arguments, the @code{shift}
-results in no output, but leaves an empty string to serve as the
-required second argument for the second pass. Put another way,
-@samp{`$1', shift($@@)} is not the same as @samp{$@@}, since only the
-former guarantees at least two arguments.
-
-@cindex quote manipulation
-@cindex manipulating quotes
-Sometimes, a recursive algorithm requires adding quotes to each element,
-or treating multiple arguments as a single element:
-
-@deffn Composite quote (@dots{})
-@deffnx Composite dquote (@dots{})
-@deffnx Composite dquote_elt (@dots{})
-Takes any number of arguments, and adds quoting. With @code{quote},
-only one level of quoting is added, effectively removing whitespace
-after commas and turning multiple arguments into a single string. With
-@code{dquote}, two levels of quoting are added, one around each element,
-and one around the list. And with @code{dquote_elt}, two levels of
-quoting are added around each element.
-@end deffn
-
-An actual implementation of these three macros is distributed as
-@file{m4-@value{VERSION}/@/doc/examples/@/quote.m4} in this package.
-First, let's examine their usage:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`quote.m4')
-@result{}
--quote-dquote-dquote_elt-
-@result{}----
--quote()-dquote()-dquote_elt()-
-@result{}--`'-`'-
--quote(`1')-dquote(`1')-dquote_elt(`1')-
-@result{}-1-`1'-`1'-
--quote(`1', `2')-dquote(`1', `2')-dquote_elt(`1', `2')-
-@result{}-1,2-`1',`2'-`1',`2'-
-define(`n', `$#')dnl
--n(quote(`1', `2'))-n(dquote(`1', `2'))-n(dquote_elt(`1', `2'))-
-@result{}-1-1-2-
-dquote(dquote_elt(`1', `2'))
-@result{}``1'',``2''
-dquote_elt(dquote(`1', `2'))
-@result{}``1',`2''
-@end example
-
-The last two lines show that when given two arguments, @code{dquote}
-results in one string, while @code{dquote_elt} results in two. Now,
-examine the implementation. Note that @code{quote} and
-@code{dquote_elt} make decisions based on their number of arguments, so
-that when called without arguments, they result in nothing instead of a
-quoted empty string; this is so that it is possible to distinguish
-between no arguments and an empty first argument. @code{dquote}, on the
-other hand, results in a string no matter what, since it is still
-possible to tell whether it was invoked without arguments based on the
-resulting string.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`quote.m4')dnl
-@result{}divert(`-1')
-@result{}# quote(args) - convert args to single-quoted string
-@result{}define(`quote', `ifelse(`$#', `0', `', ``$*'')')
-@result{}# dquote(args) - convert args to quoted list of quoted strings
-@result{}define(`dquote', ``$@@'')
-@result{}# dquote_elt(args) - convert args to list of double-quoted strings
-@result{}define(`dquote_elt', `ifelse(`$#', `0', `', `$#', `1', ```$1''',
-@result{} ```$1'',$0(shift($@@))')')
-@result{}divert`'dnl
-@end example
-
-It is worth pointing out that @samp{quote(@var{args})} is more efficient
-than @samp{joinall(`,', @var{args})} for producing the same output.
-
-@cindex nine arguments, more than
-@cindex more than nine arguments
-@cindex arguments, more than nine
-One more useful macro based on @code{shift} allows portably selecting
-an arbitrary argument (usually greater than the ninth argument), without
-relying on the GNU extension of multi-digit arguments
-(@pxref{Arguments}).
-
-@deffn Composite argn (@var{n}, @dots{})
-Expands to argument @var{n} out of the remaining arguments. @var{n}
-must be a positive number. Usually invoked as
-@samp{argn(`@var{n}',$@@)}.
-@end deffn
-
-It is implemented as:
-
-@example
-define(`argn', `ifelse(`$1', 1, ``$2'',
- `argn(decr(`$1'), shift(shift($@@)))')')
-@result{}
-argn(`1', `a')
-@result{}a
-define(`foo', `argn(`11', $@@)')
-@result{}
-foo(`a', `b', `c', `d', `e', `f', `g', `h', `i', `j', `k', `l')
-@result{}k
-@end example
-
-@node Forloop
-@section Iteration by counting
-
-@cindex for loops
-@cindex loops, counting
-@cindex counting loops
-Here is an example of a loop macro that implements a simple for loop.
-
-@deffn Composite forloop (@var{iterator}, @var{start}, @var{end}, @var{text})
-Takes the name in @var{iterator}, which must be a valid macro name, and
-successively assign it each integer value from @var{start} to @var{end},
-inclusive. For each assignment to @var{iterator}, append @var{text} to
-the expansion of the @code{forloop}. @var{text} may refer to
-@var{iterator}. Any definition of @var{iterator} prior to this
-invocation is restored.
-@end deffn
-
-It can, for example, be used for simple counting:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`forloop.m4')
-@result{}
-forloop(`i', `1', `8', `i ')
-@result{}1 2 3 4 5 6 7 8@w{ }
-@end example
-
-For-loops can be nested, like:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`forloop.m4')
-@result{}
-forloop(`i', `1', `4', `forloop(`j', `1', `8', ` (i, j)')
-')
-@result{} (1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8)
-@result{} (2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8)
-@result{} (3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8)
-@result{} (4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8)
-@result{}
-@end example
-
-The implementation of the @code{forloop} macro is fairly
-straightforward. The @code{forloop} macro itself is simply a wrapper,
-which saves the previous definition of the first argument, calls the
-internal macro @code{@w{_forloop}}, and re-establishes the saved
-definition of the first argument.
-
-The macro @code{@w{_forloop}} expands the fourth argument once, and
-tests to see if the iterator has reached the final value. If it has
-not finished, it increments the iterator (using the predefined macro
-@code{incr}, @pxref{Incr}), and recurses.
-
-Here is an actual implementation of @code{forloop}, distributed as
-@file{m4-@value{VERSION}/@/doc/examples/@/forloop.m4} in this package:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`forloop.m4')dnl
-@result{}divert(`-1')
-@result{}# forloop(var, from, to, stmt) - simple version
-@result{}define(`forloop', `pushdef(`$1', `$2')_forloop($@@)popdef(`$1')')
-@result{}define(`_forloop',
-@result{} `$4`'ifelse($1, `$3', `', `define(`$1', incr($1))$0($@@)')')
-@result{}divert`'dnl
-@end example
-
-Notice the careful use of quotes. Certain macro arguments are left
-unquoted, each for its own reason. Try to find out @emph{why} these
-arguments are left unquoted, and see what happens if they are quoted.
-(As presented, these two macros are useful but not very robust for
-general use. They lack even basic error handling for cases like
-@var{start} less than @var{end}, @var{end} not numeric, or
-@var{iterator} not being a macro name. See if you can improve these
-macros; or @pxref{Improved forloop, , Answers}).
-
-@node Foreach
-@section Iteration by list contents
-
-@cindex for each loops
-@cindex loops, list iteration
-@cindex iterating over lists
-Here is an example of a loop macro that implements list iteration.
-
-@deffn Composite foreach (@var{iterator}, @var{paren-list}, @var{text})
-@deffnx Composite foreachq (@var{iterator}, @var{quote-list}, @var{text})
-Takes the name in @var{iterator}, which must be a valid macro name, and
-successively assign it each value from @var{paren-list} or
-@var{quote-list}. In @code{foreach}, @var{paren-list} is a
-comma-separated list of elements contained in parentheses. In
-@code{foreachq}, @var{quote-list} is a comma-separated list of elements
-contained in a quoted string. For each assignment to @var{iterator},
-append @var{text} to the overall expansion. @var{text} may refer to
-@var{iterator}. Any definition of @var{iterator} prior to this
-invocation is restored.
-@end deffn
-
-As an example, this displays each word in a list inside of a sentence,
-using an implementation of @code{foreach} distributed as
-@file{m4-@value{VERSION}/@/doc/examples/@/foreach.m4}, and @code{foreachq}
-in @file{m4-@value{VERSION}/@/doc/examples/@/foreachq.m4}.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`foreach.m4')
-@result{}
-foreach(`x', (foo, bar, foobar), `Word was: x
-')dnl
-@result{}Word was: foo
-@result{}Word was: bar
-@result{}Word was: foobar
-include(`foreachq.m4')
-@result{}
-foreachq(`x', `foo, bar, foobar', `Word was: x
-')dnl
-@result{}Word was: foo
-@result{}Word was: bar
-@result{}Word was: foobar
-@end example
-
-It is possible to be more complex; each element of the @var{paren-list}
-or @var{quote-list} can itself be a list, to pass as further arguments
-to a helper macro. This example generates a shell case statement:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`foreach.m4')
-@result{}
-define(`_case', ` $1)
- $2=" $1";;
-')dnl
-define(`_cat', `$1$2')dnl
-case $`'1 in
-@result{}case $1 in
-foreach(`x', `(`(`a', `vara')', `(`b', `varb')', `(`c', `varc')')',
- `_cat(`_case', x)')dnl
-@result{} a)
-@result{} vara=" a";;
-@result{} b)
-@result{} varb=" b";;
-@result{} c)
-@result{} varc=" c";;
-esac
-@result{}esac
-@end example
-
-The implementation of the @code{foreach} macro is a bit more involved;
-it is a wrapper around two helper macros. First, @code{@w{_arg1}} is
-needed to grab the first element of a list. Second,
-@code{@w{_foreach}} implements the recursion, successively walking
-through the original list. Here is a simple implementation of
-@code{foreach}:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`foreach.m4')dnl
-@result{}divert(`-1')
-@result{}# foreach(x, (item_1, item_2, ..., item_n), stmt)
-@result{}# parenthesized list, simple version
-@result{}define(`foreach', `pushdef(`$1')_foreach($@@)popdef(`$1')')
-@result{}define(`_arg1', `$1')
-@result{}define(`_foreach', `ifelse(`$2', `()', `',
-@result{} `define(`$1', _arg1$2)$3`'$0(`$1', (shift$2), `$3')')')
-@result{}divert`'dnl
-@end example
-
-Unfortunately, that implementation is not robust to macro names as list
-elements. Each iteration of @code{@w{_foreach}} is stripping another
-layer of quotes, leading to erratic results if list elements are not
-already fully expanded. The first cut at implementing @code{foreachq}
-takes this into account. Also, when using quoted elements in a
-@var{paren-list}, the overall list must be quoted. A @var{quote-list}
-has the nice property of requiring fewer characters to create a list
-containing the same quoted elements. To see the difference between the
-two macros, we attempt to pass double-quoted macro names in a list,
-expecting the macro name on output after one layer of quotes is removed
-during list iteration and the final layer removed during the final
-rescan:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-define(`a', `1')define(`b', `2')define(`c', `3')
-@result{}
-include(`foreach.m4')
-@result{}
-include(`foreachq.m4')
-@result{}
-foreach(`x', `(``a'', ``(b'', ``c)'')', `x
-')
-@result{}1
-@result{}(2)1
-@result{}
-@result{}, x
-@result{})
-foreachq(`x', ```a'', ``(b'', ``c)''', `x
-')dnl
-@result{}a
-@result{}(b
-@result{}c)
-@end example
-
-Obviously, @code{foreachq} did a better job; here is its implementation:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`foreachq.m4')dnl
-@result{}include(`quote.m4')dnl
-@result{}divert(`-1')
-@result{}# foreachq(x, `item_1, item_2, ..., item_n', stmt)
-@result{}# quoted list, simple version
-@result{}define(`foreachq', `pushdef(`$1')_foreachq($@@)popdef(`$1')')
-@result{}define(`_arg1', `$1')
-@result{}define(`_foreachq', `ifelse(quote($2), `', `',
-@result{} `define(`$1', `_arg1($2)')$3`'$0(`$1', `shift($2)', `$3')')')
-@result{}divert`'dnl
-@end example
-
-Notice that @code{@w{_foreachq}} had to use the helper macro
-@code{quote} defined earlier (@pxref{Shift}), to ensure that the
-embedded @code{ifelse} call does not go haywire if a list element
-contains a comma. Unfortunately, this implementation of @code{foreachq}
-has its own severe flaw. Whereas the @code{foreach} implementation was
-linear, this macro is quadratic in the number of list elements, and is
-much more likely to trip up the limit set by the command line option
-@option{--nesting-limit} (or @option{-L}, @pxref{Limits control, ,
-Invoking m4}). Additionally, this implementation does not expand
-@samp{defn(`@var{iterator}')} very well, when compared with
-@code{foreach}.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`foreach.m4')include(`foreachq.m4')
-@result{}
-foreach(`name', `(`a', `b')', ` defn(`name')')
-@result{} a b
-foreachq(`name', ``a', `b'', ` defn(`name')')
-@result{} _arg1(`a', `b') _arg1(shift(`a', `b'))
-@end example
-
-It is possible to have robust iteration with linear behavior and sane
-@var{iterator} contents for either list style. See if you can learn
-from the best elements of both of these implementations to create robust
-macros (or @pxref{Improved foreach, , Answers}).
-
-@node Stacks
-@section Working with definition stacks
-
-@cindex definition stack
-@cindex pushdef stack
-@cindex stack, macro definition
-Thanks to @code{pushdef}, manipulation of a stack is an intrinsic
-operation in @code{m4}. Normally, only the topmost definition in a
-stack is important, but sometimes, it is desirable to manipulate the
-entire definition stack.
-
-@deffn Composite stack_foreach (@var{macro}, @var{action})
-@deffnx Composite stack_foreach_lifo (@var{macro}, @var{action})
-For each of the @code{pushdef} definitions associated with @var{macro},
-invoke the macro @var{action} with a single argument of that definition.
-@code{stack_foreach} visits the oldest definition first, while
-@code{stack_foreach_lifo} visits the current definition first.
-@var{action} should not modify or dereference @var{macro}. There are a
-few special macros, such as @code{defn}, which cannot be used as the
-@var{macro} parameter.
-@end deffn
-
-A sample implementation of these macros is distributed in the file
-@file{m4-@value{VERSION}/@/doc/examples/@/stack.m4}.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`stack.m4')
-@result{}
-pushdef(`a', `1')pushdef(`a', `2')pushdef(`a', `3')
-@result{}
-define(`show', ``$1'
-')
-@result{}
-stack_foreach(`a', `show')dnl
-@result{}1
-@result{}2
-@result{}3
-stack_foreach_lifo(`a', `show')dnl
-@result{}3
-@result{}2
-@result{}1
-@end example
-
-Now for the implementation. Note the definition of a helper macro,
-@code{_stack_reverse}, which destructively swaps the contents of one
-stack of definitions into the reverse order in the temporary macro
-@samp{tmp-$1}. By calling the helper twice, the original order is
-restored back into the macro @samp{$1}; since the operation is
-destructive, this explains why @samp{$1} must not be modified or
-dereferenced during the traversal. The caller can then inject
-additional code to pass the definition currently being visited to
-@samp{$2}. The choice of helper names is intentional; since @samp{-} is
-not valid as part of a macro name, there is no risk of conflict with a
-valid macro name, and the code is guaranteed to use @code{defn} where
-necessary. Finally, note that any macro used in the traversal of a
-@code{pushdef} stack, such as @code{pushdef} or @code{defn}, cannot be
-handled by @code{stack_foreach}, since the macro would temporarily be
-undefined during the algorithm.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`stack.m4')dnl
-@result{}divert(`-1')
-@result{}# stack_foreach(macro, action)
-@result{}# Invoke ACTION with a single argument of each definition
-@result{}# from the definition stack of MACRO, starting with the oldest.
-@result{}define(`stack_foreach',
-@result{}`_stack_reverse(`$1', `tmp-$1')'dnl
-@result{}`_stack_reverse(`tmp-$1', `$1', `$2(defn(`$1'))')')
-@result{}# stack_foreach_lifo(macro, action)
-@result{}# Invoke ACTION with a single argument of each definition
-@result{}# from the definition stack of MACRO, starting with the newest.
-@result{}define(`stack_foreach_lifo',
-@result{}`_stack_reverse(`$1', `tmp-$1', `$2(defn(`$1'))')'dnl
-@result{}`_stack_reverse(`tmp-$1', `$1')')
-@result{}define(`_stack_reverse',
-@result{}`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0($@@)')')
-@result{}divert`'dnl
-@end example
-
-@node Composition
-@section Building macros with macros
-
-@cindex macro composition
-@cindex composing macros
-Since m4 is a macro language, it is possible to write macros that
-can build other macros. First on the list is a way to automate the
-creation of blind macros.
-
-@cindex macro, blind
-@cindex blind macro
-@deffn Composite define_blind (@var{name}, @ovar{value})
-Defines @var{name} as a blind macro, such that @var{name} will expand to
-@var{value} only when given explicit arguments. @var{value} should not
-be the result of @code{defn} (@pxref{Defn}). This macro is only
-recognized with parameters, and results in an empty string.
-@end deffn
-
-Defining a macro to define another macro can be a bit tricky. We want
-to use a literal @samp{$#} in the argument to the nested @code{define}.
-However, if @samp{$} and @samp{#} are adjacent in the definition of
-@code{define_blind}, then it would be expanded as the number of
-arguments to @code{define_blind} rather than the intended number of
-arguments to @var{name}. The solution is to pass the difficult
-characters through extra arguments to a helper macro
-@code{_define_blind}. When composing macros, it is a common idiom to
-need a helper macro to concatenate text that forms parameters in the
-composed macro, rather than interpreting the text as a parameter of the
-composing macro.
-
-As for the limitation against using @code{defn}, there are two reasons.
-If a macro was previously defined with @code{define_blind}, then it can
-safely be renamed to a new blind macro using plain @code{define}; using
-@code{define_blind} to rename it just adds another layer of
-@code{ifelse}, occupying memory and slowing down execution. And if a
-macro is a builtin, then it would result in an attempt to define a macro
-consisting of both text and a builtin token; this is not supported, and
-the builtin token is flattened to an empty string.
-
-With that explanation, here's the definition, and some sample usage.
-Notice that @code{define_blind} is itself a blind macro.
-
-@example
-$ @kbd{m4 -d}
-define(`define_blind', `ifelse(`$#', `0', ``$0'',
-`_$0(`$1', `$2', `$'`#', `$'`0')')')
-@result{}
-define(`_define_blind', `define(`$1',
-`ifelse(`$3', `0', ``$4'', `$2')')')
-@result{}
-define_blind
-@result{}define_blind
-define_blind(`foo', `arguments were $*')
-@result{}
-foo
-@result{}foo
-foo(`bar')
-@result{}arguments were bar
-define(`blah', defn(`foo'))
-@result{}
-blah
-@result{}blah
-blah(`a', `b')
-@result{}arguments were a,b
-defn(`blah')
-@result{}ifelse(`$#', `0', ``$0'', `arguments were $*')
-@end example
-
-@cindex currying arguments
-@cindex argument currying
-Another interesting composition tactic is argument @dfn{currying}, or
-factoring a macro that takes multiple arguments for use in a context
-that provides exactly one argument.
-
-@deffn Composite curry (@var{macro}, @dots{})
-Expand to a macro call that takes exactly one argument, then appends
-that argument to the original arguments and invokes @var{macro} with the
-resulting list of arguments.
-@end deffn
-
-A demonstration of currying makes the intent of this macro a little more
-obvious. The macro @code{stack_foreach} mentioned earlier is an example
-of a context that provides exactly one argument to a macro name. But
-coupled with currying, we can invoke @code{reverse} with two arguments
-for each definition of a macro stack. This example uses the file
-@file{m4-@value{VERSION}/@/doc/examples/@/curry.m4} included in the
-distribution.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`curry.m4')include(`stack.m4')
-@result{}
-define(`reverse', `ifelse(`$#', `0', , `$#', `1', ``$1'',
- `reverse(shift($@@)), `$1'')')
-@result{}
-pushdef(`a', `1')pushdef(`a', `2')pushdef(`a', `3')
-@result{}
-stack_foreach(`a', `:curry(`reverse', `4')')
-@result{}:1, 4:2, 4:3, 4
-curry(`curry', `reverse', `1')(`2')(`3')
-@result{}3, 2, 1
-@end example
-
-Now for the implementation. Notice how @code{curry} leaves off with a
-macro name but no open parenthesis, while still in the middle of
-collecting arguments for @samp{$1}. The macro @code{_curry} is the
-helper macro that takes one argument, then adds it to the list and
-finally supplies the closing parenthesis. The use of a comma inside the
-@code{shift} call allows currying to also work for a macro that takes
-one argument, although it often makes more sense to invoke that macro
-directly rather than going through @code{curry}.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`curry.m4')dnl
-@result{}divert(`-1')
-@result{}# curry(macro, args)
-@result{}# Expand to a macro call that takes one argument, then invoke
-@result{}# macro(args, extra).
-@result{}define(`curry', `$1(shift($@@,)_$0')
-@result{}define(`_curry', ``$1')')
-@result{}divert`'dnl
-@end example
-
-Unfortunately, with M4 1.4.x, @code{curry} is unable to handle builtin
-tokens, which are silently flattened to the empty string when passed
-through another text macro. The following example demonstrates a usage
-of @code{curry} that works in M4 1.6, but is not portable to earlier
-versions:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`curry.m4')
-@result{}
-curry(`define', `mylen')(defn(`len'))
-@result{}
-mylen(`abc')
-@result{}3
-@end example
-
-@cindex renaming macros
-@cindex copying macros
-@cindex macros, copying
-Putting the last few concepts together, it is possible to copy or rename
-an entire stack of macro definitions.
-
-@deffn Composite copy (@var{source}, @var{dest})
-@deffnx Composite rename (@var{source}, @var{dest})
-Ensure that @var{dest} is undefined, then define it to the same stack of
-definitions currently in @var{source}. @code{copy} leaves @var{source}
-unchanged, while @code{rename} undefines @var{source}. There are only a
-few macros, such as @code{copy} or @code{defn}, which cannot be copied
-via this macro.
-@end deffn
-
-The implementation is relatively straightforward (although since it uses
-@code{curry}, it is unable to copy builtin macros when used with M4
-1.4.x. See if you can design a portable version that works across all
-M4 versions, or @pxref{Improved copy, , Answers}).
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`curry.m4')include(`stack.m4')
-@result{}
-define(`rename', `copy($@@)undefine(`$1')')dnl
-define(`copy', `ifdef(`$2', `errprint(`$2 already defined
-')m4exit(`1')',
- `stack_foreach(`$1', `curry(`pushdef', `$2')')')')dnl
-pushdef(`a', `1')pushdef(`a', defn(`divnum'))pushdef(`a', `2')
-@result{}
-copy(`a', `b')
-@result{}
-rename(`b', `c')
-@result{}
-a b c
-@result{}2 b 2
-popdef(`a', `c')a c
-@result{}0 0
-popdef(`a', `c')a c
-@result{}1 1
-@end example
-
-@node Debugging
-@chapter How to debug macros and input
-
-@cindex debugging macros
-@cindex macros, debugging
-When writing macros for @code{m4}, they often do not work as intended on
-the first try (as is the case with most programming languages).
-Fortunately, there is support for macro debugging in @code{m4}.
-
-@menu
-* Dumpdef:: Displaying macro definitions
-* Trace:: Tracing macro calls
-* Debugmode:: Controlling debugging options
-* Debuglen:: Limiting debug output
-* Debugfile:: Saving debugging output
-@end menu
-
-@node Dumpdef
-@section Displaying macro definitions
-
-@cindex displaying macro definitions
-@cindex macros, displaying definitions
-@cindex definitions, displaying macro
-@cindex standard error, output to
-If you want to see what a name expands into, you can use the builtin
-@code{dumpdef}:
-
-@deffn {Builtin (m4)} dumpdef (@ovar{name@dots{}})
-Accepts any number of arguments. If called without any arguments, it
-displays the definitions of all known names, otherwise it displays the
-definitions of each @var{name} given, sorted by name. If a @var{name}
-is undefined, the @samp{d} debug level controls whether a warning is
-issued (@pxref{Debugmode}). Likewise, the @samp{o} debug level controls
-whether the output is issued to standard error or the current debug
-file (@pxref{Debugfile}).
-
-The expansion of @code{dumpdef} is void.
-@end deffn
-
-@example
-$ @kbd{m4 -d}
-define(`foo', `Hello world.')
-@result{}
-dumpdef(`foo')
-@error{}foo:@tabchar{}`Hello world.'
-@result{}
-dumpdef(`define')
-@error{}define:@tabchar{}<define>
-@result{}
-@end example
-
-The last example shows how builtin macros definitions are displayed.
-The definition that is dumped corresponds to what would occur if the
-macro were to be called at that point, even if other definitions are
-still live due to redefining a macro during argument collection.
-
-@example
-$ @kbd{m4 -d}
-pushdef(`f', ``$0'1')pushdef(`f', ``$0'2')
-@result{}
-f(popdef(`f')dumpdef(`f'))
-@error{}f:@tabchar{}``$0'1'
-@result{}f2
-f(popdef(`f')dumpdef(`f'))
-@error{}m4:stdin:3: warning: dumpdef: undefined macro 'f'
-@result{}f1
-debugmode(`-d')
-@result{}
-dumpdef(`f')
-@result{}
-@end example
-
-@xref{Debugmode}, for information on how the @samp{m}, @samp{q}, and
-@samp{s} flags affect the details of the display. Remember, the
-@samp{q} flag is implied when the @option{--debug} option (@option{-d},
-@pxref{Debugging options, , Invoking m4}) is used in the command line
-without arguments. Also, @option{--debuglen} (@pxref{Debuglen}) can affect
-output, by truncating longer strings (but not builtin and module names).
-
-@comment options: -ds -l3
-@example
-$ @kbd{m4 -ds -l 3}
-pushdef(`foo', `1 long string')
-@result{}
-pushdef(`foo', defn(`divnum'))
-@result{}
-pushdef(`foo', `3')
-@result{}
-debugmode(`+m')
-@result{}
-dumpdef(`foo', `dnl', `indir', `__gnu__')
-@error{}__gnu__:@tabchar{}@{gnu@}
-@error{}dnl:@tabchar{}<dnl>@{m4@}
-@error{}foo:@tabchar{}3, <divnum>@{m4@}, 1 l...
-@error{}indir:@tabchar{}<indir>@{gnu@}
-@result{}
-debugmode(`-ms')debugmode(`+q')
-@result{}
-dumpdef(`foo')
-@error{}foo:@tabchar{}`3'
-@result{}
-@end example
-
-@node Trace
-@section Tracing macro calls
-
-@cindex tracing macro expansion
-@cindex macro expansion, tracing
-@cindex expansion, tracing macro
-@cindex standard error, output to
-It is possible to trace macro calls and expansions through the builtins
-@code{traceon} and @code{traceoff}:
-
-@deffn {Builtin (m4)} traceon (@ovar{names@dots{}})
-@deffnx {Builtin (m4)} traceoff (@ovar{names@dots{}})
-When called without any arguments, @code{traceon} and @code{traceoff}
-will turn tracing on and off, respectively, for all macros, identical to
-using the @samp{t} flag of @code{debugmode} (@pxref{Debugmode}).
-
-When called with arguments, only the macros listed in @var{names} are
-affected, whether or not they are currently defined. A macro's
-expansion will be traced if global tracing is on, or if the individual
-macro tracing flag is set; to avoid tracing a macro, both the global
-flag and the macro must have tracing off.
-
-The expansion of @code{traceon} and @code{traceoff} is void.
-@end deffn
-
-Whenever a traced macro is called and the arguments have been collected,
-the call is displayed. If the expansion of the macro call is not void,
-the expansion can be displayed after the call. The output is printed
-to the current debug file (defaulting to standard error,
-@pxref{Debugfile}).
-
-@example
-$ @kbd{m4 -d}
-define(`foo', `Hello World.')
-@result{}
-define(`echo', `$@@')
-@result{}
-traceon(`foo', `echo')
-@result{}
-foo
-@error{}m4trace: -1- foo -> `Hello World.'
-@result{}Hello World.
-echo(`gnus', `and gnats')
-@error{}m4trace: -1- echo(`gnus', `and gnats') -> ``gnus',`and gnats''
-@result{}gnus,and gnats
-@end example
-
-The number between dashes is the depth of the expansion. It is one most
-of the time, signifying an expansion at the outermost level, but it
-increases when macro arguments contain unquoted macro calls. The
-maximum number that will appear between dashes is controlled by the
-option @option{--nesting-limit} (or @option{-L}, @pxref{Limits control,
-, Invoking m4}). Additionally, the option @option{--trace} (or
-@option{-t}) can be used to invoke @code{traceon(@var{name})} before
-parsing input.
-
-@comment options: -d-V -L3 -tifelse
-@comment status: 1
-@example
-$ @kbd{m4 -L 3 -t ifelse}
-ifelse(`one level')
-@error{}m4trace: -1- ifelse
-@result{}
-ifelse(ifelse(ifelse(`three levels')))
-@error{}m4trace: -3- ifelse
-@error{}m4trace: -2- ifelse
-@error{}m4trace: -1- ifelse
-@result{}
-ifelse(ifelse(ifelse(ifelse(`four levels'))))
-@error{}m4:stdin:3: recursion limit of 3 exceeded, use -L<N> to change it
-@end example
-
-Tracing by name is an attribute that is preserved whether the macro is
-defined or not. This allows the selection of macros to trace before
-those macros are defined.
-
-@example
-$ @kbd{m4 -d}
-traceoff(`foo')
-@result{}
-traceon(`foo')
-@result{}
-foo
-@result{}foo
-defn(`foo')
-@error{}m4:stdin:4: warning: defn: undefined macro 'foo'
-@result{}
-undefine(`foo')
-@error{}m4:stdin:5: warning: undefine: undefined macro 'foo'
-@result{}
-pushdef(`foo')
-@result{}
-popdef(`foo')
-@result{}
-popdef(`foo')
-@error{}m4:stdin:8: warning: popdef: undefined macro 'foo'
-@result{}
-define(`foo', `bar')
-@result{}
-foo
-@error{}m4trace: -1- foo -> `bar'
-@result{}bar
-undefine(`foo')
-@result{}
-ifdef(`foo', `yes', `no')
-@result{}no
-indir(`foo')
-@error{}m4:stdin:13: warning: indir: undefined macro 'foo'
-@result{}
-define(`foo', `blah')
-@result{}
-foo
-@error{}m4trace: -1- foo -> `blah'
-@result{}blah
-@end example
-
-Tracing even works on builtins. However, @code{defn} (@pxref{Defn})
-does not transfer tracing status.
-
-@example
-$ @kbd{m4 -d}
-traceon(`traceon')
-@result{}
-traceon(`traceoff')
-@error{}m4trace: -1- traceon(`traceoff') -> `'
-@result{}
-traceoff(`traceoff')
-@error{}m4trace: -1- traceoff(`traceoff') -> `'
-@result{}
-traceoff(`traceon')
-@result{}
-traceon(`eval', `m4_divnum')
-@result{}
-define(`m4_eval', defn(`eval'))
-@result{}
-define(`m4_divnum', defn(`divnum'))
-@result{}
-eval(divnum)
-@error{}m4trace: -1- eval(`0') -> `0'
-@result{}0
-m4_eval(m4_divnum)
-@error{}m4trace: -2- m4_divnum -> `0'
-@result{}0
-@end example
-
-As of GNU M4 2.0, named macro tracing is independent of global
-tracing status; calling @code{traceoff} without arguments turns off the
-global trace flag, but does not turn off tracing for macros where
-tracing was requested by name. Likewise, calling @code{traceon} without
-arguments will affect tracing of macros that are not defined yet. This
-behavior matches traditional implementations of @code{m4}.
-
-@example
-$ @kbd{m4 -d}
-traceon
-@result{}
-define(`foo', `bar')
-@error{}m4trace: -1- define(`foo', `bar') -> `'
-@result{}
-foo # traced, even though foo was not defined at traceon
-@error{}m4trace: -1- foo -> `bar'
-@result{}bar # traced, even though foo was not defined at traceon
-traceoff(`foo')
-@error{}m4trace: -1- traceoff(`foo') -> `'
-@result{}
-foo # traced, since global tracing is still on
-@error{}m4trace: -1- foo -> `bar'
-@result{}bar # traced, since global tracing is still on
-traceon(`foo')
-@error{}m4trace: -1- traceon(`foo') -> `'
-@result{}
-traceoff
-@error{}m4trace: -1- traceoff -> `'
-@result{}
-foo # traced, since foo is now traced by name
-@error{}m4trace: -1- foo -> `bar'
-@result{}bar # traced, since foo is now traced by name
-traceoff(`foo')
-@result{}
-foo # untraced
-@result{}bar # untraced
-@end example
-
-However, GNU M4 prior to 2.0 had slightly different
-semantics, where @code{traceon} without arguments only affected symbols
-that were defined at that moment, and @code{traceoff} without arguments
-stopped all tracing, even when tracing was requested by macro name. The
-addition of the macro @code{m4symbols} (@pxref{M4symbols}) in 2.0 makes it
-possible to write a file that approximates the older semantics
-regardless of which version of GNU M4 is in use.
-
-@comment options: -d-V
-@example
-$ @kbd{m4}
-ifdef(`m4symbols',
- `define(`traceon', `ifelse(`$#', `0', `builtin(`traceon', m4symbols)',
- `builtin(`traceon', $@@)')')dnl
-define(`traceoff', `ifelse(`$#', `0',
- `builtin(`traceoff')builtin(`traceoff', m4symbols)',
- `builtin(`traceoff', $@@)')')')dnl
-define(`a', `1')
-@result{}
-traceon # called before b is defined, so b is not traced
-@result{} # called before b is defined, so b is not traced
-define(`b', `2')
-@error{}m4trace: -1- define
-@result{}
-a b
-@error{}m4trace: -1- a
-@result{}1 2
-traceon(`b')
-@error{}m4trace: -1- traceon
-@error{}m4trace: -1- ifelse
-@error{}m4trace: -1- builtin
-@result{}
-a b
-@error{}m4trace: -1- a
-@error{}m4trace: -1- b
-@result{}1 2
-traceoff # stops tracing b, even though it was traced by name
-@error{}m4trace: -1- traceoff
-@error{}m4trace: -1- ifelse
-@error{}m4trace: -1- builtin
-@error{}m4trace: -2- m4symbols
-@error{}m4trace: -1- builtin
-@result{} # stops tracing b, even though it was traced by name
-a b
-@result{}1 2
-@end example
-
-@xref{Debugmode}, for information on controlling the details of the
-display. The format of the trace output is not specified by
-POSIX, and varies between implementations of @code{m4}.
-
-Starting with M4 1.6, tracing also works via @code{indir}
-(@pxref{Indir}). However, since tracing is an attribute tracked by
-macro names, and @code{builtin} bypasses macro names (@pxref{Builtin}),
-it is not possible for @code{builtin} to trace which subsidiary builtin
-it invokes. If you are worried about tracking all invocations of a
-given builtin, you should also trace @code{builtin}, or enable global
-tracing (the @samp{t} debug level, @pxref{Debugmode}).
-
-@example
-$ @kbd{m4 -d}
-define(`my_defn', defn(`defn'))undefine(`defn')
-@result{}
-define(`foo', `bar')traceon(`foo', `defn', `my_defn')
-@result{}
-foo
-@error{}m4trace: -1- foo -> `bar'
-@result{}bar
-indir(`foo')
-@error{}m4trace: -1- foo -> `bar'
-@result{}bar
-my_defn(`foo')
-@error{}m4trace: -1- my_defn(`foo') -> ``bar''
-@result{}bar
-indir(`my_defn', `foo')
-@error{}m4trace: -1- my_defn(`foo') -> ``bar''
-@result{}bar
-builtin(`defn', `foo')
-@result{}bar
-debugmode(`+cxt')
-@result{}
-builtin(`defn', builtin(`shift', `', `foo'))
-@error{}m4trace: -1- id 12: builtin ... = <builtin>
-@error{}m4trace: -2- id 13: builtin ... = <builtin>
-@error{}m4trace: -2- id 13: builtin(`shift', `', `foo') -> ``foo''
-@error{}m4trace: -1- id 12: builtin(`defn', `foo') -> ``bar''
-@result{}bar
-indir(`my_defn', indir(`shift', `', `foo'))
-@error{}m4trace: -1- id 14: indir ... = <indir>
-@error{}m4trace: -2- id 15: indir ... = <indir>
-@error{}m4trace: -2- id 15: shift ... = <shift>
-@error{}m4trace: -2- id 15: shift(`', `foo') -> ``foo''
-@error{}m4trace: -2- id 15: indir(`shift', `', `foo') -> ``foo''
-@error{}m4trace: -1- id 14: my_defn ... = <defn>
-@error{}m4trace: -1- id 14: my_defn(`foo') -> ``bar''
-@error{}m4trace: -1- id 14: indir(`my_defn', `foo') -> ``bar''
-@result{}bar
-@end example
-
-@node Debugmode
-@section Controlling debugging options
-
-@cindex controlling debugging output
-@cindex debugging output, controlling
-The @option{--debug} option to @code{m4} (also spelled
-@option{--debugmode} or @option{-d}, @pxref{Debugging options, ,
-Invoking m4}) controls the amount of details presented in three
-categories of output. Trace output is requested by @code{traceon}
-(@pxref{Trace}), and each line is prefixed by @samp{m4trace:} in
-relation to a macro invocation. Debug output tracks useful events not
-associated with a macro invocation, and each line is prefixed by
-@samp{m4debug:}. Finally, @code{dumpdef} (@pxref{Dumpdef}) output is
-affected, with no prefix added to the output lines.
-
-The @var{flags} following the option can be one or more of the
-following:
-
-@table @code
-@item a
-In trace output, show the actual arguments that were collected before
-invoking the macro. Arguments are subject to length truncation
-specified by @code{debuglen} (@pxref{Debuglen}).
-
-@item c
-In trace output, show an additional line for each macro call, when the
-macro is seen, but before the arguments are collected, and show the
-definition of the macro that will be used for the expansion. By
-default, only one line is printed, after all arguments are collected and
-the expansion determined. The definition is subject to length
-truncation specified by @code{debuglen} (@pxref{Debuglen}). This is
-often used with the @samp{x} flag.
-
-@item d
-Output a warning on any attempt to dereference an undefined macro via
-@code{builtin}, @code{defn}, @code{dumpdef}, @code{indir},
-@code{popdef}, or @code{undefine}. Note that @code{indef},
-@code{m4symbols},
-@code{traceon}, and @code{traceoff} do not dereference undefined macros.
-Like any other warning, the warnings enabled by this flag go to standard
-error regardless of the current @code{debugfile} setting, and will
-change exit status if the command line option @option{--fatal-warnings}
-was specified. This flag is useful in diagnosing spelling mistakes in
-macro names. It is enabled by default when neither @option{--debug} nor
-@option{--fatal-warnings} are specified on the command line.
-
-@item e
-In trace output, show the expansion of each macro call. The expansion
-is subject to length truncation specified by @code{debuglen}
-(@pxref{Debuglen}).
-
-@item f
-In debug and trace output, include the name of the current input file in
-the output line.
-
-@item i
-In debug output, print a message each time the current input file is
-changed.
-
-@item l
-In debug and trace output, include the current input line number in the
-output line.
-
-@item m
-In debug output, print a message each time a module is manipulated
-(@pxref{Modules}). In trace output when the @samp{c} flag is in effect,
-and in dumpdef output, follow builtin macros with their module name,
-surrounded by braces (@samp{@{@}}).
-
-@item o
-Output @code{dumpdef} data to standard error instead of the current
-debug file. This can be useful when post-processing trace output, where
-interleaving dumpdef and trace output can cause ambiguities.
-
-@item p
-In debug output, print a message when a named file is found through the
-path search mechanism (@pxref{Search Path}), giving the actual file name
-used.
-
-@item q
-In trace and dumpdef output, quote actual arguments and macro expansions
-in the display with the current quotes. This is useful in connection
-with the @samp{a} and @samp{e} flags above.
-
-@item s
-In dumpdef output, show the entire stack of definitions associated with
-a symbol via @code{pushdef}.
-
-@item t
-In trace output, trace all macro calls made in this invocation of
-@code{m4}. This is equivalent to using @code{traceon} without
-arguments.
-
-@item x
-In trace output, add a unique `macro call id' to each line of the trace
-output. This is useful in connection with the @samp{c} flag above, to
-match where a macro is first recognized with where it is finally
-expanded, in spite of intermediate expansions that occur while
-collecting arguments. It can also be used in isolation to determine how
-many macros have been expanded.
-
-@item V
-A shorthand for all of the above flags.
-@end table
-
-As special cases, if @var{flags} starts with a @samp{+}, the named flags
-are enabled without impacting other flags, and if it starts with a
-@samp{-}, the named flags are disabled without impacting other flags.
-Without either of these starting characters, @var{flags} simply replaces
-the previous setting.
-@comment FIXME - should we accept usage like debugmode(+fl-q)? Also,
-@comment should we add debugmode(?) which expands to the current
-@comment enabled flags, and debugmode(e?) which expands to e if e is
-@comment currently enabled?
-
-If no flags are specified with the @option{--debug} option, the default is
-@samp{+adeq}. Many examples in this manual show their output using
-default flags.
-
-@cindex GNU extensions
-There is a builtin macro @code{debugmode}, which allows on-the-fly control of
-the debugging output format:
-
-@deffn {Builtin (gnu)} debugmode (@ovar{flags})
-The argument @var{flags} should be a subset of the letters listed above.
-If no argument is present, all debugging flags are cleared (as if
-@var{flags} were an explicit @samp{-V}). With an empty argument, the
-most common flags are enabled (as if @var{flags} were an explicit
-@samp{+adeq}). If an unknown flag is encountered, an error is issued.
-
-The expansion of @code{debugmode} is void.
-@end deffn
-
-@comment options: -d-V
-@example
-$ @kbd{m4}
-define(`foo', `FOO$1')
-@result{}
-traceon(`foo', `divnum')
-@result{}
-debugmode()dnl same as debugmode(`+adeq')
-foo
-@error{}m4trace: -1- foo -> `FOO'
-@result{}FOO
-debugmode(`V')debugmode(`-q')
-@error{}m4trace:stdin:5: -1- id 7: debugmode ... = <debugmode>@{gnu@}
-@error{}m4trace:stdin:5: -1- id 7: debugmode(`-q') -> `'
-@result{}
-foo(
-`BAR')
-@error{}m4trace:stdin:6: -1- id 8: foo ... = FOO$1
-@error{}m4trace:stdin:6: -1- id 8: foo(BAR) -> FOOBAR
-@result{}FOOBAR
-debugmode`'dnl same as debugmode(`-V')
-@error{}m4trace:stdin:8: -1- id 9: debugmode ... = <debugmode>@{gnu@}
-@error{}m4trace:stdin:8: -1- id 9: debugmode ->@w{ }
-foo
-@error{}m4trace: -1- foo
-@result{}FOO
-debugmode(`+clmx')
-@result{}
-foo(divnum)
-@error{}m4trace:11: -1- id 13: foo ... = FOO$1
-@error{}m4trace:11: -2- id 14: divnum ... = <divnum>@{m4@}
-@error{}m4trace:11: -2- id 14: divnum
-@error{}m4trace:11: -1- id 13: foo
-@result{}FOO0
-debugmode(`-m')
-@result{}
-@end example
-
-This example shows the effects of the debug flags that are not related
-to macro tracing.
-
-@comment examples
-@comment options: -dip
-@example
-$ @kbd{m4 -dip -I doc/examples}
-@error{}m4debug: input read from 'stdin'
-define(`foo', `m4wrap(`wrapped text
-')dnl')
-@result{}
-include(`incl.m4')dnl
-@error{}m4debug: path search for 'incl.m4' found 'doc/examples/incl.m4'
-@error{}m4debug: input read from 'doc/examples/incl.m4'
-@result{}Include file start
-@result{}Include file end
-@error{}m4debug: input reverted to stdin, line 3
-^D
-@error{}m4debug: input exhausted
-@error{}m4debug: input from m4wrap recursion level 1
-@result{}wrapped text
-@error{}m4debug: input from m4wrap exhausted
-@end example
-
-@node Debuglen
-@section Limiting debug output
-
-@cindex GNU extensions
-@cindex arglength
-@cindex debuglen
-@cindex limiting trace output length
-@cindex trace output, limiting length
-@cindex dumpdef output, limiting length
-When debugging, sometimes it is desirable to reduce the clutter of
-arbitrary-length strings, because the prefix carries enough information
-to understand the issues. The builtin macro @code{debuglen}, along with
-the command line option counterpart @option{--debuglen} (or @option{-l},
-@pxref{Debugging options, , Invoking m4}), allow on-the-fly control of
-debugging string lengths:
-
-@deffn {Builtin (gnu)} debuglen (@var{len})
-The argument @var{len} is an integer that controls how much of
-arbitrary-length strings should be output during trace and dumpdef
-output. If specified to a non-zero value, then strings longer than that
-length are truncated, and @samp{...} included in the output to show that
-truncation took place. A warning is issued if @var{len} cannot be
-parsed as an integer.
-@comment FIXME - make this understand an optional suffix, similar to how
-@comment --debuglen does. Also, we need a section documenting scaling
-@comment suffixes.
-@comment FIXME - should we allow len to be `?', meaning expand to the
-@comment current value?
-
-The macro @code{debuglen} is recognized only with parameters.
-@end deffn
-
-The following example demonstrates the behavior of length truncation.
-Note that each argument and the final result are individually truncated.
-Also, the special tokens for builtin functions are not truncated.
-
-@comment options: -l6 -techo -tdefn
-@example
-$ @kbd{m4 -d -l 6 -t echo -t defn}
-debuglen(`oops')
-@error{}m4:stdin:1: warning: debuglen: non-numeric argument 'oops'
-@result{}
-define(`echo', `$@@')
-@result{}
-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...') -> `<changequote>'
-@error{}m4trace: -1- echo(<changequote>) -> ``<changequote>''
-@result{}
-debuglen
-@result{}debuglen
-debuglen(`0')
-@result{}
-echo(`long string')
-@error{}m4trace: -1- echo(`long string') -> ``long string''
-@result{}long string
-debuglen(`12')
-@result{}
-echo(`long string')
-@error{}m4trace: -1- echo(`long string') -> ``long string...'
-@result{}long string
-@end example
-
-@node Debugfile
-@section Saving debugging output
-
-@cindex saving debugging output
-@cindex debugging output, saving
-@cindex output, saving debugging
-@cindex GNU extensions
-Debug and tracing output can be redirected to files using either the
-@option{--debugfile} option to @code{m4} (@pxref{Debugging options, ,
-Invoking m4}), or with the builtin macro @code{debugfile}:
-
-@deffn {Builtin (gnu)} debugfile (@ovar{file})
-Send all further debug and trace output to @var{file}, opened in append
-mode. If @var{file} is the empty string, debug and trace output are
-discarded. If @code{debugfile} is called without any arguments, debug
-and trace output are sent to standard error. Output from @code{dumpdef}
-is sent to this file if the debug level @code{o} is not set
-(@pxref{Debugmode}). This does not affect
-warnings, error messages, or @code{errprint} output, which are
-always sent to standard error. If @var{file} cannot be opened, the
-current debug file is unchanged, and an error is issued.
-
-When the @option{--safer} option (@pxref{Operation modes, , Invoking
-m4}) is in effect, @var{file} must be empty or omitted, since otherwise
-an input file could cause the modification of arbitrary files.
-
-The expansion of @code{debugfile} is void.
-@end deffn
-
-@example
-$ @kbd{m4 -d}
-traceon(`divnum')
-@result{}
-divnum(`extra')
-@error{}m4:stdin:2: warning: divnum: extra arguments ignored: 1 > 0
-@error{}m4trace: -1- divnum(`extra') -> `0'
-@result{}0
-debugfile()
-@result{}
-divnum(`extra')
-@error{}m4:stdin:4: warning: divnum: extra arguments ignored: 1 > 0
-@result{}0
-debugfile
-@result{}
-divnum
-@error{}m4trace: -1- divnum -> `0'
-@result{}0
-@end example
-
-Although the @option{--safer} option cripples @code{debugfile} to a
-limited subset of capabilities, you may still use the @option{--debugfile}
-option from the command line with no restrictions.
-
-@comment options: --safer --debugfile=trace -tfoo -Dfoo=bar -d+l
-@comment status: 1
-@example
-$ @kbd{m4 --safer --debugfile trace -t foo -D foo=bar -daelq}
-foo # traced to `trace'
-@result{}bar # traced to `trace'
-debugfile(`file')
-@error{}m4:stdin:2: debugfile: disabled by --safer
-@result{}
-foo # traced to `trace'
-@result{}bar # traced to `trace'
-debugfile()
-@result{}
-foo # trace discarded
-@result{}bar # trace discarded
-debugfile
-@result{}
-foo # traced to stderr
-@error{}m4trace:7: -1- foo -> `bar'
-@result{}bar # traced to stderr
-undivert(`trace')dnl
-@result{}m4trace:1: -1- foo -> `bar'
-@result{}m4trace:3: -1- foo -> `bar'
-@end example
-
-Sometimes it is useful to post-process trace output, even though there
-is no standardized format for trace output. In this situation, forcing
-@code{dumpdef} to output to standard error instead of the default of the
-current debug file will avoid any ambiguities between the two types of
-output; it also allows debugging via @code{dumpdef} when debug output is
-discarded.
-
-@example
-$ @kbd{m4 -d}
-traceon(`divnum')
-@result{}
-divnum
-@error{}m4trace: -1- divnum -> `0'
-@result{}0
-dumpdef(`divnum')
-@error{}divnum:@tabchar{}<divnum>
-@result{}
-debugfile(`')
-@result{}
-divnum
-@result{}0
-dumpdef(`divnum')
-@result{}
-debugmode(`+o')
-@result{}
-divnum
-@result{}0
-dumpdef(`divnum')
-@error{}divnum:@tabchar{}<divnum>
-@result{}
-@end example
-
-@node Input Control
-@chapter Input control
-
-This chapter describes various builtin macros for controlling the input
-to @code{m4}.
-
-@menu
-* Dnl:: Deleting whitespace in input
-* Changequote:: Changing the quote characters
-* Changecom:: Changing the comment delimiters
-* Changeresyntax:: Changing the regular expression syntax
-* Changesyntax:: Changing the lexical structure of the input
-* M4wrap:: Saving text until end of input
-@end menu
-
-@node Dnl
-@section Deleting whitespace in input
-
-@cindex deleting whitespace in input
-@cindex discarding input
-@cindex input, discarding
-The builtin @code{dnl} stands for ``Discard to Next Line'':
-
-@deffn {Builtin (m4)} dnl
-All characters, up to and including the next newline, are discarded
-without performing any macro expansion. A warning is issued if the end
-of the file is encountered without a newline.
-
-The expansion of @code{dnl} is void.
-@end deffn
-
-It is often used in connection with @code{define}, to remove the
-newline that follows the call to @code{define}. Thus
-
-@example
-define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
-foo
-@result{}Macro foo.
-@end example
-
-The input up to and including the next newline is discarded, as opposed
-to the way comments are treated (@pxref{Comments}), when the command
-line option @option{--discard-comments} is not in effect
-(@pxref{Operation modes, , Invoking m4}).
-
-Usually, @code{dnl} is immediately followed by an end of line or some
-other whitespace. GNU @code{m4} will produce a warning diagnostic if
-@code{dnl} is followed by an open parenthesis. In this case, @code{dnl}
-will collect and process all arguments, looking for a matching close
-parenthesis. All predictable side effects resulting from this
-collection will take place. @code{dnl} will return no output. The
-input following the matching close parenthesis up to and including the
-next newline, on whatever line containing it, will still be discarded.
-
-@example
-dnl(`args are ignored, but side effects occur',
-define(`foo', `like this')) while this text is ignored: undefine(`foo')
-@error{}m4:stdin:1: warning: dnl: extra arguments ignored: 2 > 0
-See how `foo' was defined, foo?
-@result{}See how foo was defined, like this?
-@end example
-
-If the end of file is encountered without a newline character, a
-warning is issued and dnl stops consuming input.
-
-@example
-m4wrap(`m4wrap(`2 hi
-')0 hi dnl 1 hi')
-@result{}
-define(`hi', `HI')
-@result{}
-^D
-@error{}m4:stdin:1: warning: dnl: end of file treated as newline
-@result{}0 HI 2 HI
-@end example
-
-@node Changequote
-@section Changing the quote characters
-
-@cindex changing quote delimiters
-@cindex quote delimiters, changing
-@cindex delimiters, changing
-The default quote delimiters can be changed with the builtin
-@code{changequote}:
-
-@deffn {Builtin (m4)} changequote (@dvar{start, `}, @dvar{end, '})
-This sets @var{start} as the new begin-quote delimiter and @var{end} as
-the new end-quote delimiter. If both arguments are missing, the default
-quotes (@code{`} and @code{'}) are used. If @var{start} is void, then
-quoting is disabled. Otherwise, if @var{end} is missing or void, the
-default end-quote delimiter (@code{'}) is used. The quote delimiters
-can be of any length.
-
-The expansion of @code{changequote} is void.
-@end deffn
-
-@example
-changequote(`[', `]')
-@result{}
-define([foo], [Macro [foo].])
-@result{}
-foo
-@result{}Macro foo.
-@end example
-
-The quotation strings can safely contain eight-bit characters.
-If no single character is appropriate, @var{start} and @var{end} can be
-of any length. Other implementations cap the delimiter length to five
-characters, but GNU has no inherent limit.
-
-@example
-changequote(`[[[', `]]]')
-@result{}
-define([[[foo]]], [[[Macro [[[[[foo]]]]].]]])
-@result{}
-foo
-@result{}Macro [[foo]].
-@end example
-
-Calling @code{changequote} with @var{start} as the empty string will
-effectively disable the quoting mechanism, leaving no way to quote text.
-However, using an empty string is not portable, as some other
-implementations of @code{m4} revert to the default quoting, while others
-preserve the prior non-empty delimiter. If @var{start} is not empty,
-then an empty @var{end} will use the default end-quote delimiter of
-@samp{'}, as otherwise, it would be impossible to end a quoted string.
-Again, this is not portable, as some other @code{m4} implementations
-reuse @var{start} as the end-quote delimiter, while others preserve the
-previous non-empty value. Omitting both arguments restores the default
-begin-quote and end-quote delimiters; fortunately this behavior is
-portable to all implementations of @code{m4}.
-
-@example
-define(`foo', `Macro `FOO'.')
-@result{}
-changequote(`', `')
-@result{}
-foo
-@result{}Macro `FOO'.
-`foo'
-@result{}`Macro `FOO'.'
-changequote(`,)
-@result{}
-foo
-@result{}Macro FOO.
-@end example
-
-There is no way in @code{m4} to quote a string containing an unmatched
-begin-quote, except using @code{changequote} to change the current
-quotes.
-
-If the quotes should be changed from, say, @samp{[} to @samp{[[},
-temporary quote characters have to be defined. To achieve this, two
-calls of @code{changequote} must be made, one for the temporary quotes
-and one for the new quotes.
-
-Macros are recognized in preference to the begin-quote string, so if a
-prefix of @var{start} can be recognized as part of a potential macro
-name, the quoting mechanism is effectively disabled. Unless you use
-@code{changesyntax} (@pxref{Changesyntax}), this means that @var{start}
-should not begin with a letter, digit, or @samp{_} (underscore).
-However, even though quoted strings are not recognized, the quote
-characters can still be discerned in macro expansion and in trace
-output.
-
-@example
-define(`echo', `$@@')
-@result{}
-define(`hi', `HI')
-@result{}
-changequote(`q', `Q')
-@result{}
-q hi Q hi
-@result{}q HI Q HI
-echo(hi)
-@result{}qHIQ
-changequote
-@result{}
-changequote(`-', `EOF')
-@result{}
-- hi EOF hi
-@result{} hi HI
-changequote
-@result{}
-changequote(`1', `2')
-@result{}
-hi1hi2
-@result{}hi1hi2
-hi 1hi2
-@result{}HI hi
-@end example
-
-Quotes are recognized in preference to argument collection. In
-particular, if @var{start} is a single @samp{(}, then argument
-collection is effectively disabled. For portability with other
-implementations, it is a good idea to avoid @samp{(}, @samp{,}, and
-@samp{)} as the first character in @var{start}.
-
-@example
-define(`echo', `$#:$@@:')
-@result{}
-define(`hi', `HI')
-@result{}
-changequote(`(',`)')
-@result{}
-echo(hi)
-@result{}0::hi
-changequote
-@result{}
-changequote(`((', `))')
-@result{}
-echo(hi)
-@result{}1:HI:
-echo((hi))
-@result{}0::hi
-changequote
-@result{}
-changequote(`,', `)')
-@result{}
-echo(hi,hi)bye)
-@result{}1:HIhibye:
-@end example
-
-However, if you are not worried about portability, using @samp{(} and
-@samp{)} as quoting characters has an interesting property---you can use
-it to compute a quoted string containing the expansion of any quoted
-text, as long as the expansion results in both balanced quotes and
-balanced parentheses. The trick is realizing @code{expand} uses
-@samp{$1} unquoted, to trigger its expansion using the normal quoting
-characters, but uses extra parentheses to group unquoted commas that
-occur in the expansion without consuming whitespace following those
-commas. Then @code{_expand} uses @code{changequote} to convert the
-extra parentheses back into quoting characters. Note that it takes two
-more @code{changequote} invocations to restore the original quotes.
-Contrast the behavior on whitespace when using @samp{$*}, via
-@code{quote}, to attempt the same task.
-
-@example
-changequote(`[', `]')dnl
-define([a], [1, (b)])dnl
-define([b], [2])dnl
-define([quote], [[$*]])dnl
-define([expand], [_$0(($1))])dnl
-define([_expand],
- [changequote([(], [)])$1changequote`'changequote(`[', `]')])dnl
-expand([a, a, [a, a], [[a, a]]])
-@result{}1, (2), 1, (2), a, a, [a, a]
-quote(a, a, [a, a], [[a, a]])
-@result{}1,(2),1,(2),a, a,[a, a]
-@end example
-
-If @var{end} is a prefix of @var{start}, the end-quote will be
-recognized in preference to a nested begin-quote. In particular,
-changing the quotes to have the same string for @var{start} and
-@var{end} disables nesting of quotes. When quote nesting is disabled,
-it is impossible to double-quote strings across macro expansions, so
-using the same string is not done very often.
-
-@example
-define(`hi', `HI')
-@result{}
-changequote(`""', `"')
-@result{}
-""hi"""hi"
-@result{}hihi
-""hi" ""hi"
-@result{}hi hi
-""hi"" "hi"
-@result{}hi" "HI"
-changequote
-@result{}
-`hi`hi'hi'
-@result{}hi`hi'hi
-changequote(`"', `"')
-@result{}
-"hi"hi"hi"
-@result{}hiHIhi
-@end example
-
-It is an error if the end of file occurs within a quoted string.
-
-@comment status: 1
-@example
-`hello world'
-@result{}hello world
-`dangling quote
-^D
-@error{}m4:stdin:2: end of file in string
-@end example
-
-@comment status: 1
-@example
-ifelse(`dangling quote
-^D
-@error{}m4:stdin:1: ifelse: end of file in string
-@end example
-
-@node Changecom
-@section Changing the comment delimiters
-
-@cindex changing comment delimiters
-@cindex comment delimiters, changing
-@cindex delimiters, changing
-The default comment delimiters can be changed with the builtin
-macro @code{changecom}:
-
-@deffn {Builtin (m4)} changecom (@ovar{start}, @dvar{end, @key{NL}})
-This sets @var{start} as the new begin-comment delimiter and @var{end}
-as the new end-comment delimiter. If both arguments are missing, or
-@var{start} is void, then comments are disabled. Otherwise, if
-@var{end} is missing or void, the default end-comment delimiter of
-newline is used. The comment delimiters can be of any length.
-
-The expansion of @code{changecom} is void.
-@end deffn
-
-@example
-define(`comment', `COMMENT')
-@result{}
-# A normal comment
-@result{}# A normal comment
-changecom(`/*', `*/')
-@result{}
-# Not a comment anymore
-@result{}# Not a COMMENT anymore
-But: /* this is a comment now */ while this is not a comment
-@result{}But: /* this is a comment now */ while this is not a COMMENT
-@end example
-
-@cindex comments, copied to output
-Note how comments are copied to the output, much as if they were quoted
-strings. If you want the text inside a comment expanded, quote the
-begin-comment delimiter.
-
-Calling @code{changecom} without any arguments, or with @var{start} as
-the empty string, will effectively disable the commenting mechanism. To
-restore the original comment start of @samp{#}, you must explicitly ask
-for it. If @var{start} is not empty, then an empty @var{end} will use
-the default end-comment delimiter of newline, as otherwise, it would be
-impossible to end a comment. However, this is not portable, as some
-other @code{m4} implementations preserve the previous non-empty
-delimiters instead.
-
-@example
-define(`comment', `COMMENT')
-@result{}
-changecom
-@result{}
-# Not a comment anymore
-@result{}# Not a COMMENT anymore
-changecom(`#', `')
-@result{}
-# comment again
-@result{}# comment again
-@end example
-
-The comment strings can safely contain eight-bit characters.
-If no single character is appropriate, @var{start} and @var{end} can be
-of any length. Other implementations cap the delimiter length to five
-characters, but GNU has no inherent limit.
-
-As of M4 1.6, macros and quotes are recognized in preference to
-comments, so if a prefix of @var{start} can be recognized as part of a
-potential macro name, or confused with a quoted string, the comment
-mechanism is effectively disabled (earlier versions of GNU M4
-favored comments, but this was inconsistent with other implementations).
-Unless you use @code{changesyntax} (@pxref{Changesyntax}), this means
-that @var{start} should not begin with a letter, digit, or @samp{_}
-(underscore), and that neither the start-quote nor the start-comment
-string should be a prefix of the other.
-
-@example
-define(`hi', `HI')
-@result{}
-define(`hi1hi2', `hello')
-@result{}
-changecom(`q', `Q')
-@result{}
-q hi Q hi
-@result{}q HI Q HI
-changecom(`1', `2')
-@result{}
-hi1hi2
-@result{}hello
-hi 1hi2
-@result{}HI 1hi2
-changecom(`[[', `]]')
-@result{}
-changequote(`[[[', `]]]')
-@result{}
-[hi]
-@result{}[HI]
-[[hi]]
-@result{}[[hi]]
-[[[hi]]]
-@result{}hi
-changequote
-@result{}
-changecom(`[[[', `]]]')
-@result{}
-changequote(`[[', `]]')
-@result{}
-[[hi]]
-@result{}hi
-[[[hi]]]
-@result{}[hi]
-@end example
-
-Comments are recognized in preference to argument collection. In
-particular, if @var{start} is a single @samp{(}, then argument
-collection is effectively disabled. For portability with other
-implementations, it is a good idea to avoid @samp{(}, @samp{,}, and
-@samp{)} as the first character in @var{start}.
-
-@example
-define(`echo', `$#:$*:$@@:')
-@result{}
-define(`hi', `HI')
-@result{}
-changecom(`(',`)')
-@result{}
-echo(hi)
-@result{}0:::(hi)
-changecom
-@result{}
-changecom(`((', `))')
-@result{}
-echo(hi)
-@result{}1:HI:HI:
-echo((hi))
-@result{}0:::((hi))
-changecom(`,', `)')
-@result{}
-echo(hi,hi)bye)
-@result{}1:HI,hi)bye:HI,hi)bye:
-changecom
-@result{}
-echo(hi,`,`'hi',hi)
-@result{}3:HI,,HI,HI:HI,,`'hi,HI:
-echo(hi,`,`'hi',hi`'changecom(`,,', `hi'))
-@result{}3:HI,,`'hi,HI:HI,,`'hi,HI:
-@end example
-
-It is an error if the end of file occurs within a comment.
-
-@comment status: 1
-@example
-changecom(`/*', `*/')
-@result{}
-/*dangling comment
-^D
-@error{}m4:stdin:2: end of file in comment
-@end example
-
-@comment status: 1
-@example
-changecom(`/*', `*/')
-@result{}
-len(/*dangling comment
-^D
-@error{}m4:stdin:2: len: end of file in comment
-@end example
-
-@node Changeresyntax
-@section Changing the regular expression syntax
-
-@cindex regular expression syntax, changing
-@cindex basic regular expressions
-@cindex extended regular expressions
-@cindex regular expressions
-@cindex expressions, regular
-@cindex syntax, changing regular expression
-@cindex flavors of regular expressions
-@cindex GNU extensions
-The GNU extensions @code{patsubst}, @code{regexp}, and more
-recently, @code{renamesyms} each deal with regular expressions. There
-are multiple flavors of regular expressions, so the
-@code{changeresyntax} builtin exists to allow choosing the default
-flavor:
-
-@deffn {Builtin (gnu)} changeresyntax (@var{resyntax})
-Changes the default regular expression syntax used by M4 according to
-the value of @var{resyntax}, equivalent to passing @var{resyntax} as the
-argument to the command line option @option{--regexp-syntax}
-(@pxref{Operation modes, , Invoking m4}). If @var{resyntax} is empty,
-the default flavor is reverted to the @code{GNU_M4} style, compatible
-with emacs.
-
-@var{resyntax} can be any one of the values in the table below. Case is
-not important, and @samp{-} or @samp{ } can be substituted for @samp{_} in
-the given names. If @var{resyntax} is unrecognized, a warning is
-issued and the default flavor is not changed.
-
-@table @dfn
-@item AWK
-@xref{awk regular expression syntax}, for details.
-
-@item BASIC
-@itemx ED
-@itemx POSIX_BASIC
-@itemx SED
-@xref{posix-basic regular expression syntax}, for details.
-
-@item BSD_M4
-@item EXTENDED
-@itemx POSIX_EXTENDED
-@xref{posix-extended regular expression syntax}, for details.
-
-@item GNU_AWK
-@itemx GAWK
-@xref{gnu-awk regular expression syntax}, for details.
-
-@item GNU_EGREP
-@itemx EGREP
-@xref{egrep regular expression syntax}, for details.
-
-@item GNU_M4
-@item EMACS
-@itemx GNU_EMACS
-@xref{emacs regular expression syntax}, for details. This is the
-default regular expression flavor.
-
-@item GREP
-@xref{grep regular expression syntax}, for details.
-
-@item MINIMAL
-@itemx POSIX_MINIMAL
-@itemx POSIX_MINIMAL_BASIC
-@xref{posix-minimal-basic regular expression syntax}, for details.
-
-@item POSIX_AWK
-@xref{posix-awk regular expression syntax}, for details.
-
-@item POSIX_EGREP
-@xref{posix-egrep regular expression syntax}, for details.
-@end table
-
-The expansion of @code{changeresyntax} is void.
-The macro @code{changeresyntax} is recognized only with parameters.
-This macro was added in M4 2.0.
-@end deffn
-
-For an example of how @var{resyntax} is recognized, the first three
-usages select the @samp{GNU_M4} regular expression flavor:
-
-@example
-changeresyntax(`gnu m4')
-@result{}
-changeresyntax(`GNU-m4')
-@result{}
-changeresyntax(`Gnu_M4')
-@result{}
-changeresyntax(`unknown')
-@error{}m4:stdin:4: warning: changeresyntax: bad syntax-spec: 'unknown'
-@result{}
-@end example
-
-Using @code{changeresyntax} makes it possible to omit the optional
-@var{resyntax} parameter to other macros, while still using a different
-regular expression flavor.
-
-@example
-patsubst(`ab', `a|b', `c')
-@result{}ab
-patsubst(`ab', `a\|b', `c')
-@result{}cc
-patsubst(`ab', `a|b', `c', `EXTENDED')
-@result{}cc
-changeresyntax(`EXTENDED')
-@result{}
-patsubst(`ab', `a|b', `c')
-@result{}cc
-patsubst(`ab', `a\|b', `c')
-@result{}ab
-@end example
-
-@node Changesyntax
-@section Changing the lexical structure of the input
-
-@cindex lexical structure of the input
-@cindex input, lexical structure of the
-@cindex syntax table
-@cindex changing syntax
-@cindex GNU extensions
-@quotation
-The macro @code{changesyntax} and all associated functionality is
-experimental (@pxref{Experiments}). The functionality might change in
-the future. Please direct your comments about it the same way you would
-do for bugs.
-@end quotation
-
-The input to @code{m4} is read character by character, and these
-characters are grouped together to form input tokens (such as macro
-names, strings, comments, etc.).
-
-Each token is parsed according to certain rules. For example, a macro
-name starts with a letter or @samp{_} and consists of the longest
-possible string of letters, @samp{_} and digits. But who is to decide
-what characters are letters, digits, quotes, white space? Earlier the
-operating system decided, now you do. The builtin macro
-@code{changesyntax} is used to change the way @code{m4} parses the input
-stream into tokens.
-
-@deffn {Builtin (gnu)} changesyntax (@var{syntax-spec}, @dots{})
-Each @var{syntax-spec} is a two-part string. The first part is a
-command, consisting of a single character describing a syntax category,
-and an optional one-character action. The action can be @samp{-} to
-remove the listed characters from that category, @samp{=} to set the
-category to the listed characters
-and reassign all other characters previously in that category to
-`Other', or @samp{+} to add the listed characters to the category
-without affecting other characters. If an action is not specified, but
-additional characters are present, then @samp{=} is assumed.
-
-The remaining characters of each @var{syntax-spec} form the set of
-characters to perform the action on for that syntax category. Character
-ranges are expanded as for @code{translit} (@pxref{Translit}). To start
-the character set with @samp{-}, @samp{+}, or @samp{=}, an action must
-be specified.
-
-If @var{syntax-spec} is just a category, and no action or characters
-were specified, then all characters in that category are reset to their
-default state. A warning is issued if the category character is not
-valid. If @var{syntax-spec} is the empty string, then all categories
-are reset to their default state.
-
-Syntax categories are divided into basic and context. Every input
-byte belongs to exactly one basic syntax category. Additionally, any
-byte can be assigned to a context category regardless of its current
-basic category. Context categories exist because a character can
-behave differently when parsed in isolation than when it occurs in
-context to close out a token started by another basic category (for
-example, @kbd{newline} defaults to the basic category `Whitespace' as
-well as the context category `End comment').
-
-The following table describes the case-insensitive designation for each
-syntax category (the first byte in @var{syntax-spec}), and a description
-of what each category controls.
-
-@multitable @columnfractions .06 .20 .13 .55
-@headitem Code @tab Category @tab Type @tab Description
-
-@item @kbd{W} @tab @dfn{Words} @tab Basic
-@tab Characters that can start a macro name. Defaults to the letters as
-defined by the locale, and the character @samp{_}.
-
-@item @kbd{D} @tab @dfn{Digits} @tab Basic
-@tab Characters that, together with the letters, form the remainder of a
-macro name. Defaults to the ten digits @samp{0}@dots{}@samp{9}, and any
-other digits defined by the locale.
-
-@item @kbd{S} @tab @dfn{White space} @tab Basic
-@tab Characters that should be trimmed from the beginning of each argument to
-a macro call. The defaults are space, tab, newline, carriage return,
-form feed, and vertical tab, and any others as defined by the locale.
-
-@item @kbd{(} @tab @dfn{Open parenthesis} @tab Basic
-@tab Characters that open the argument list of a macro call. The default is
-the single character @samp{(}.
-
-@item @kbd{)} @tab @dfn{Close parenthesis} @tab Basic
-@tab Characters that close the argument list of a macro call. The default
-is the single character @samp{)}.
-
-@item @kbd{,} @tab @dfn{Argument separator} @tab Basic
-@tab Characters that separate the arguments of a macro call. The default is
-the single character @samp{,}.
-
-@item @kbd{L} @tab @dfn{Left quote} @tab Basic
-@tab The set of characters that can start a single-character quoted string.
-The default is the single character @samp{`}. For multiple-character
-quote delimiters, use @code{changequote} (@pxref{Changequote}).
-
-@item @kbd{R} @tab @dfn{Right quote} @tab Context
-@tab The set of characters that can end a single-character quoted string.
-The default is the single character @samp{'}. For multiple-character
-quote delimiters, use @code{changequote} (@pxref{Changequote}). Note
-that @samp{'} also defaults to the syntax category `Other', when it
-appears in isolation.
-
-@item @kbd{B} @tab @dfn{Begin comment} @tab Basic
-@tab The set of characters that can start a single-character comment. The
-default is the single character @samp{#}. For multiple-character
-comment delimiters, use @code{changecom} (@pxref{Changecom}).
-
-@item @kbd{E} @tab @dfn{End comment} @tab Context
-@tab The set of characters that can end a single-character comment. The
-default is the single character @kbd{newline}. For multiple-character
-comment delimiters, use @code{changecom} (@pxref{Changecom}). Note that
-newline also defaults to the syntax category `White space', when it
-appears in isolation.
-
-@item @kbd{$} @tab @dfn{Dollar} @tab Context
-@tab Characters that can introduce an argument reference in the body of a
-macro. The default is the single character @samp{$}.
-
-@comment FIXME - implement ${10} argument parsing.
-@item @kbd{@{} @tab @dfn{Left brace} @tab Context
-@tab Characters that introduce an extended argument reference in the body of
-a macro immediately after a character in the Dollar category. The
-default is the single character @samp{@{}.
-
-@item @kbd{@}} @tab @dfn{Right brace} @tab Context
-@tab Characters that conclude an extended argument reference in the body of a
-macro. The default is the single character @samp{@}}.
-
-@item @kbd{O} @tab @dfn{Other} @tab Basic
-@tab Characters that have no special syntactical meaning to @code{m4}.
-Defaults to all characters except those in the categories above.
-
-@item @kbd{A} @tab @dfn{Active} @tab Basic
-@tab Characters that themselves, alone, form macro names. This is a
-GNU extension, and active characters have lower precedence
-than comments. By default, no characters are active.
-
-@item @kbd{@@} @tab @dfn{Escape} @tab Basic
-@tab Characters that must precede macro names for them to be recognized.
-This is a GNU extension. When an escape character is defined,
-then macros are not recognized unless the escape character is present;
-however, the macro name, visible by @samp{$0} in macro definitions, does
-not include the escape character. By default, no characters are
-escapes.
-
-@comment FIXME - we should also consider supporting:
-@comment @item @kbd{I} @tab @dfn{Ignore} @tab Basic
-@comment @tab Characters that are ignored if they appear in
-@comment the input; perhaps defaulting to '\0'.
-@end multitable
-
-The expansion of @code{changesyntax} is void.
-The macro @code{changesyntax} is recognized only with parameters. Use
-this macro with caution, as it is possible to change the syntax in such
-a way that no further macros can be recognized by @code{m4}.
-This macro was added in M4 2.0.
-@end deffn
-
-With @code{changesyntax} we can modify what characters form a word. For
-example, we can make @samp{.} a valid character in a macro name, or even
-start a macro name with a number.
-
-@example
-define(`test.1', `TEST ONE')
-@result{}
-define(`1', `one')
-@result{}
-__file__
-@result{}stdin
-test.1
-@result{}test.1
-dnl Add `.' and remove `_'.
-changesyntax(`W+.', `W-_')
-@result{}
-__file__
-@result{}__file__
-test.1
-@result{}TEST ONE
-dnl Set words to include numbers.
-changesyntax(`W=a-zA-Z0-9_')
-@result{}
-__file__
-@result{}stdin
-test.1
-@result{}test.one
-dnl Reset words to default (a-zA-Z_).
-changesyntax(`W')
-@result{}
-__file__
-@result{}stdin
-test.1
-@result{}test.1
-@end example
-
-Another possibility is to change the syntax of a macro call.
-
-@example
-define(`test', `$#')
-@result{}
-test(a, b, c)
-@result{}3
-dnl Change macro syntax.
-changesyntax(`(<', `,|', `)>')
-@result{}
-test(a, b, c)
-@result{}0(a, b, c)
-test<a|b|c>
-@result{}3
-@end example
-
-Leading spaces are always removed from macro arguments in @code{m4}, but
-by changing the syntax categories we can avoid it. The use of
-@code{format} is an alternative to using a literal tab character.
-
-@example
-define(`test', `$1$2$3')
-@result{}
-test(`a', `b', `c')
-@result{}abc
-dnl Don't ignore whitespace.
-changesyntax(`O 'format(``%c'', `9')`
-')
-@result{}
-test(a, b,
-c)
-@result{}a b
-@result{}c
-@end example
-
-It is possible to redefine the @samp{$} used to indicate macro arguments
-in user defined macros. Dollar class syntax elements are copied to the
-output if there is no valid expansion.
-
-@example
-define(`argref', `Dollar: $#, Question: ?#')
-@result{}
-argref(1, 2, 3)
-@result{}Dollar: 3, Question: ?#
-dnl Change argument identifier.
-changesyntax(`$?')
-@result{}
-argref(1,2,3)
-@result{}Dollar: $#, Question: 3
-define(`escape', `$?`'1$?1?')
-@result{}
-escape(foo)
-@result{}$?1$foo?
-dnl Multiple argument identifiers.
-changesyntax(`$+$')
-@result{}
-argref(1, 2, 3)
-@result{}Dollar: 3, Question: 3
-@end example
-
-Macro calls can be given a @TeX{} or Texinfo like syntax using an
-escape. If one or more characters are defined as escapes, macro names
-are only recognized if preceded by an escape character.
-
-If the escape is not followed by what is normally a word (a letter
-optionally followed by letters and/or numerals), that single character
-is returned as a macro name.
-
-As always, words without a macro definition cause no error message.
-They and the escape character are simply output.
-
-@example
-define(`foo', `bar')
-@result{}
-dnl Require @@ escape before any macro.
-changesyntax(`@@@@')
-@result{}
-foo
-@result{}foo
-@@foo
-@result{}bar
-@@bar
-@result{}@@bar
-@@dnl Change escape character.
-@@changesyntax(`@@\', `O@@')
-@result{}
-foo
-@result{}foo
-@@foo
-@result{}@@foo
-\foo
-@result{}bar
-define(`#', `No comment')
-@result{}define(#, No comment)
-\define(`#', `No comment')
-@result{}
-\# \foo # Comment \foo
-@result{}No comment bar # Comment \foo
-@end example
-
-Active characters are known from @TeX{}. In @code{m4} an active
-character is always seen as a one-letter word, and so, if it has a macro
-definition, the macro will be called.
-
-@example
-define(`@@', `TEST')
-@result{}
-define(`a@@a', `hello')
-@result{}
-define(`a', `A')
-@result{}
-@@
-@result{}@@
-a@@a
-@result{}A@@A
-dnl Make @@ active.
-changesyntax(`A@@')
-@result{}
-@@
-@result{}TEST
-a@@a
-@result{}ATESTa
-@end example
-
-There is obviously an overlap between @code{changesyntax} and
-@code{changequote}, since there are now two ways to modify quote
-delimiters. To avoid incompatibilities, if the quotes are modified by
-@code{changequote}, any characters previously set to either quote
-delimiter by @code{changesyntax} are first demoted to the other category
-(@samp{O}), so the result is only a single set of quotes. In the other
-direction, if quotes were already disabled, or if both the start and end
-delimiter set by @code{changequote} are single bytes, then
-@code{changesyntax} preserves those settings. But if either delimiter
-occupies multiple bytes, @code{changesyntax} first disables both
-delimiters. Quotes can be disabled via @code{changesyntax} by emptying
-the left quote basic category (@samp{L}). Meanwhile, the right quote
-context category (@samp{R}) will never be empty; if a
-@code{changesyntax} action would otherwise leave that category empty,
-then the default end delimiter from @code{changequote} (@samp{'}) is
-used; thus, it is never possible to get @code{m4} in a state where a
-quoted string cannot be terminated. These interactions apply to comment
-delimiters as well, @i{mutatis mutandis} with @code{changecom}.
-
-@example
-define(`test', `TEST')
-@result{}
-dnl Add additional single-byte delimiters.
-changesyntax(`L+<', `R+>')
-@result{}
-<test> `test' [test] <<test>>
-@result{}test test [TEST] <test>
-dnl Use standard interface, overriding changesyntax settings.
-changequote(<[>, `]')
-@result{}
-<test> `test' [test] <<test>>
-@result{}<TEST> `TEST' test <<TEST>>
-dnl Introduce multi-byte delimiters.
-changequote([<<], [>>])
-@result{}
-<test> `test' [test] <<test>>
-@result{}<TEST> `TEST' [TEST] test
-dnl Change end quote, effectively disabling quotes.
-changesyntax(<<R]>>)
-@result{}
-<test> `test' [test] <<test>>
-@result{}<TEST> `TEST' [TEST] <<TEST>>
-dnl Change beginning quote, make ] normal, thus making ' end quote.
-changesyntax(L`, R-])
-@result{}
-<test> `test' [test] <<test>>
-@result{}<TEST> test [TEST] <<TEST>>
-dnl Set multi-byte quote; unrelated changes don't impact it.
-changequote(`<<', `>>')changesyntax(<<@@\>>)
-@result{}
-<\test> `\test' [\test] <<\test>>
-@result{}<TEST> `TEST' [TEST] \test
-@end example
-
-If several characters are assigned to a category that forms single
-character tokens, all such characters are treated as equal. Any open
-parenthesis will match any close parenthesis, etc.
-
-@example
-dnl Go crazy with symbols.
-changesyntax(`(@{<', `)@}>', `,;:', `O(,)')
-@result{}
-eval@{2**4-1; 2: 8>
-@result{}00001111
-@end example
-
-The syntax table is initialized to be backwards compatible, so if you
-never call @code{changesyntax}, nothing will have changed.
-
-For now, debugging output continues to use @kbd{(}, @kbd{,} and @kbd{)}
-to show macro calls; and macro expansions that result in a list of
-arguments (such as @samp{$@@} or @code{shift}) use @samp{,}, regardless
-of the current syntax settings. However, this is likely to change in a
-future release, so it should not be relied on, particularly since it is
-next to impossible to write recursive macros if the argument separator
-doesn't match between expansion and rescanning.
-
-@c FIXME - changing syntax of , should not break iterative macros.
-@example
-$ @kbd{m4 -d}
-changesyntax(`,=|')traceon(`foo')define(`foo'|`$#:$@@')
-@result{}
-foo(foo(1|2|3))
-@error{}m4trace: -2- foo(`1', `2', `3') -> `3:`1',`2',`3''
-@error{}m4trace: -1- foo(`3:1,2,3') -> `1:`3:1,2,3''
-@result{}1:3:1,2,3
-@end example
-
-@node M4wrap
-@section Saving text until end of input
-
-@cindex saving input
-@cindex input, saving
-@cindex deferring expansion
-@cindex expansion, deferring
-It is possible to `save' some text until the end of the normal input has
-been seen. Text can be saved, to be read again by @code{m4} when the
-normal input has been exhausted. This feature is normally used to
-initiate cleanup actions before normal exit, e.g., deleting temporary
-files.
-
-To save input text, use the builtin @code{m4wrap}:
-
-@deffn {Builtin (m4)} m4wrap (@var{string}, @dots{})
-Stores @var{string} in a safe place, to be reread when end of input is
-reached. As a GNU extension, additional arguments are
-concatenated with a space to the @var{string}.
-
-Successive invocations of @code{m4wrap} accumulate saved text in
-first-in, first-out order, as required by POSIX.
-
-The expansion of @code{m4wrap} is void.
-The macro @code{m4wrap} is recognized only with parameters.
-@end deffn
-
-@example
-define(`cleanup', `This is the `cleanup' action.
-')
-@result{}
-m4wrap(`cleanup')
-@result{}
-This is the first and last normal input line.
-@result{}This is the first and last normal input line.
-^D
-@result{}This is the cleanup action.
-@end example
-
-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}.
-
-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.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 POSIX.
-
-@example
-m4wrap(`1
-')
-@result{}
-m4wrap(`2', `3
-')
-@result{}
-^D
-@result{}1
-@result{}2 3
-@end example
-
-However, earlier versions had reverse ordering (LIFO---last in, first
-out), as this behavior is more like the semantics of the C function
-@code{atexit}. It is possible to emulate POSIX behavior even
-with older versions of GNU M4 by including the file
-@file{m4-@value{VERSION}/@/doc/examples/@/wrapfifo.m4} from the
-distribution:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`wrapfifo.m4')dnl
-@result{}dnl Redefine m4wrap to have FIFO semantics.
-@result{}define(`_m4wrap_level', `0')dnl
-@result{}define(`m4wrap',
-@result{}`ifdef(`m4wrap'_m4wrap_level,
-@result{} `define(`m4wrap'_m4wrap_level,
-@result{} defn(`m4wrap'_m4wrap_level)`$1')',
-@result{} `builtin(`m4wrap', `define(`_m4wrap_level',
-@result{} incr(_m4wrap_level))dnl
-@result{}m4wrap'_m4wrap_level)dnl
-@result{}define(`m4wrap'_m4wrap_level, `$1')')')dnl
-include(`wrapfifo.m4')
-@result{}
-m4wrap(`a`'m4wrap(`c
-', `d')')m4wrap(`b')
-@result{}
-^D
-@result{}abc
-@end example
-
-It is likewise possible to emulate LIFO behavior without resorting to
-the GNU M4 extension of @code{builtin}, by including the file
-@file{m4-@value{VERSION}/@/doc/examples/@/wraplifo.m4} from the
-distribution. (Unfortunately, both examples shown here share some
-subtle bugs. See if you can find and correct them; or @pxref{Improved
-m4wrap, , Answers}).
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`wraplifo.m4')dnl
-@result{}dnl Redefine m4wrap to have LIFO semantics.
-@result{}define(`_m4wrap_level', `0')dnl
-@result{}define(`_m4wrap', defn(`m4wrap'))dnl
-@result{}define(`m4wrap',
-@result{}`ifdef(`m4wrap'_m4wrap_level,
-@result{} `define(`m4wrap'_m4wrap_level,
-@result{} `$1'defn(`m4wrap'_m4wrap_level))',
-@result{} `_m4wrap(`define(`_m4wrap_level', incr(_m4wrap_level))dnl
-@result{}m4wrap'_m4wrap_level)dnl
-@result{}define(`m4wrap'_m4wrap_level, `$1')')')dnl
-include(`wraplifo.m4')
-@result{}
-m4wrap(`a`'m4wrap(`c
-', `d')')m4wrap(`b')
-@result{}
-^D
-@result{}bac
-@end example
-
-Here is an example of implementing a factorial function using
-@code{m4wrap}:
-
-@example
-define(`f', `ifelse(`$1', `0', `Answer: 0!=1
-', eval(`$1>1'), `0', `Answer: $2$1=eval(`$2$1')
-', `m4wrap(`f(decr(`$1'), `$2$1*')')')')
-@result{}
-f(`10')
-@result{}
-^D
-@result{}Answer: 10*9*8*7*6*5*4*3*2*1=3628800
-@end example
-
-Invocations of @code{m4wrap} at the same recursion level are
-concatenated and rescanned as usual:
-
-@example
-define(`ab', `AB
-')
-@result{}
-m4wrap(`a')m4wrap(`b')
-@result{}
-^D
-@result{}AB
-@end example
-
-@noindent
-however, the transition between recursion levels behaves like an end of
-file condition between two input files.
-
-@comment status: 1
-@example
-m4wrap(`m4wrap(`)')len(abc')
-@result{}
-^D
-@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
-
-@cindex file inclusion
-@cindex inclusion, of files
-@code{m4} allows you to include named files at any point in the input.
-
-@menu
-* Include:: Including named files and modules
-* Search Path:: Searching for include files
-@end menu
-
-@node Include
-@section Including named files and modules
-
-There are two builtin macros in @code{m4} for including files:
-
-@deffn {Builtin (m4)} include (@var{file})
-@deffnx {Builtin (m4)} sinclude (@var{file})
-Both macros cause the file named @var{file} to be read by
-@code{m4}. When the end of the file is reached, input is resumed from
-the previous input file.
-
-The expansion of @code{include} and @code{sinclude} is therefore the
-contents of @var{file}.
-
-If @var{file} does not exist, is a directory, or cannot otherwise be
-read, the expansion is void,
-and @code{include} will fail with an error while @code{sinclude} is
-silent. The empty string counts as a file that does not exist.
-
-The macros @code{include} and @code{sinclude} are recognized only with
-parameters.
-@end deffn
-
-@comment status: 1
-@example
-include(`n')
-@error{}m4:stdin:1: include: cannot open file 'n': No such file or directory
-@result{}
-include()
-@error{}m4:stdin:2: include: cannot open file '': No such file or directory
-@result{}
-sinclude(`n')
-@result{}
-sinclude()
-@result{}
-@end example
-
-This section uses the @option{--include} command-line option (or
-@option{-I}, @pxref{Preprocessor features, , Invoking m4}) to grab
-files from the @file{m4-@value{VERSION}/@/doc/examples}
-directory shipped as part of the GNU @code{m4} package. The
-file @file{m4-@value{VERSION}/@/doc/examples/@/incl.m4} in the distribution
-contains the lines:
-
-@comment ignore
-@example
-$ @kbd{cat doc/examples/incl.m4}
-@result{}Include file start
-@result{}foo
-@result{}Include file end
-@end example
-
-Normally file inclusion is used to insert the contents of a file
-into the input stream. The contents of the file will be read by
-@code{m4} and macro calls in the file will be expanded:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-define(`foo', `FOO')
-@result{}
-include(`incl.m4')
-@result{}Include file start
-@result{}FOO
-@result{}Include file end
-@result{}
-@end example
-
-The fact that @code{include} and @code{sinclude} expand to the contents
-of the file can be used to define macros that operate on entire files.
-Here is an example, which defines @samp{bar} to expand to the contents
-of @file{incl.m4}:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-define(`bar', include(`incl.m4'))
-@result{}
-This is `bar': >>bar<<
-@result{}This is bar: >>Include file start
-@result{}foo
-@result{}Include file end
-@result{}<<
-@end example
-
-This use of @code{include} is not trivial, though, as files can contain
-quotes, commas, and parentheses, which can interfere with the way the
-@code{m4} parser works. GNU M4 seamlessly concatenates
-the file contents with the next character, even if the included file
-ended in the middle of a comment, string, or macro call. These
-conditions are only treated as end of file errors if specified as input
-files on the command line.
-
-In GNU M4, an alternative method of reading files is
-using @code{undivert} (@pxref{Undivert}) on a named file.
-
-In addition, as a GNU M4 extension, if the included file cannot
-be found exactly as given, various standard suffixes are appended.
-If the included file name is absolute (a full path from the root directory
-is given) then additional search directories are not examined, although
-suffixes will be tried if the file is not found exactly as given.
-For each directory that is searched (according to the absolute directory
-give in the file name, or else by directories listed in @env{M4PATH} and
-given with the @option{-I} and @option{-B} options), first the unchanged
-file name is tried, and then again with the suffixes @samp{.m4f} and
-@samp{.m4}.
-
-Furthermore, if no matching file has yet been found, before moving on to
-the next directory, @samp{.la} and the usual binary module suffix for
-the host platform (usually @samp{.so}) are also tried. Matching with one
-of those suffixes will attempt to load the matched file as a dynamic
-module. @xref{Modules}, for more details.
-
-@node Search Path
-@section Searching for include files
-
-@cindex search path for included files
-@cindex included files, search path for
-@cindex GNU extensions
-GNU @code{m4} allows included files to be found in other directories
-than the current working directory.
-
-@cindex @env{M4PATH}
-If the @option{--prepend-include} or @option{-B} command-line option was
-provided (@pxref{Preprocessor features, , Invoking m4}), those
-directories are searched first, in reverse order that those options were
-listed on the command line. Then @code{m4} looks in the current working
-directory. Next comes the directories specified with the
-@option{--include} or @option{-I} option, in the order found on the
-command line. Finally, if the @env{M4PATH} environment variable is set,
-it is expected to contain a colon-separated list of directories, which
-will be searched in order.
-
-If the automatic search for include-files causes trouble, the @samp{p}
-debug flag (@pxref{Debugmode}) can help isolate the problem.
-
-@node Diversions
-@chapter Diverting and undiverting output
-
-@cindex deferring output
-Diversions are a way of temporarily saving output. The output of
-@code{m4} can at any time be diverted to a temporary file, and be
-reinserted into the output stream, @dfn{undiverted}, again at a later
-time.
-
-@cindex @env{TMPDIR}
-Numbered diversions are counted from 0 upwards, diversion number 0
-being the normal output stream. GNU
-@code{m4} tries to keep diversions in memory. However, there is a
-limit to the overall memory usable by all diversions taken together
-(512K, currently). When this maximum is about to be exceeded,
-a temporary file is opened to receive the contents of the biggest
-diversion still in memory, freeing this memory for other diversions.
-When creating the temporary file, @code{m4} honors the value of the
-environment variable @env{TMPDIR}, and falls back to @file{/tmp}.
-Thus, the amount of available disk space provides the only real limit on
-the number and aggregate size of diversions.
-
-Diversions make it possible to generate output in a different order than
-the input was read. It is possible to implement topological sorting
-dependencies. For example, GNU Autoconf makes use of
-diversions under the hood to ensure that the expansion of a prerequisite
-macro appears in the output prior to the expansion of a dependent macro,
-regardless of which order the two macros were invoked in the user's
-input file.
-
-@menu
-* Divert:: Diverting output
-* Undivert:: Undiverting output
-* Divnum:: Diversion numbers
-* Cleardivert:: Discarding diverted text
-@end menu
-
-@node Divert
-@section Diverting output
-
-@cindex diverting output to files
-@cindex output, diverting to files
-@cindex files, diverting output to
-Output is diverted using @code{divert}:
-
-@deffn {Builtin (m4)} divert (@dvar{number, 0}, @ovar{text})
-The current diversion is changed to @var{number}. If @var{number} is left
-out or empty, it is assumed to be zero. If @var{number} cannot be
-parsed, the diversion is unchanged.
-
-@cindex GNU extensions
-As a GNU extension, if optional @var{text} is supplied and
-@var{number} was valid, then @var{text} is immediately output to the
-new diversion, regardless of whether the expansion of @code{divert}
-occurred while collecting arguments for another macro.
-
-The expansion of @code{divert} is void.
-@end deffn
-
-When all the @code{m4} input will have been processed, all existing
-diversions are automatically undiverted, in numerical order.
-
-@example
-divert(`1')
-This text is diverted.
-divert
-@result{}
-This text is not diverted.
-@result{}This text is not diverted.
-^D
-@result{}
-@result{}This text is diverted.
-@end example
-
-Several calls of @code{divert} with the same argument do not overwrite
-the previous diverted text, but append to it. Diversions are printed
-after any wrapped text is expanded.
-
-@example
-define(`text', `TEXT')
-@result{}
-divert(`1')`diverted text.'
-divert
-@result{}
-m4wrap(`Wrapped text precedes ')
-@result{}
-^D
-@result{}Wrapped TEXT precedes diverted text.
-@end example
-
-@cindex discarding input
-@cindex input, discarding
-If output is diverted to a negative diversion, it is simply discarded.
-This can be used to suppress unwanted output. A common example of
-unwanted output is the trailing newlines after macro definitions. Here
-is a common programming idiom in @code{m4} for avoiding them.
-
-@example
-divert(`-1')
-define(`foo', `Macro `foo'.')
-define(`bar', `Macro `bar'.')
-divert
-@result{}
-@end example
-
-@cindex GNU extensions
-Traditional implementations only supported ten diversions. But as a
-GNU extension, diversion numbers can be as large as positive
-integers will allow, rather than treating a multi-digit diversion number
-as a request to discard text.
-
-@example
-divert(eval(`1<<28'))world
-divert(`2')hello
-^D
-@result{}hello
-@result{}world
-@end example
-
-The ability to immediately output extra text is a GNU
-extension, but it can prove useful for ensuring that text goes to a
-particular diversion no matter how many pending macro expansions are in
-progress. For a demonstration of why this is useful, it is important to
-understand in the example below why @samp{one} is output in diversion 2,
-not diversion 1, while @samp{three} and @samp{five} both end up in the
-correctly numbered diversion. The key point is that when @code{divert}
-is executed unquoted as part of the argument collection of another
-macro, the side effect takes place immediately, but the text @samp{one}
-is not passed to any diversion until after the @samp{divert(`2')} and
-the enclosing @code{echo} have also taken place. The example with
-@samp{three} shows how following the quoting rule of thumb delays the
-invocation of @code{divert} until it is not nested in any argument
-collection context, while the example with @samp{five} shows the use of
-the optional argument to speed up the output process.
-
-@example
-define(`echo', `$1')
-@result{}
-echo(divert(`1')`one'divert(`2'))`'dnl
-echo(`divert(`3')three`'divert(`4')')`'dnl
-echo(divert(`5', `five')divert(`6'))`'dnl
-divert
-@result{}
-undivert(`1')
-@result{}
-undivert(`2')
-@result{}one
-undivert(`3')
-@result{}three
-undivert(`4')
-@result{}
-undivert(`5')
-@result{}five
-undivert(`6')
-@result{}
-@end example
-
-Note that @code{divert} is an English word, but also an active macro
-without arguments. When processing plain text, the word might appear in
-normal text and be unintentionally swallowed as a macro invocation. One
-way to avoid this is to use the @option{-P} option to rename all
-builtins (@pxref{Operation modes, , Invoking m4}). Another is to write
-a wrapper that requires a parameter to be recognized.
-
-@example
-We decided to divert the stream for irrigation.
-@result{}We decided to the stream for irrigation.
-define(`divert', `ifelse(`$#', `0', ``$0'', `builtin(`$0', $@@)')')
-@result{}
-divert(`-1')
-Ignored text.
-divert(`0')
-@result{}
-We decided to divert the stream for irrigation.
-@result{}We decided to divert the stream for irrigation.
-@end example
-
-@node Undivert
-@section Undiverting output
-
-Diverted text can be undiverted explicitly using the builtin
-@code{undivert}:
-
-@deffn {Builtin (m4)} undivert (@ovar{diversions@dots{}})
-Undiverts the numeric @var{diversions} given by the arguments, in the
-order given. If no arguments are supplied, all diversions are
-undiverted, in numerical order.
-
-@cindex file inclusion
-@cindex inclusion, of files
-@cindex GNU extensions
-As a GNU extension, @var{diversions} may contain non-numeric
-strings, which are treated as the names of files to copy into the output
-without expansion. A warning is issued if a file could not be opened.
-
-The expansion of @code{undivert} is void.
-@end deffn
-
-@example
-divert(`1')
-This text is diverted.
-divert
-@result{}
-This text is not diverted.
-@result{}This text is not diverted.
-undivert(`1')
-@result{}
-@result{}This text is diverted.
-@result{}
-@end example
-
-Notice the last two blank lines. One of them comes from the newline
-following @code{undivert}, the other from the newline that followed the
-@code{divert}! A diversion often starts with a blank line like this.
-
-When diverted text is undiverted, it is @emph{not} reread by @code{m4},
-but rather copied directly to the current output, and it is therefore
-not an error to undivert into a diversion. Undiverting the empty string
-is the same as specifying diversion 0; in either case nothing happens
-since the output has already been flushed.
-
-@example
-divert(`1')diverted text
-divert
-@result{}
-undivert()
-@result{}
-undivert(`0')
-@result{}
-undivert
-@result{}diverted text
-@result{}
-divert(`1')more
-divert(`2')undivert(`1')diverted text`'divert
-@result{}
-undivert(`1')
-@result{}
-undivert(`2')
-@result{}more
-@result{}diverted text
-@end example
-
-When a diversion has been undiverted, the diverted text is discarded,
-and it is not possible to bring back diverted text more than once.
-
-@example
-divert(`1')
-This text is diverted first.
-divert(`0')undivert(`1')dnl
-@result{}
-@result{}This text is diverted first.
-undivert(`1')
-@result{}
-divert(`1')
-This text is also diverted but not appended.
-divert(`0')undivert(`1')dnl
-@result{}
-@result{}This text is also diverted but not appended.
-@end example
-
-Attempts to undivert the current diversion are silently ignored. Thus,
-when the current diversion is not 0, the current diversion does not get
-rearranged among the other diversions.
-
-@example
-divert(`1')one
-divert(`2')two
-divert(`3')three
-divert(`4')four
-divert(`5')five
-divert(`2')undivert(`5', `2', `4')dnl
-undivert`'dnl effectively undivert(`1', `2', `3', `4', `5')
-divert`'undivert`'dnl
-@result{}two
-@result{}five
-@result{}four
-@result{}one
-@result{}three
-@end example
-
-@cindex GNU extensions
-@cindex file inclusion
-@cindex inclusion, of files
-GNU @code{m4} allows named files to be undiverted. Given a
-non-numeric argument, the contents of the file named will be copied,
-uninterpreted, to the current output. This complements the builtin
-@code{include} (@pxref{Include}). To illustrate the difference, assume
-the file @file{foo} contains:
-
-@comment file: foo
-@example
-$ @kbd{cat foo}
-bar
-@end example
-
-@noindent
-then
-
-@example
-define(`bar', `BAR')
-@result{}
-undivert(`foo')
-@result{}bar
-@result{}
-include(`foo')
-@result{}BAR
-@result{}
-@end example
-
-If the file is not found (or cannot be read), an error message is
-issued, and the expansion is void. It is possible to intermix files
-and diversion numbers.
-
-@example
-divert(`1')diversion one
-divert(`2')undivert(`foo')dnl
-divert(`3')diversion three
-divert`'dnl
-undivert(`1', `2', `foo', `3')dnl
-@result{}diversion one
-@result{}bar
-@result{}bar
-@result{}diversion three
-@end example
-
-@node Divnum
-@section Diversion numbers
-
-@cindex diversion numbers
-The current diversion is tracked by the builtin @code{divnum}:
-
-@deffn {Builtin (m4)} divnum
-Expands to the number of the current diversion.
-@end deffn
-
-@example
-Initial divnum
-@result{}Initial 0
-divert(`1')
-Diversion one: divnum
-divert(`2')
-Diversion two: divnum
-^D
-@result{}
-@result{}Diversion one: 1
-@result{}
-@result{}Diversion two: 2
-@end example
-
-@node Cleardivert
-@section Discarding diverted text
-
-@cindex discarding diverted text
-@cindex diverted text, discarding
-Often it is not known, when output is diverted, whether the diverted
-text is actually needed. Since all non-empty diversion are brought back
-on the main output stream when the end of input is seen, a method of
-discarding a diversion is needed. If all diversions should be
-discarded, the easiest is to end the input to @code{m4} with
-@samp{divert(`-1')} followed by an explicit @samp{undivert}:
-
-@example
-divert(`1')
-Diversion one: divnum
-divert(`2')
-Diversion two: divnum
-divert(`-1')
-undivert
-^D
-@end example
-
-@noindent
-No output is produced at all.
-
-Clearing selected diversions can be done with the following macro:
-
-@deffn Composite cleardivert (@ovar{diversions@dots{}})
-Discard the contents of each of the listed numeric @var{diversions}.
-@end deffn
-
-@example
-define(`cleardivert',
-`pushdef(`_n', divnum)divert(`-1')undivert($@@)divert(_n)popdef(`_n')')
-@result{}
-@end example
-
-It is called just like @code{undivert}, but the effect is to clear the
-diversions, given by the arguments. (This macro has a nasty bug! You
-should try to see if you can find it and correct it; or @pxref{Improved
-cleardivert, , Answers}).
-
-@node Modules
-@chapter Extending M4 with dynamic runtime modules
-
-@cindex modules
-@cindex dynamic modules
-@cindex loadable modules
-GNU M4 1.4.x had a monolithic architecture. All of its
-functionality was contained in a single binary, and additional macros
-could be added only by writing more code in the M4 language, or at the
-extreme by hacking the sources and recompiling the whole thing to make
-a custom M4 installation.
-
-Starting with release 2.0, M4 supports and is composed of loadable modules.
-Additional modules can be loaded into the running M4 interpreter as it is
-started up at the command line, or during normal expansion of macros. This
-facilitates runtime extension of the M4 builtin macro list using compiled C
-code linked against a new shared library, typically named @file{libm4.so}.
-
-For example, you might want to add a @code{setenv} builtin to M4, to
-use before invoking @code{esyscmd}. We might write a @file{setenv.c}
-something like this:
-
-@comment ignore
-@example
-#include "m4module.h"
-
-M4BUILTIN(setenv);
-
-m4_builtin m4_builtin_table[] =
-@{
- /* name handler flags minargs maxargs */
- @{ "setenv", builtin_setenv, M4_BUILTIN_BLIND, 2, 3 @},
-
- @{ NULL, NULL, 0, 0, 0 @}
-@};
-
-/**
- * setenv(NAME, VALUE, [OVERWRITE])
- **/
-M4BUILTIN_HANDLER (setenv)
-@{
- int overwrite = 1;
-
- if (argc >= 4)
- if (!m4_numeric_arg (context, argc, argv, 3, &overwrite))
- return;
-
- setenv (M4ARG (1), M4ARG (2), overwrite);
-@}
-@end example
-
-Then, having compiled and linked the module, in (somewhat contrived)
-M4 code:
-
-@comment ignore
-@example
-$ @kbd{m4 setenv}
-setenv(`PATH', `/sbin:/bin:/usr/sbin:/usr/bin')
-@result{}
-esyscmd(`ifconfig -a')dnl
-@result{}@dots{}
-@end example
-
-Or instead of loading the module from the M4 invocation, you can use
-the @code{include} builtin:
-
-@comment ignore
-@example
-$ @kbd{m4}
-include(`setenv')
-@result{}
-setenv(`PATH', `/sbin:/bin:/usr/sbin:/usr/bin')
-@result{}
-@end example
-
-Also, at run time, you can choose which core modules to load. SUSv3 M4
-functionality is contained in the module @samp{m4}, GNU extensions in the
-module @samp{gnu}, and so on. All of the builtin descriptions in this manual
-are annotated with the module from which they are loaded -- mostly from the
-module @samp{m4}.
-
-When you start GNU M4, the modules @samp{m4} and @samp{gnu} are
-loaded by default. If you supply the @option{-G} option at startup, the
-module @samp{traditional} is loaded instead of @samp{gnu}.
-@xref{Compatibility}, for more details on the differences between these
-two modes of startup.
-
-@menu
-* M4modules:: Listing loaded modules
-* Standard Modules:: Standard bundled modules
-@end menu
-
-@node M4modules
-@section Listing loaded modules
-
-@deffn {Builtin (gnu)} m4modules
-Expands to a quoted ordered list of currently loaded modules,
-with the most recently loaded module at the front of the list. Loading
-a module multiple times will not affect the order of this list, the
-position depends on when the module was @emph{first} loaded.
-@end deffn
-
-For example, after GNU @code{m4} is started with no additional modules,
-@code{m4modules} will yield the following:
-
-@example
-$ @kbd{m4}
-m4modules
-@result{}gnu,m4
-@end example
-
-@node Standard Modules
-@section Standard bundled modules
-
-GNU @code{m4} ships with several bundled modules as standard.
-By convention, these modules define a text macro that can be tested
-with @code{ifdef} when they are loaded; only the @code{m4} module lacks
-this feature test macro, since it is not permitted by POSIX.
-Each of the feature test macros are intended to be used without
-arguments.
-
-@table @code
-@item m4
-Provides all of the builtins defined by POSIX. This module
-is always loaded --- GNU @code{m4} would only be a very slow
-version of @command{cat} without the builtins supplied by this module.
-
-@item gnu
-Provides all of the GNU extensions, as defined by
-GNU M4 through the 1.4.x release series. It also provides a
-couple of feature test macros:
-
-@deffn {Macro (gnu)} __gnu__
-Expands to the empty string, as an indication that the @samp{gnu}
-module is loaded.
-@end deffn
-
-@deffn {Macro (gnu)} __m4_version__
-Expands to an unquoted string containing the release version number of
-the running GNU @code{m4} executable.
-@end deffn
-
-This module is always loaded, unless the @option{-G} command line
-option is supplied at startup (@pxref{Limits control, , Invoking m4}).
-
-@item traditional
-This module provides compatibility with System V @code{m4}, for anything
-not specified by POSIX, and is loaded instead of the
-@samp{gnu} module if the @option{-G} command line option is specified.
-
-@deffn {Macro (traditional)} __traditional__
-Expands to the empty string, as an indication that the
-@samp{traditional} module is loaded.
-@end deffn
-
-@item mpeval
-This module provides the implementation for the experimental
-@code{mpeval} feature. If the host machine does not have the
-GNU gmp library, the builtin will generate an error if called.
-@xref{Mpeval}, for more details. The module also defines the following
-macro:
-
-@deffn {Macro (mpeval)} __mpeval__
-Expands to the empty string, as an indication that the @samp{mpeval}
-module is loaded.
-@end deffn
-@end table
-
-Here is an example of using the feature test macros.
-
-@example
-$ @kbd{m4}
-__gnu__-__traditional__
-@result{}-__traditional__
-ifdef(`__gnu__', `Extensions are active', `Minimal features')
-@result{}Extensions are active
-__gnu__(`ignored')
-@error{}m4:stdin:3: warning: __gnu__: extra arguments ignored: 1 > 0
-@result{}
-@end example
-
-@comment options: -G
-@example
-$ @kbd{m4 --traditional}
-__gnu__-__traditional__
-@result{}__gnu__-
-ifdef(`__gnu__', `Extensions are active', `Minimal features')
-@result{}Minimal features
-@end example
-
-Since the version string is unquoted and can potentially contain macro
-names (for example, a beta release could be numbered @samp{1.9b}), or be
-impacted by the use of @code{changesyntax}), the
-@code{__m4_version__} macro should generally be used via @code{defn}
-rather than directly invoked (@pxref{Defn}). In general, feature tests
-are more reliable than version number checks, so exercise caution when
-using this macro.
-
-@comment This test is excluded from the testsuite since it depends on a
-@comment texinfo macro; but builtins.at covers the same thing.
-@comment ignore
-@example
-defn(`__m4_version__')
-@result{}@value{VERSION}
-@end example
-
-@node Text handling
-@chapter Macros for text handling
-
-There are a number of builtins in @code{m4} for manipulating text in
-various ways, extracting substrings, searching, substituting, and so on.
-
-@menu
-* Len:: Calculating length of strings
-* Index macro:: Searching for substrings
-* Regexp:: Searching for regular expressions
-* Substr:: Extracting substrings
-* Translit:: Translating characters
-* Patsubst:: Substituting text by regular expression
-* Format:: Formatting strings (printf-like)
-@end menu
-
-@node Len
-@section Calculating length of strings
-
-@cindex length of strings
-@cindex strings, length of
-The length of a string can be calculated by @code{len}:
-
-@deffn {Builtin (m4)} len (@var{string})
-Expands to the length of @var{string}, as a decimal number.
-
-The macro @code{len} is recognized only with parameters.
-@end deffn
-
-@example
-len()
-@result{}0
-len(`abcdef')
-@result{}6
-@end example
-
-@node Index macro
-@section Searching for substrings
-
-@cindex substrings, locating
-Searching for substrings is done with @code{index}:
-
-@deffn {Builtin (m4)} index (@var{string}, @var{substring}, @ovar{offset})
-Expands to the index of the first occurrence of @var{substring} in
-@var{string}. The first character in @var{string} has index 0. If
-@var{substring} does not occur in @var{string}, @code{index} expands to
-@samp{-1}. If @var{offset} is provided, it determines the index at
-which the search starts; a negative @var{offset} specifies the offset
-relative to the end of @var{string}.
-
-The macro @code{index} is recognized only with parameters.
-@end deffn
-
-@example
-index(`gnus, gnats, and armadillos', `nat')
-@result{}7
-index(`gnus, gnats, and armadillos', `dag')
-@result{}-1
-@end example
-
-Omitting @var{substring} evokes a warning, but still produces output;
-contrast this with an empty @var{substring}.
-
-@example
-index(`abc')
-@error{}m4:stdin:1: warning: index: too few arguments: 1 < 2
-@result{}0
-index(`abc', `')
-@result{}0
-index(`abc', `b')
-@result{}1
-@end example
-
-@cindex GNU extensions
-As an extension, an @var{offset} can be provided to limit the search to
-the tail of the @var{string}. A negative offset is interpreted relative
-to the end of @var{string}, and it is not an error if @var{offset}
-exceeds the bounds of @var{string}.
-
-@example
-index(`aba', `a', `1')
-@result{}2
-index(`ababa', `ba', `-3')
-@result{}3
-index(`abc', `ab', `4')
-@result{}-1
-index(`abc', `bc', `-4')
-@result{}1
-@end example
-
-@ignore
-@comment Expose a bug in the strstr() algorithm present in glibc
-@comment 2.9 through 2.12 and in gnulib up to Sep 2010.
-
-@example
-index(`;:11-:12-:12-:12-:12-:12-:12-:12-:12.:12.:12.:12.:12.:12.:12.:12.:12-:',
-`:12-:12-:12-:12-:12-:12-:12-:12-')
-@result{}-1
-@end example
-
-@comment Expose a bug in the gnulib replacement strstr() algorithm
-@comment present from Jun 2010 to Feb 2011, including m4 1.4.15.
-
-@example
-index(`..wi.d.', `.d.')
-@result{}4
-@end example
-@end ignore
-
-@node Regexp
-@section Searching for regular expressions
-
-@cindex regular expressions
-@cindex expressions, regular
-@cindex GNU extensions
-Searching for regular expressions is done with the builtin
-@code{regexp}:
-
-@deffn {Builtin (gnu)} regexp (@var{string}, @var{regexp}, @var{resyntax})
-@deffnx {Builtin (gnu)} regexp (@var{string}, @var{regexp}, @
- @ovar{replacement}, @ovar{resyntax})
-Searches for @var{regexp} in @var{string}.
-
-If @var{resyntax} is given, the particular flavor of regular expression
-understood with respect to @var{regexp} can be changed from the current
-default. @xref{Changeresyntax}, for details of the values that can be
-given for this argument. If exactly three arguments given, then the
-third argument is treated as @var{resyntax} only if it matches a known
-syntax name, otherwise it is treated as @var{replacement}.
-
-If @var{replacement} is omitted, @code{regexp} expands to the index of
-the first match of @var{regexp} in @var{string}. If @var{regexp} does
-not match anywhere in @var{string}, it expands to -1.
-
-If @var{replacement} is supplied, and there was a match, @code{regexp}
-changes the expansion to this argument, with @samp{\@var{n}} substituted
-by the text matched by the @var{n}th parenthesized sub-expression of
-@var{regexp}, up to nine sub-expressions. The escape @samp{\&} is
-replaced by the text of the entire regular expression matched. For
-all other characters, @samp{\} treats the next character literally. A
-warning is issued if there were fewer sub-expressions than the
-@samp{\@var{n}} requested, or if there is a trailing @samp{\}. If there
-was no match, @code{regexp} expands to the empty string.
-
-The macro @code{regexp} is recognized only with parameters.
-@end deffn
-
-@example
-regexp(`GNUs not Unix', `\<[a-z]\w+')
-@result{}5
-regexp(`GNUs not Unix', `\<Q\w*')
-@result{}-1
-regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
-@result{}*** Unix *** nix ***
-regexp(`GNUs not Unix', `\<Q\w*', `*** \& *** \1 ***')
-@result{}
-@end example
-
-Here are some more examples on the handling of backslash:
-
-@example
-regexp(`abc', `\(b\)', `\\\10\a')
-@result{}\b0a
-regexp(`abc', `b', `\1\')
-@error{}m4:stdin:2: warning: regexp: sub-expression 1 not present
-@error{}m4:stdin:2: warning: regexp: trailing \ ignored in replacement
-@result{}
-regexp(`abc', `\(\(d\)?\)\(c\)', `\1\2\3\4\5\6')
-@error{}m4:stdin:3: warning: regexp: sub-expression 4 not present
-@error{}m4:stdin:3: warning: regexp: sub-expression 5 not present
-@error{}m4:stdin:3: warning: regexp: sub-expression 6 not present
-@result{}c
-@end example
-
-Omitting @var{regexp} evokes a warning, but still produces output;
-contrast this with an empty @var{regexp} argument.
-
-@example
-regexp(`abc')
-@error{}m4:stdin:1: warning: regexp: too few arguments: 1 < 2
-@result{}0
-regexp(`abc', `')
-@result{}0
-regexp(`abc', `', `\\def')
-@result{}\def
-@end example
-
-If @var{resyntax} is given, @var{regexp} must be given according to
-the syntax chosen, though the default regular expression syntax
-remains unchanged for other invocations:
-
-@example
-regexp(`GNUs not Unix', `\w(\w+)$', `*** \& *** \1 ***',
- `POSIX_EXTENDED')
-@result{}*** Unix *** nix ***
-regexp(`GNUs not Unix', `\w(\w+)$', `*** \& *** \1 ***')
-@result{}
-@end example
-
-Occasionally, you might want to pass an @var{resyntax} argument without
-wishing to give @var{replacement}. If there are exactly three
-arguments, and the last argument is a valid @var{resyntax}, it is used
-as such, rather than as a replacement.
-
-@example
-regexp(`GNUs not Unix', `\w(\w+)$', `POSIX_EXTENDED')
-@result{}9
-regexp(`GNUs not Unix', `\w(\w+)$', `POSIX_EXTENDED', `POSIX_EXTENDED')
-@result{}POSIX_EXTENDED
-regexp(`GNUs not Unix', `\w(\w+)$', `POSIX_EXTENDED', `')
-@result{}
-regexp(`GNUs not Unix', `\w\(\w+\)$', `POSIX_EXTENDED', `')
-@result{}POSIX_EXTENDED
-@end example
-
-@node Substr
-@section Extracting substrings
-
-@cindex extracting substrings
-@cindex substrings, extracting
-Substrings are extracted with @code{substr}:
-
-@deffn {Builtin (m4)} substr (@var{string}, @var{from}, @ovar{length}, @
- @ovar{replace})
-Performs a substring operation on @var{string}. If @var{from} is
-positive, it represents the 0-based index where the substring begins.
-If @var{length} is omitted, the substring ends at the end of
-@var{string}; if it is positive, @var{length} is added to the starting
-index to determine the ending index.
-
-@cindex GNU extensions
-As a GNU extension, if @var{from} is negative, it is added to
-the length of @var{string} to determine the starting index; if it is
-empty, the start of the string is used. Likewise, if @var{length} is
-negative, it is added to the length of @var{string} to determine the
-ending index, and an emtpy @var{length} behaves like an omitted
-@var{length}. It is not an error if either of the resulting indices lie
-outside the string, but the selected substring only contains the bytes
-of @var{string} that overlap the selected indices. If the end point
-lies before the beginning point, the substring chosen is the empty
-string located at the starting index.
-
-If @var{replace} is omitted, then the expansion is only the selected
-substring, which may be empty. As a GNU extension,if
-@var{replace} is provided, then the expansion is the original
-@var{string} with the selected substring replaced by @var{replace}. The
-expansion is empty and a warning issued if @var{from} or @var{length}
-cannot be parsed, or if @var{replace} is provided but the selected
-indices do not overlap with @var{string}.
-
-The macro @code{substr} is recognized only with parameters.
-@end deffn
-
-@example
-substr(`gnus, gnats, and armadillos', `6')
-@result{}gnats, and armadillos
-substr(`gnus, gnats, and armadillos', `6', `5')
-@result{}gnats
-@end example
-
-Omitting @var{from} evokes a warning, but still produces output. On the
-other hand, selecting a @var{from} or @var{length} that lies beyond
-@var{string} is not a problem.
-
-@example
-substr(`abc')
-@error{}m4:stdin:1: warning: substr: too few arguments: 1 < 2
-@result{}abc
-substr(`abc', `')
-@result{}abc
-substr(`abc', `4')
-@result{}
-substr(`abc', `1', `4')
-@result{}bc
-@end example
-
-Using negative values for @var{from} or @var{length} are GNU
-extensions, useful for accessing a fixed size tail of an
-arbitrary-length string. Prior to M4 1.6, using these values would
-silently result in the empty string. Some other implementations crash
-on negative values, and many treat an explicitly empty @var{length} as
-0, which is different from the omitted @var{length} implying the rest of
-the original @var{string}.
-
-@example
-substr(`abcde', `2', `')
-@result{}cde
-substr(`abcde', `-3')
-@result{}cde
-substr(`abcde', `', `-3')
-@result{}ab
-substr(`abcde', `-6')
-@result{}abcde
-substr(`abcde', `-6', `5')
-@result{}abcd
-substr(`abcde', `-7', `1')
-@result{}
-substr(`abcde', `1', `-2')
-@result{}bc
-substr(`abcde', `-4', `-1')
-@result{}bcd
-substr(`abcde', `4', `-3')
-@result{}
-substr(`abcdefghij', `-09', `08')
-@result{}bcdefghi
-@end example
-
-Another useful GNU extension, also added in M4 1.6, is the
-ability to replace a substring within the original @var{string}. An
-empty length substring at the beginning or end of @var{string} is valid,
-but selecting a substring that does not overlap @var{string} causes a
-warning.
-
-@example
-substr(`abcde', `1', `3', `t')
-@result{}ate
-substr(`abcde', `5', `', `f')
-@result{}abcdef
-substr(`abcde', `-3', `-4', `f')
-@result{}abfcde
-substr(`abcde', `-6', `1', `f')
-@result{}fabcde
-substr(`abcde', `-7', `1', `f')
-@error{}m4:stdin:5: warning: substr: substring out of range
-@result{}
-substr(`abcde', `6', `', `f')
-@error{}m4:stdin:6: warning: substr: substring out of range
-@result{}
-@end example
-
-If backwards compabitility to M4 1.4.x behavior is necessary, the
-following macro is sufficient to do the job (mimicking warnings about
-empty @var{from} or @var{length} or an ignored fourth argument is left
-as an exercise to the reader).
-
-@example
-define(`substr', `ifelse(`$#', `0', ``$0'',
- eval(`2 < $#')`$3', `1', `',
- index(`$2$3', `-'), `-1', `builtin(`$0', `$1', `$2', `$3')')')
-@result{}
-substr(`abcde', `3')
-@result{}de
-substr(`abcde', `3', `')
-@result{}
-substr(`abcde', `-1')
-@result{}
-substr(`abcde', `1', `-1')
-@result{}
-substr(`abcde', `2', `1', `C')
-@result{}c
-@end example
-
-On the other hand, it is possible to portably emulate the GNU
-extension of negative @var{from} and @var{length} arguments across all
-@code{m4} implementations, albeit with a lot more overhead. This
-example uses @code{incr} and @code{decr} to normalize @samp{-08} to
-something that a later @code{eval} will treat as a decimal value, rather
-than looking like an invalid octal number, while avoiding using these
-macros on an empty string. The helper macro @code{_substr_normalize} is
-recursive, since it is easier to fix @var{length} after @var{from} has
-been normalized, with the final iteration supplying two non-negative
-arguments to the original builtin, now named @code{_substr}.
-
-@comment options: -daq -t_substr
-@example
-$ @kbd{m4 -daq -t _substr}
-define(`_substr', defn(`substr'))dnl
-define(`substr', `ifelse(`$#', `0', ``$0'',
- `_$0(`$1', _$0_normalize(len(`$1'),
- ifelse(`$2', `', `0', `incr(decr(`$2'))'),
- ifelse(`$3', `', `', `incr(decr(`$3'))')))')')dnl
-define(`_substr_normalize', `ifelse(
- eval(`$2 < 0 && $1 + $2 >= 0'), `1',
- `$0(`$1', eval(`$1 + $2'), `$3')',
- eval(`$2 < 0')`$3', `1', ``0', `$1'',
- eval(`$2 < 0 && $3 - 0 >= 0 && $1 + $2 + $3 - 0 >= 0'), `1',
- `$0(`$1', `0', eval(`$1 + $2 + $3 - 0'))',
- eval(`$2 < 0 && $3 - 0 >= 0'), `1', ``0', `0'',
- eval(`$2 < 0'), `1', `$0(`$1', `0', `$3')',
- `$3', `', ``$2', `$1'',
- eval(`$3 - 0 < 0 && $1 - $2 + $3 - 0 >= 0'), `1',
- ``$2', eval(`$1 - $2 + $3')',
- eval(`$3 - 0 < 0'), `1', ``$2', `0'',
- ``$2', `$3'')')dnl
-substr(`abcde', `2', `')
-@error{}m4trace: -1- _substr(`abcde', `2', `5')
-@result{}cde
-substr(`abcde', `-3')
-@error{}m4trace: -1- _substr(`abcde', `2', `5')
-@result{}cde
-substr(`abcde', `', `-3')
-@error{}m4trace: -1- _substr(`abcde', `0', `2')
-@result{}ab
-substr(`abcde', `-6')
-@error{}m4trace: -1- _substr(`abcde', `0', `5')
-@result{}abcde
-substr(`abcde', `-6', `5')
-@error{}m4trace: -1- _substr(`abcde', `0', `4')
-@result{}abcd
-substr(`abcde', `-7', `1')
-@error{}m4trace: -1- _substr(`abcde', `0', `0')
-@result{}
-substr(`abcde', `1', `-2')
-@error{}m4trace: -1- _substr(`abcde', `1', `2')
-@result{}bc
-substr(`abcde', `-4', `-1')
-@error{}m4trace: -1- _substr(`abcde', `1', `3')
-@result{}bcd
-substr(`abcde', `4', `-3')
-@error{}m4trace: -1- _substr(`abcde', `4', `0')
-@result{}
-substr(`abcdefghij', `-09', `08')
-@error{}m4trace: -1- _substr(`abcdefghij', `1', `8')
-@result{}bcdefghi
-@end example
-
-@node Translit
-@section Translating characters
-
-@cindex translating characters
-@cindex characters, translating
-Character translation is done with @code{translit}:
-
-@deffn {Builtin (m4)} translit (@var{string}, @var{chars}, @ovar{replacement})
-Expands to @var{string}, with each character that occurs in
-@var{chars} translated into the character from @var{replacement} with
-the same index.
-
-If @var{replacement} is shorter than @var{chars}, the excess characters
-of @var{chars} are deleted from the expansion; if @var{chars} is
-shorter, the excess characters in @var{replacement} are silently
-ignored. If @var{replacement} is omitted, all characters in
-@var{string} that are present in @var{chars} are deleted from the
-expansion. If a character appears more than once in @var{chars}, only
-the first instance is used in making the translation. Only a single
-translation pass is made, even if characters in @var{replacement} also
-appear in @var{chars}.
-
-As a GNU extension, both @var{chars} and @var{replacement} can
-contain character-ranges, e.g., @samp{a-z} (meaning all lowercase
-letters) or @samp{0-9} (meaning all digits). To include a dash @samp{-}
-in @var{chars} or @var{replacement}, place it first or last in the
-entire string, or as the last character of a range. Back-to-back ranges
-can share a common endpoint. It is not an error for the last character
-in the range to be `larger' than the first. In that case, the range
-runs backwards, i.e., @samp{9-0} means the string @samp{9876543210}.
-The expansion of a range is dependent on the underlying encoding of
-characters, so using ranges is not always portable between machines.
-
-The macro @code{translit} is recognized only with parameters.
-@end deffn
-
-@example
-translit(`GNUs not Unix', `A-Z')
-@result{}s not nix
-translit(`GNUs not Unix', `a-z', `A-Z')
-@result{}GNUS NOT UNIX
-translit(`GNUs not Unix', `A-Z', `z-a')
-@result{}tmfs not fnix
-translit(`+,-12345', `+--1-5', `<;>a-c-a')
-@result{}<;>abcba
-translit(`abcdef', `aabdef', `bcged')
-@result{}bgced
-@end example
-
-In the @sc{ascii} encoding, the first example deletes all uppercase
-letters, the second converts lowercase to uppercase, and the third
-`mirrors' all uppercase letters, while converting them to lowercase.
-The two first cases are by far the most common, even though they are not
-portable to @sc{ebcdic} or other encodings. The fourth example shows a
-range ending in @samp{-}, as well as back-to-back ranges. The final
-example shows that @samp{a} is mapped to @samp{b}, not @samp{c}; the
-resulting @samp{b} is not further remapped to @samp{g}; the @samp{d} and
-@samp{e} are swapped, and the @samp{f} is discarded.
-
-Omitting @var{chars} evokes a warning, but still produces output.
-
-@example
-translit(`abc')
-@error{}m4:stdin:1: warning: translit: too few arguments: 1 < 2
-@result{}abc
-@end example
-
-@node Patsubst
-@section Substituting text by regular expression
-
-@cindex regular expressions
-@cindex expressions, regular
-@cindex pattern substitution
-@cindex substitution by regular expression
-@cindex GNU extensions
-Global substitution in a string is done by @code{patsubst}:
-
-@deffn {Builtin (gnu)} patsubst (@var{string}, @var{regexp}, @
- @ovar{replacement}, @ovar{resyntax})
-Searches @var{string} for matches of @var{regexp}, and substitutes
-@var{replacement} for each match.
-
-If @var{resyntax} is given, the particular flavor of regular expression
-understood with respect to @var{regexp} can be changed from the current
-default. @xref{Changeresyntax}, for details of the values that can be
-given for this argument. Unlike @var{regexp}, if exactly three
-arguments given, the third argument is always treated as
-@var{replacement}, even if it matches a known syntax name.
-
-The parts of @var{string} that are not covered by any match of
-@var{regexp} are copied to the expansion. Whenever a match is found, the
-search proceeds from the end of the match, so a character from
-@var{string} will never be substituted twice. If @var{regexp} matches a
-string of zero length, the start position for the search is incremented,
-to avoid infinite loops.
-
-When a replacement is to be made, @var{replacement} is inserted into
-the expansion, with @samp{\@var{n}} substituted by the text matched by
-the @var{n}th parenthesized sub-expression of @var{patsubst}, for up to
-nine sub-expressions. The escape @samp{\&} is replaced by the text of
-the entire regular expression matched. For all other characters,
-@samp{\} treats the next character literally. A warning is issued if
-there were fewer sub-expressions than the @samp{\@var{n}} requested, or
-if there is a trailing @samp{\}.
-
-The @var{replacement} argument can be omitted, in which case the text
-matched by @var{regexp} is deleted.
-
-The macro @code{patsubst} is recognized only with parameters.
-@end deffn
-
-When used with two arguments, @code{regexp} returns the position of the
-match, but @code{patsubst} deletes the match:
-
-@example
-patsubst(`GNUs not Unix', `^', `OBS: ')
-@result{}OBS: GNUs not Unix
-patsubst(`GNUs not Unix', `\<', `OBS: ')
-@result{}OBS: GNUs OBS: not OBS: Unix
-patsubst(`GNUs not Unix', `\w*', `(\&)')
-@result{}(GNUs)() (not)() (Unix)()
-patsubst(`GNUs not Unix', `\w+', `(\&)')
-@result{}(GNUs) (not) (Unix)
-patsubst(`GNUs not Unix', `[A-Z][a-z]+')
-@result{}GN not@w{ }
-patsubst(`GNUs not Unix', `not', `NOT\')
-@error{}m4:stdin:6: warning: patsubst: trailing \ ignored in replacement
-@result{}GNUs NOT Unix
-@end example
-
-Here is a slightly more realistic example, which capitalizes individual
-words or whole sentences, by substituting calls of the macros
-@code{upcase} and @code{downcase} into the strings.
-
-@deffn Composite upcase (@var{text})
-@deffnx Composite downcase (@var{text})
-@deffnx Composite capitalize (@var{text})
-Expand to @var{text}, but with capitalization changed: @code{upcase}
-changes all letters to upper case, @code{downcase} changes all letters
-to lower case, and @code{capitalize} changes the first character of each
-word to upper case and the remaining characters to lower case.
-@end deffn
-
-First, an example of their usage, using implementations distributed in
-@file{m4-@value{VERSION}/@/doc/examples/@/capitalize.m4}.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`capitalize.m4')
-@result{}
-upcase(`GNUs not Unix')
-@result{}GNUS NOT UNIX
-downcase(`GNUs not Unix')
-@result{}gnus not unix
-capitalize(`GNUs not Unix')
-@result{}Gnus Not Unix
-@end example
-
-Now for the implementation. There is a helper macro @code{_capitalize}
-which puts only its first word in mixed case. Then @code{capitalize}
-merely parses out the words, and replaces them with an invocation of
-@code{_capitalize}. (As presented here, the @code{capitalize} macro has
-some subtle flaws. You should try to see if you can find and correct
-them; or @pxref{Improved capitalize, , Answers}).
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`capitalize.m4')dnl
-@result{}divert(`-1')
-@result{}# upcase(text)
-@result{}# downcase(text)
-@result{}# capitalize(text)
-@result{}# change case of text, simple version
-@result{}define(`upcase', `translit(`$*', `a-z', `A-Z')')
-@result{}define(`downcase', `translit(`$*', `A-Z', `a-z')')
-@result{}define(`_capitalize',
-@result{} `regexp(`$1', `^\(\w\)\(\w*\)',
-@result{} `upcase(`\1')`'downcase(`\2')')')
-@result{}define(`capitalize', `patsubst(`$1', `\w+', `_$0(`\&')')')
-@result{}divert`'dnl
-@end example
-
-If @var{resyntax} is given, @var{regexp} must be given according to
-the syntax chosen, though the default regular expression syntax
-remains unchanged for other invocations:
-
-@example
-define(`epatsubst',
- `builtin(`patsubst', `$1', `$2', `$3', `POSIX_EXTENDED')')dnl
-epatsubst(`bar foo baz Foo', `(\w*) (foo|Foo)', `_\1_')
-@result{}_bar_ _baz_
-patsubst(`bar foo baz Foo', `\(\w*\) \(foo\|Foo\)', `_\1_')
-@result{}_bar_ _baz_
-@end example
-
-While @code{regexp} replaces the whole input with the replacement as
-soon as there is a match, @code{patsubst} replaces each
-@emph{occurrence} of a match and preserves non-matching pieces:
-
-@example
-define(`patreg',
-`patsubst($@@)
-regexp($@@)')dnl
-patreg(`bar foo baz Foo', `foo\|Foo', `FOO')
-@result{}bar FOO baz FOO
-@result{}FOO
-patreg(`aba abb 121', `\(.\)\(.\)\1', `\2\1\2')
-@result{}bab abb 212
-@result{}bab
-@end example
-
-Omitting @var{regexp} evokes a warning, but still produces output;
-contrast this with an empty @var{regexp} argument.
-
-@example
-patsubst(`abc')
-@error{}m4:stdin:1: warning: patsubst: too few arguments: 1 < 2
-@result{}abc
-patsubst(`abc', `')
-@result{}abc
-patsubst(`abc', `', `\\-')
-@result{}\-a\-b\-c\-
-@end example
-
-@node Format
-@section Formatting strings (printf-like)
-
-@cindex formatted output
-@cindex output, formatted
-@cindex GNU extensions
-Formatted output can be made with @code{format}:
-
-@deffn {Builtin (gnu)} format (@var{format-string}, @dots{})
-Works much like the C function @code{printf}. The first argument
-@var{format-string} can contain @samp{%} specifications which are
-satisfied by additional arguments, and the expansion of @code{format} is
-the formatted string.
-
-The macro @code{format} is recognized only with parameters.
-@end deffn
-
-Its use is best described by a few examples:
-
-@comment This test is a bit fragile, if someone tries to port to a
-@comment platform without infinity.
-@example
-define(`foo', `The brown fox jumped over the lazy dog')
-@result{}
-format(`The string "%s" uses %d characters', foo, len(foo))
-@result{}The string "The brown fox jumped over the lazy dog" uses 38 characters
-format(`%*.*d', `-1', `-1', `1')
-@result{}1
-format(`%.0f', `56789.9876')
-@result{}56790
-len(format(`%-*X', `5000', `1'))
-@result{}5000
-ifelse(format(`%010F', `infinity'), ` INF', `success',
- format(`%010F', `infinity'), ` INFINITY', `success',
- format(`%010F', `infinity'))
-@result{}success
-ifelse(format(`%.1A', `1.999'), `0X1.0P+1', `success',
- format(`%.1A', `1.999'), `0X2.0P+0', `success',
- format(`%.1A', `1.999'))
-@result{}success
-format(`%g', `0xa.P+1')
-@result{}20
-@end example
-
-Using the @code{forloop} macro defined earlier (@pxref{Forloop}), this
-example shows how @code{format} can be used to produce tabular output.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`forloop.m4')
-@result{}
-forloop(`i', `1', `10', `format(`%6d squared is %10d
-', i, eval(i**2))')
-@result{} 1 squared is 1
-@result{} 2 squared is 4
-@result{} 3 squared is 9
-@result{} 4 squared is 16
-@result{} 5 squared is 25
-@result{} 6 squared is 36
-@result{} 7 squared is 49
-@result{} 8 squared is 64
-@result{} 9 squared is 81
-@result{} 10 squared is 100
-@result{}
-@end example
-
-The builtin @code{format} is modeled after the ANSI C @samp{printf}
-function, and supports these @samp{%} specifiers: @samp{c}, @samp{s},
-@samp{d}, @samp{o}, @samp{x}, @samp{X}, @samp{u}, @samp{a}, @samp{A},
-@samp{e}, @samp{E}, @samp{f}, @samp{F}, @samp{g}, @samp{G}, and
-@samp{%}; it supports field widths and precisions, and the flags
-@samp{+}, @samp{-}, @samp{ }, @samp{0}, @samp{#}, and @samp{'}. For
-integer specifiers, the width modifiers @samp{hh}, @samp{h}, and
-@samp{l} are recognized, and for floating point specifiers, the width
-modifier @samp{l} is recognized. Items not yet supported include
-positional arguments, the @samp{n}, @samp{p}, @samp{S}, and @samp{C}
-specifiers, the @samp{z}, @samp{t}, @samp{j}, @samp{L} and @samp{ll}
-modifiers, and any platform extensions available in the native
-@code{printf}. For more details on the functioning of @code{printf},
-see the C Library Manual, or the POSIX specification (for
-example, @samp{%a} is supported even on platforms that haven't yet
-implemented C99 hexadecimal floating point output natively).
-
-@c FIXME - format still needs some improvements.
-Warnings are issued for unrecognized specifiers, an improper number of
-arguments, or difficulty parsing an argument according to the format
-string (such as overflow or extra characters). It is anticipated that a
-future release of GNU @code{m4} will support more specifiers.
-Likewise, escape sequences are not yet recognized.
-
-@example
-format(`%p', `0')
-@error{}m4:stdin:1: warning: format: unrecognized specifier in '%p'
-@result{}
-format(`%*d', `')
-@error{}m4:stdin:2: warning: format: empty string treated as 0
-@error{}m4:stdin:2: warning: format: too few arguments: 2 < 3
-@result{}0
-format(`%.1f', `2a')
-@error{}m4:stdin:3: warning: format: non-numeric argument '2a'
-@result{}2.0
-@end example
-
-@ignore
-@comment Expose a crash with a bad format string fixed in 1.4.15.
-@comment Unfortunately, 8-bit bytes are hard to check for; but the
-@comment exit status is enough to sniff the crash in broken versions.
-
-@example
-format(`%'format(`%c', `128'))
-@result{}
-@error{}ignore
-@end example
-@end ignore
-
-@node Arithmetic
-@chapter Macros for doing arithmetic
-
-@cindex arithmetic
-@cindex integer arithmetic
-Integer arithmetic is included in @code{m4}, with a C-like syntax. As
-convenient shorthands, there are builtins for simple increment and
-decrement operations.
-
-@menu
-* Incr:: Decrement and increment operators
-* Eval:: Evaluating integer expressions
-* Mpeval:: Multiple precision arithmetic
-@end menu
-
-@node Incr
-@section Decrement and increment operators
-
-@cindex decrement operator
-@cindex increment operator
-Increment and decrement of integers are supported using the builtins
-@code{incr} and @code{decr}:
-
-@deffn {Builtin (m4)} incr (@var{number})
-@deffnx {Builtin (m4)} decr (@var{number})
-Expand to the numerical value of @var{number}, incremented
-or decremented, respectively, by one. Except for the empty string, the
-expansion is empty if @var{number} could not be parsed.
-
-The macros @code{incr} and @code{decr} are recognized only with
-parameters.
-@end deffn
-
-@example
-incr(`4')
-@result{}5
-decr(`7')
-@result{}6
-incr()
-@error{}m4:stdin:3: warning: incr: empty string treated as 0
-@result{}1
-decr()
-@error{}m4:stdin:4: warning: decr: empty string treated as 0
-@result{}-1
-@end example
-
-The builtin macros @code{incr} and @code{decr} are recognized only when
-given arguments.
-
-@node Eval
-@section Evaluating integer expressions
-
-@cindex integer expression evaluation
-@cindex evaluation, of integer expressions
-@cindex expressions, evaluation of integer
-Integer expressions are evaluated with @code{eval}:
-
-@deffn {Builtin (m4)} eval (@var{expression}, @dvar{radix, 10}, @ovar{width})
-Expands to the value of @var{expression}. The expansion is empty
-if a problem is encountered while parsing the arguments. If specified,
-@var{radix} and @var{width} control the format of the output.
-
-Calculations are done with signed numbers, using at least 31-bit
-precision, but as a GNU extension, @code{m4} will use wider
-integers if available. Precision is finite, based on the platform's
-notion of @code{intmax_t}, and overflow silently results in wraparound.
-A warning is issued if division by zero is attempted, or if
-@var{expression} could not be parsed.
-
-Expressions can contain the following operators, listed in order of
-decreasing precedence.
-
-@table @samp
-@item ()
-Parentheses
-@item + - ~ !
-Unary plus and minus, and bitwise and logical negation
-@item **
-Exponentiation
-@item * / % \
-Multiplication, division, modulo, and ratio
-@item + -
-Addition and subtraction
-@item << >> >>>
-Shift left, shift right, unsigned shift right
-@item > >= < <=
-Relational operators
-@item == !=
-Equality operators
-@item &
-Bitwise and
-@item ^
-Bitwise exclusive-or
-@item |
-Bitwise or
-@item &&
-Logical and
-@item ||
-Logical or
-@item ?:
-Conditional ternary
-@item ,
-Sequential evaluation
-@end table
-
-The macro @code{eval} is recognized only with parameters.
-@end deffn
-
-All binary operators, except exponentiation, are left associative. C
-operators that perform variable assignment, such as @samp{+=} or
-@samp{--}, are not implemented, since @code{eval} only operates on
-constants, not variables. Attempting to use them results in an error.
-@comment FIXME - since XCU ERN 137 is approved, we could provide an
-@comment extension that supported assignment operators.
-
-Note that some older @code{m4} implementations use @samp{^} as an
-alternate operator for the exponentiation, although POSIX
-requires the C behavior of bitwise exclusive-or. The precedence of the
-negation operators, @samp{~} and @samp{!}, was traditionally lower than
-equality. The unary operators could not be used reliably more than once
-on the same term without intervening parentheses. The traditional
-precedence of the equality operators @samp{==} and @samp{!=} was
-identical instead of lower than the relational operators such as
-@samp{<}, even through GNU M4 1.4.8. Starting with version
-1.4.9, GNU M4 correctly follows POSIX precedence
-rules. M4 scripts designed to be portable between releases must be
-aware that parentheses may be required to enforce C precedence rules.
-Likewise, division by zero, even in the unused branch of a
-short-circuiting operator, is not always well-defined in other
-implementations.
-
-Following are some examples where the current version of M4 follows C
-precedence rules, but where older versions and some other
-implementations of @code{m4} require explicit parentheses to get the
-correct result:
-
-@example
-eval(`1 == 2 > 0')
-@result{}1
-eval(`(1 == 2) > 0')
-@result{}0
-eval(`! 0 * 2')
-@result{}2
-eval(`! (0 * 2)')
-@result{}1
-eval(`1 | 1 ^ 1')
-@result{}1
-eval(`(1 | 1) ^ 1')
-@result{}0
-eval(`+ + - ~ ! ~ 0')
-@result{}1
-eval(`++0')
-@error{}m4:stdin:8: warning: eval: invalid operator: '++0'
-@result{}
-eval(`1 = 1')
-@error{}m4:stdin:9: warning: eval: invalid operator: '1 = 1'
-@result{}
-eval(`0 |= 1')
-@error{}m4:stdin:10: warning: eval: invalid operator: '0 |= 1'
-@result{}
-eval(`2 || 1 / 0')
-@result{}1
-eval(`0 || 1 / 0')
-@error{}m4:stdin:12: warning: eval: divide by zero: '0 || 1 / 0'
-@result{}
-eval(`0 && 1 % 0')
-@result{}0
-eval(`2 && 1 % 0')
-@error{}m4:stdin:14: warning: eval: modulo by zero: '2 && 1 % 0'
-@result{}
-@end example
-
-@cindex GNU extensions
-As a GNU extension, @code{eval} supports several operators
-that do not appear in C@. A right-associative exponentiation operator
-@samp{**} computes the value of the left argument raised to the right,
-modulo the numeric precision width. If evaluated, the exponent must be
-non-negative, and at least one of the arguments must be non-zero, or a
-warning is issued. An unsigned shift operator @samp{>>>} allows
-shifting a negative number as though it were an unsigned bit pattern,
-which shifts in 0 bits rather than twos-complement sign-extension. A
-ratio operator @samp{\} behaves like normal division @samp{/} on
-integers, but is provided for symmetry with @code{mpeval}.
-Additionally, the C operators @samp{,} and @samp{?:} are supported.
-
-@example
-eval(`2 ** 3 ** 2')
-@result{}512
-eval(`(2 ** 3) ** 2')
-@result{}64
-eval(`0 ** 1')
-@result{}0
-eval(`2 ** 0')
-@result{}1
-eval(`0 ** 0')
-@result{}
-@error{}m4:stdin:5: warning: eval: divide by zero: '0 ** 0'
-eval(`4 ** -2')
-@error{}m4:stdin:6: warning: eval: negative exponent: '4 ** -2'
-@result{}
-eval(`2 || 4 ** -2')
-@result{}1
-eval(`(-1 >> 1) == -1')
-@result{}1
-eval(`(-1 >>> 1) > (1 << 30)')
-@result{}1
-eval(`6 \ 3')
-@result{}2
-eval(`1 ? 2 : 3')
-@result{}2
-eval(`0 ? 2 : 3')
-@result{}3
-eval(`1 ? 2 : 1/0')
-@result{}2
-eval(`0 ? 1/0 : 3')
-@result{}3
-eval(`4, 5')
-@result{}5
-@end example
-
-Within @var{expression}, (but not @var{radix} or @var{width}), numbers
-without a special prefix are decimal. A simple @samp{0} prefix
-introduces an octal number. @samp{0x} introduces a hexadecimal number.
-As GNU extensions, @samp{0b} introduces a binary number.
-@samp{0r} introduces a number expressed in any radix between 1 and 36:
-the prefix should be immediately followed by the decimal expression of
-the radix, a colon, then the digits making the number. For radix 1,
-leading zeros are ignored, and all remaining digits must be @samp{1};
-for all other radices, the digits are @samp{0}, @samp{1}, @samp{2},
-@dots{}. Beyond @samp{9}, the digits are @samp{a}, @samp{b} @dots{} up
-to @samp{z}. Lower and upper case letters can be used interchangeably
-in numbers prefixes and as number digits.
-
-Parentheses may be used to group subexpressions whenever needed. For the
-relational operators, a true relation returns @code{1}, and a false
-relation return @code{0}.
-
-Here are a few examples of use of @code{eval}.
-
-@example
-eval(`-3 * 5')
-@result{}-15
-eval(`-99 / 10')
-@result{}-9
-eval(`-99 % 10')
-@result{}-9
-eval(`99 % -10')
-@result{}9
-eval(index(`Hello world', `llo') >= 0)
-@result{}1
-eval(`0r1:0111 + 0b100 + 0r3:12')
-@result{}12
-define(`square', `eval(`($1) ** 2')')
-@result{}
-square(`9')
-@result{}81
-square(square(`5')` + 1')
-@result{}676
-define(`foo', `666')
-@result{}
-eval(`foo / 6')
-@error{}m4:stdin:11: warning: eval: bad expression: 'foo / 6'
-@result{}
-eval(foo / 6)
-@result{}111
-@end example
-
-As the last two lines show, @code{eval} does not handle macro
-names, even if they expand to a valid expression (or part of a valid
-expression). Therefore all macros must be expanded before they are
-passed to @code{eval}.
-@comment update this if we add support for variables.
-
-Some calculations are not portable to other implementations, since they
-have undefined semantics in C, but GNU @code{m4} has
-well-defined behavior on overflow. When shifting, an out-of-range shift
-amount is implicitly brought into the range of the precision using
-modulo arithmetic (for example, on 32-bit integers, this would be an
-implicit bit-wise and with 0x1f). This example should work whether your
-platform uses 32-bit integers, 64-bit integers, or even some other
-atypical size.
-
-@example
-define(`max_int', eval(`-1 >>> 1'))
-@result{}
-define(`min_int', eval(max_int` + 1'))
-@result{}
-eval(min_int` < 0')
-@result{}1
-eval(max_int` > 0')
-@result{}1
-ifelse(eval(min_int` / -1'), min_int, `overflow occurred')
-@result{}overflow occurred
-eval(`0x80000000 % -1')
-@result{}0
-eval(`-4 >> 1')
-@result{}-2
-eval(`-4 >> 'eval(len(eval(max_int, `2'))` + 2'))
-@result{}-2
-@end example
-
-If @var{radix} is specified, it specifies the radix to be used in the
-expansion. The default radix is 10; this is also the case if
-@var{radix} is the empty string. A warning results if the radix is
-outside the range of 1 through 36, inclusive. The result of @code{eval}
-is always taken to be signed. No radix prefix is output, and for
-radices greater than 10, the digits are lower case (although some
-other implementations use upper case). The output is unquoted, and
-subject to further macro expansion. The @var{width}
-argument specifies the minimum output width, excluding any negative
-sign. The result is zero-padded to extend the expansion to the
-requested width. A warning results if the width is negative. If
-@var{radix} or @var{width} is out of bounds, the expansion of
-@code{eval} is empty.
-
-@example
-eval(`666', `10')
-@result{}666
-eval(`666', `11')
-@result{}556
-eval(`666', `6')
-@result{}3030
-eval(`666', `6', `10')
-@result{}0000003030
-eval(`-666', `6', `10')
-@result{}-0000003030
-eval(`10', `', `0')
-@result{}10
-`0r1:'eval(`10', `1', `11')
-@result{}0r1:01111111111
-eval(`10', `16')
-@result{}a
-eval(`1', `37')
-@error{}m4:stdin:9: warning: eval: radix out of range: 37
-@result{}
-eval(`1', , `-1')
-@error{}m4:stdin:10: warning: eval: negative width: -1
-@result{}
-eval()
-@error{}m4:stdin:11: warning: eval: empty string treated as 0
-@result{}0
-eval(` ')
-@error{}m4:stdin:12: warning: eval: empty string treated as 0
-@result{}0
-define(`a', `hi')eval(` 10 ', `16')
-@result{}hi
-@end example
-
-@node Mpeval
-@section Multiple precision arithmetic
-
-When @code{m4} is compiled with a multiple precision arithmetic library
-(@pxref{Experiments}), a builtin @code{mpeval} is defined.
-
-@deffn {Builtin (mpeval)} mpeval (@var{expression}, @dvar{radix, 10}, @
- @ovar{width})
-Behaves similarly to @code{eval}, except the calculations are done with
-infinite precision, and rational numbers are supported. Numbers may be
-of any length.
-
-The macro @code{mpeval} is recognized only with parameters.
-@end deffn
-
-For the most part, using @code{mpeval} is similar to using @code{eval}:
-
-@comment options: mpeval -
-@example
-$ @kbd{m4 mpeval -}
-mpeval(`(1 << 70) + 2 ** 68 * 3', `16')
-@result{}700000000000000000
-`0r24:'mpeval(`0r36:zYx', `24', `5')
-@result{}0r24:038m9
-@end example
-
-The ratio operator, @samp{\}, is provided with the same precedence as
-division, and rationally divides two numbers and canonicalizes the
-result, whereas the division operator @samp{/} always returns the
-integer quotient of the division. To convert a rational value to
-integral, divide (@samp{/}) by 1. Some operators, such as @samp{%},
-@samp{<<}, @samp{>>}, @samp{~}, @samp{&}, @samp{|} and @samp{^} operate
-only on integers and will truncate any rational remainder. The unsigned
-shift operator, @samp{>>>}, behaves identically with regular right
-shifts, @samp{>>}, since with infinite precision, it is not possible to
-convert a negative number to a positive using shifts. The
-exponentiation operator, @samp{**}, assumes that the exponent is
-integral, but allows negative exponents. With the short-circuit logical
-operators, @samp{||} and @samp{&&}, a non-zero result preserves the
-value of the argument that ended evaluation, rather than collapsing to
-@samp{1}. The operators @samp{?:} and @samp{,} are always available,
-even in POSIX mode, since @code{mpeval} does not have to
-conform to the POSIX rules for @code{eval}.
-
-@comment options: mpeval -
-@example
-$ @kbd{m4 mpeval -}
-mpeval(`2 / 4')
-@result{}0
-mpeval(`2 \ 4')
-@result{}1\2
-mpeval(`2 || 3')
-@result{}2
-mpeval(`1 && 3')
-@result{}3
-mpeval(`-1 >> 1')
-@result{}-1
-mpeval(`-1 >>> 1')
-@result{}-1
-@end example
-
-@node Shell commands
-@chapter Macros for running shell commands
-
-@cindex UNIX commands, running
-@cindex executing shell commands
-@cindex running shell commands
-@cindex shell commands, running
-@cindex commands, running shell
-There are a few builtin macros in @code{m4} that allow you to run shell
-commands from within @code{m4}.
-
-Note that the definition of a valid shell command is system dependent.
-On UNIX systems, this is the typical @command{/bin/sh}. But on other
-systems, such as native Windows, the shell has a different syntax of
-commands that it understands. Some examples in this chapter assume
-@command{/bin/sh}, and also demonstrate how to quit early with a known
-exit value if this is not the case.
-
-@menu
-* Platform macros:: Determining the platform
-* Syscmd:: Executing simple commands
-* Esyscmd:: Reading the output of commands
-* Sysval:: Exit status
-* Mkstemp:: Making temporary files
-* Mkdtemp:: Making temporary directories
-@end menu
-
-@node Platform macros
-@section Determining the platform
-
-@cindex platform macros
-Sometimes it is desirable for an input file to know which platform
-@code{m4} is running on. GNU @code{m4} provides several
-macros that are predefined to expand to the empty string; checking for
-their existence will confirm platform details.
-
-@deffn {Optional builtin (gnu)} __os2__
-@deffnx {Optional builtin (traditional)} os2
-@deffnx {Optional builtin (gnu)} __unix__
-@deffnx {Optional builtin (traditional)} unix
-@deffnx {Optional builtin (gnu)} __windows__
-@deffnx {Optional builtin (traditional)} windows
-Each of these macros is conditionally defined as needed to describe the
-environment of @code{m4}. If defined, each macro expands to the empty
-string.
-@end deffn
-
-On UNIX systems, GNU @code{m4} will define @code{@w{__unix__}}
-in the @samp{gnu} module, and @code{unix} in the @samp{traditional}
-module.
-
-On native Windows systems, GNU @code{m4} will define
-@code{@w{__windows__}} in the @samp{gnu} module, and @code{windows} in
-the @samp{traditional} module.
-
-On OS/2 systems, GNU @code{m4} will define @code{@w{__os2__}}
-in the @samp{gnu} module, and @code{os2} in the @samp{traditional}
-module.
-
-If GNU M4 does not provide a platform macro for your system,
-please report that as a bug.
-
-@example
-define(`provided', `0')
-@result{}
-ifdef(`__unix__', `define(`provided', incr(provided))')
-@result{}
-ifdef(`__windows__', `define(`provided', incr(provided))')
-@result{}
-ifdef(`__os2__', `define(`provided', incr(provided))')
-@result{}
-provided
-@result{}1
-@end example
-
-@node Syscmd
-@section Executing simple commands
-
-Any shell command can be executed, using @code{syscmd}:
-
-@deffn {Builtin (m4)} syscmd (@var{shell-command})
-Executes @var{shell-command} as a shell command.
-
-The expansion of @code{syscmd} is void, @emph{not} the output from
-@var{shell-command}! Output or error messages from @var{shell-command}
-are not read by @code{m4}. @xref{Esyscmd}, if you need to process the
-command output.
-
-Prior to executing the command, @code{m4} flushes its buffers.
-The default standard input, output and error of @var{shell-command} are
-the same as those of @code{m4}.
-
-By default, the @var{shell-command} will be used as the argument to the
-@option{-c} option of the @command{/bin/sh} shell (or the version of
-@command{sh} specified by @samp{command -p getconf PATH}, if your system
-supports that). If you prefer a different shell, the
-@command{configure} script can be given the option
-@option{--with-syscmd-shell=@var{location}} to set the location of an
-alternative shell at GNU @code{m4} installation; the
-alternative shell must still support @option{-c}.
-
-When the @option{--safer} option (@pxref{Operation modes, , Invoking
-m4}) is in effect, @code{syscmd} results in an error, since otherwise an
-input file could execute arbitrary code.
-
-The macro @code{syscmd} is recognized only with parameters.
-@end deffn
-
-@example
-define(`foo', `FOO')
-@result{}
-syscmd(`echo foo')
-@result{}foo
-@result{}
-@end example
-
-Note how the expansion of @code{syscmd} keeps the trailing newline of
-the command, as well as using the newline that appeared after the macro.
-
-The following is an example of @var{shell-command} using the same
-standard input as @code{m4}:
-
-@comment The testsuite does not know how to parse pipes from the
-@comment texinfo. Fortunately, there are other tests in the testsuite
-@comment that test this same feature.
-@comment ignore
-@example
-$ @kbd{echo "m4wrap(\`syscmd(\`cat')')" | m4}
-@result{}
-@end example
-
-It tells @code{m4} to read all of its input before executing the wrapped
-text, then hands a valid (albeit emptied) pipe as standard input for the
-@code{cat} subcommand. Therefore, you should be careful when using
-standard input (either by specifying no files, or by passing @samp{-} as
-a file name on the command line, @pxref{Command line files, , Invoking
-m4}), and also invoking subcommands via @code{syscmd} or @code{esyscmd}
-that consume data from standard input. When standard input is a
-seekable file, the subprocess will pick up with the next character not
-yet processed by @code{m4}; when it is a pipe or other non-seekable
-file, there is no guarantee how much data will already be buffered by
-@code{m4} and thus unavailable to the child.
-
-Following is an example of how potentially unsafe actions can be
-suppressed.
-
-@comment options: --safer
-@comment status: 1
-@example
-$ @kbd{m4 --safer}
-syscmd(`echo hi')
-@error{}m4:stdin:1: syscmd: disabled by --safer
-@result{}
-@end example
-
-@node Esyscmd
-@section Reading the output of commands
-
-@cindex GNU extensions
-If you want @code{m4} to read the output of a shell command, use
-@code{esyscmd}:
-
-@deffn {Builtin (gnu)} esyscmd (@var{shell-command})
-Expands to the standard output of the shell command
-@var{shell-command}.
-
-Prior to executing the command, @code{m4} flushes its buffers.
-The default standard input and standard error of @var{shell-command} are
-the same as those of @code{m4}. The error output of @var{shell-command}
-is not a part of the expansion: it will appear along with the error
-output of @code{m4}.
-
-By default, the @var{shell-command} will be used as the argument to the
-@option{-c} option of the @command{/bin/sh} shell (or the version of
-@command{sh} specified by @samp{command -p getconf PATH}, if your system
-supports that). If you prefer a different shell, the
-@command{configure} script can be given the option
-@option{--with-syscmd-shell=@var{location}} to set the location of an
-alternative shell at GNU @code{m4} installation; the
-alternative shell must still support @option{-c}.
-
-When the @option{--safer} option (@pxref{Operation modes, , Invoking
-m4}) is in effect, @code{esyscmd} results in an error, since otherwise
-an input file could execute arbitrary code.
-
-The macro @code{esyscmd} is recognized only with parameters.
-@end deffn
-
-@example
-define(`foo', `FOO')
-@result{}
-esyscmd(`echo foo')
-@result{}FOO
-@result{}
-@end example
-
-Note how the expansion of @code{esyscmd} keeps the trailing newline of
-the command, as well as using the newline that appeared after the macro.
-
-Just as with @code{syscmd}, care must be exercised when sharing standard
-input between @code{m4} and the child process of @code{esyscmd}.
-Likewise, potentially unsafe actions can be suppressed.
-
-@comment options: --safer
-@comment status: 1
-@example
-$ @kbd{m4 --safer}
-esyscmd(`echo hi')
-@error{}m4:stdin:1: esyscmd: disabled by --safer
-@result{}
-@end example
-
-@node Sysval
-@section Exit status
-
-@cindex UNIX commands, exit status from
-@cindex exit status from shell commands
-@cindex shell commands, exit status from
-@cindex commands, exit status from shell
-@cindex status of shell commands
-To see whether a shell command succeeded, use @code{sysval}:
-
-@deffn {Builtin (m4)} sysval
-Expands to the exit status of the last shell command run with
-@code{syscmd} or @code{esyscmd}. Expands to 0 if no command has been
-run yet.
-@end deffn
-
-@example
-sysval
-@result{}0
-syscmd(`false')
-@result{}
-ifelse(sysval, `0', `zero', `non-zero')
-@result{}non-zero
-syscmd(`exit 2')
-@result{}
-sysval
-@result{}2
-syscmd(`true')
-@result{}
-sysval
-@result{}0
-esyscmd(`false')
-@result{}
-ifelse(sysval, `0', `zero', `non-zero')
-@result{}non-zero
-esyscmd(`echo dnl && exit 127')
-@result{}
-sysval
-@result{}127
-esyscmd(`true')
-@result{}
-sysval
-@result{}0
-@end example
-
-@code{sysval} results in 127 if there was a problem executing the
-command, for example, if the system-imposed argument length is exceeded,
-or if there were not enough resources to fork. It is not possible to
-distinguish between failed execution and successful execution that had
-an exit status of 127, unless there was output from the child process.
-
-On UNIX platforms, where it is possible to detect when command execution
-is terminated by a signal, rather than a normal exit, the result is the
-signal number shifted left by eight bits.
-
-@comment This test has difficulties being portable, even on platforms
-@comment where syscmd invokes /bin/sh. Kill is not portable with signal
-@comment names. According to autoconf, the only portable signal numbers
-@comment are 1 (HUP), 2 (INT), 9 (KILL), 13 (PIPE) and 15 (TERM). But
-@comment all shells handle SIGINT, and ksh handles HUP (as in, the shell
-@comment exits normally rather than letting the signal terminate it).
-@comment Also, TERM is flaky, as it can also kill the running m4 on
-@comment systems where /bin/sh does not create its own process group.
-@comment And PIPE is unreliable, since people tend to run with it
-@comment ignored, with m4 inheriting that choice. That leaves KILL as
-@comment the only signal we can reliably test.
-@example
-dnl This test assumes kill is a shell builtin, and that signals are
-dnl recognizable.
-ifdef(`__unix__', ,
- `errprint(` skipping: syscmd does not have unix semantics
-')m4exit(`77')')dnl
-syscmd(`kill -9 $$')
-@result{}
-sysval
-@result{}2304
-syscmd()
-@result{}
-sysval
-@result{}0
-esyscmd(`kill -9 $$')
-@result{}
-sysval
-@result{}2304
-@end example
-
-When the @option{--safer} option (@pxref{Operation modes, , Invoking
-m4}) is in effect, @code{sysval} will always remain at its default value
-of zero.
-
-@comment options: --safer
-@comment status: 1
-@example
-$ @kbd{m4 --safer}
-sysval
-@result{}0
-syscmd(`false')
-@error{}m4:stdin:2: syscmd: disabled by --safer
-@result{}
-sysval
-@result{}0
-@end example
-
-@node Mkstemp
-@section Making temporary files
-
-@cindex temporary file names
-@cindex files, names of temporary
-Commands specified to @code{syscmd} or @code{esyscmd} might need a
-temporary file, for output or for some other purpose. There is a
-builtin macro, @code{mkstemp}, for making a temporary file:
-
-@deffn {Builtin (m4)} mkstemp (@var{template})
-@deffnx {Builtin (m4)} maketemp (@var{template})
-Expands to the quoted name of a new, empty file, made from the string
-@var{template}, which should end with the string @samp{XXXXXX}. The six
-@samp{X} characters are then replaced with random characters matching
-the regular expression @samp{[a-zA-Z0-9._-]}, in order to make the file
-name unique. If fewer than six @samp{X} characters are found at the end
-of @code{template}, the result will be longer than the template. The
-created file will have access permissions as if by @kbd{chmod =rw,go=},
-meaning that the current umask of the @code{m4} process is taken into
-account, and at most only the current user can read and write the file.
-
-The traditional behavior, standardized by POSIX, is that
-@code{maketemp} merely replaces the trailing @samp{X} with the process
-id, without creating a file or quoting the expansion, and without
-ensuring that the resulting
-string is a unique file name. In part, this means that using the same
-@var{template} twice in the same input file will result in the same
-expansion. This behavior is a security hole, as it is very easy for
-another process to guess the name that will be generated, and thus
-interfere with a subsequent use of @code{syscmd} trying to manipulate
-that file name. Hence, POSIX has recommended that all new
-implementations of @code{m4} provide the secure @code{mkstemp} builtin,
-and that users of @code{m4} check for its existence.
-
-The expansion is void and an error issued if a temporary file could
-not be created.
-
-When the @option{--safer} option (@pxref{Operation modes, Invoking m4})
-is in effect, @code{mkstemp} and GNU-mode @code{maketemp}
-result in an error, since otherwise an input file could perform a mild
-denial-of-service attack by filling up a disk with multiple empty files.
-
-The macros @code{mkstemp} and @code{maketemp} are recognized only with
-parameters.
-@end deffn
-
-If you try this next example, you will most likely get different output
-for the two file names, since the replacement characters are randomly
-chosen:
-
-@comment ignore
-@example
-$ @kbd{m4}
-define(`tmp', `oops')
-@result{}
-maketemp(`/tmp/fooXXXXXX')
-@error{}m4:stdin:1: warning: maketemp: recommend using mkstemp instead
-@result{}/tmp/fooa07346
-ifdef(`mkstemp', `define(`maketemp', defn(`mkstemp'))',
- `define(`mkstemp', defn(`maketemp'))dnl
-errprint(`warning: potentially insecure maketemp implementation
-')')
-@result{}
-mkstemp(`doc')
-@result{}docQv83Uw
-@end example
-
-@comment options: --safer
-@comment status: 1
-@example
-$ @kbd{m4 --safer}
-maketemp(`/tmp/fooXXXXXX')
-@error{}m4:stdin:1: warning: maketemp: recommend using mkstemp instead
-@error{}m4:stdin:1: maketemp: disabled by --safer
-@result{}
-mkstemp(`/tmp/fooXXXXXX')
-@error{}m4:stdin:2: mkstemp: disabled by --safer
-@result{}
-@end example
-
-@cindex GNU extensions
-Unless you use the @option{--traditional} command line option (or
-@option{-G}, @pxref{Limits control, , Invoking m4}), the GNU
-version of @code{maketemp} is secure. This means that using the same
-template to multiple calls will generate multiple files. However, we
-recommend that you use the new @code{mkstemp} macro, introduced in
-GNU M4 1.4.8, which is secure even in traditional mode. Also,
-as of M4 1.4.11, the secure implementation quotes the resulting file
-name, so that you are guaranteed to know what file was created even if
-the random file name happens to match an existing macro. Notice that
-this example is careful to use @code{defn} to avoid unintended expansion
-of @samp{foo}.
-
-@example
-$ @kbd{m4}
-define(`foo', `errprint(`oops')')
-@result{}
-syscmd(`rm -f foo-??????')sysval
-@result{}0
-define(`file1', maketemp(`foo-XXXXXX'))dnl
-@error{}m4:stdin:3: warning: maketemp: recommend using mkstemp instead
-ifelse(esyscmd(`echo \` foo-?????? \''), `foo-??????',
- `no file', `created')
-@result{}created
-define(`file2', maketemp(`foo-XX'))dnl
-@error{}m4:stdin:6: warning: maketemp: recommend using mkstemp instead
-define(`file3', mkstemp(`foo-XXXXXX'))dnl
-ifelse(len(defn(`file1')), len(defn(`file2')),
- `same length', `different')
-@result{}same length
-ifelse(defn(`file1'), defn(`file2'), `same', `different file')
-@result{}different file
-ifelse(defn(`file2'), defn(`file3'), `same', `different file')
-@result{}different file
-ifelse(defn(`file1'), defn(`file3'), `same', `different file')
-@result{}different file
-syscmd(`rm 'defn(`file1') defn(`file2') defn(`file3'))
-@result{}
-sysval
-@result{}0
-@end example
-
-@comment options: -G
-@example
-$ @kbd{m4 -G}
-syscmd(`rm -f foo-*')sysval
-@result{}0
-define(`file1', maketemp(`foo-XXXXXX'))dnl
-@error{}m4:stdin:2: warning: maketemp: recommend using mkstemp instead
-define(`file2', maketemp(`foo-XXXXXX'))dnl
-@error{}m4:stdin:3: warning: maketemp: recommend using mkstemp instead
-ifelse(file1, file2, `same', `different file')
-@result{}same
-len(maketemp(`foo-XXXXX'))
-@error{}m4:stdin:5: warning: maketemp: recommend using mkstemp instead
-@result{}9
-define(`abc', `def')
-@result{}
-maketemp(`foo-abc')
-@result{}foo-def
-@error{}m4:stdin:7: warning: maketemp: recommend using mkstemp instead
-syscmd(`test -f foo-*')sysval
-@result{}1
-@end example
-
-@node Mkdtemp
-@section Making temporary directories
-
-@cindex temporary directory
-@cindex directories, temporary
-@cindex GNU extensions
-Commands specified to @code{syscmd} or @code{esyscmd} might need a
-temporary directory, for holding multiple temporary files; such a
-directory can be created with @code{mkdtemp}:
-
-@deffn {Builtin (gnu)} mkdtemp (@var{template})
-Expands to the quoted name of a new, empty directory, made from the string
-@var{template}, which should end with the string @samp{XXXXXX}. The six
-@samp{X} characters are then replaced with random characters matching
-the regular expression @samp{[a-zA-Z0-9._-]}, in order to make the name
-unique. If fewer than six @samp{X} characters are found at the end of
-@code{template}, the result will be longer than the template. The
-created directory will have access permissions as if by @kbd{chmod
-=rwx,go=}, meaning that the current umask of the @code{m4} process is
-taken into account, and at most only the current user can read, write,
-and search the directory.
-
-The expansion is void and an error issued if a temporary directory could
-not be created.
-
-When the @option{--safer} option (@pxref{Operation modes, Invoking m4})
-is in effect, @code{mkdtemp} results in an error, since otherwise an
-input file could perform a mild denial-of-service attack by filling up a
-disk with multiple directories.
-
-The macro @code{mkdtemp} is recognized only with parameters.
-This macro was added in M4 2.0.
-@end deffn
-
-If you try this next example, you will most likely get different output
-for the directory names, since the replacement characters are randomly
-chosen:
-
-@comment ignore
-@example
-$ @kbd{m4}
-define(`tmp', `oops')
-@result{}
-mkdtemp(`/tmp/fooXXXXXX')
-@result{}/tmp/foo2h89Vo
-mkdtemp(`dir)
-@result{}dirrg079A
-@end example
-
-@comment options: --safer
-@comment status: 1
-@example
-$ @kbd{m4 --safer}
-mkdtemp(`/tmp/fooXXXXXX')
-@error{}m4:stdin:1: mkdtemp: disabled by --safer
-@result{}
-@end example
-
-Multiple calls with the same template will generate multiple
-directories.
-
-@example
-$ @kbd{m4}
-syscmd(`echo foo??????')dnl
-@result{}foo??????
-define(`dir1', mkdtemp(`fooXXXXXX'))dnl
-ifelse(esyscmd(`echo foo??????'), `foo??????', `no dir', `created')
-@result{}created
-define(`dir2', mkdtemp(`fooXXXXXX'))dnl
-ifelse(dir1, dir2, `same', `different directories')
-@result{}different directories
-syscmd(`rmdir 'dir1 dir2)
-@result{}
-sysval
-@result{}0
-@end example
-
-@node Miscellaneous
-@chapter Miscellaneous builtin macros
-
-This chapter describes various builtins, that do not really belong in
-any of the previous chapters.
-
-@menu
-* Errprint:: Printing error messages
-* Location:: Printing current location
-* M4exit:: Exiting from @code{m4}
-* Syncoutput:: Turning on and off sync lines
-@end menu
-
-@node Errprint
-@section Printing error messages
-
-@cindex printing error messages
-@cindex error messages, printing
-@cindex messages, printing error
-@cindex standard error, output to
-You can print error messages using @code{errprint}:
-
-@deffn {Builtin (m4)} errprint (@var{message}, @dots{})
-Prints @var{message} and the rest of the arguments to standard error,
-separated by spaces. Standard error is used, regardless of the
-@option{--debugfile} option (@pxref{Debugging options, , Invoking m4}).
-
-The expansion of @code{errprint} is void.
-The macro @code{errprint} is recognized only with parameters.
-@end deffn
-
-@example
-errprint(`Invalid arguments to forloop
-')
-@error{}Invalid arguments to forloop
-@result{}
-errprint(`1')errprint(`2',`3
-')
-@error{}12 3
-@result{}
-@end example
-
-A trailing newline is @emph{not} printed automatically, so it should be
-supplied as part of the argument, as in the example. Unfortunately, the
-exact output of @code{errprint} is not very portable to other @code{m4}
-implementations: POSIX requires that all arguments be printed,
-but some implementations of @code{m4} only print the first.
-Furthermore, some BSD implementations always append a newline
-for each @code{errprint} call, regardless of whether the last argument
-already had one, and POSIX is silent on whether this is
-acceptable.
-
-@node Location
-@section Printing current location
-
-@cindex location, input
-@cindex input location
-To make it possible to specify the location of an error, three
-utility builtins exist:
-
-@deffn {Builtin (gnu)} __file__
-@deffnx {Builtin (gnu)} __line__
-@deffnx {Builtin (gnu)} __program__
-Expand to the quoted name of the current input file, the
-current input line number in that file, and the quoted name of the
-current invocation of @code{m4}.
-@end deffn
-
-@example
-errprint(__program__:__file__:__line__: `input error
-')
-@error{}m4:stdin:1: input error
-@result{}
-@end example
-
-Line numbers start at 1 for each file. If the file was found due to the
-@option{-I} option or @env{M4PATH} environment variable, that is
-reflected in the file name. Synclines, via @code{syncoutput}
-(@pxref{Syncoutput}) or the command line option @option{--synclines}
-(or @option{-s}, @pxref{Preprocessor features, , Invoking m4}), and the
-@samp{f} and @samp{l} flags of @code{debugmode} (@pxref{Debugmode}),
-also use this notion of current file and line. Redefining the three
-location macros has no effect on syncline, debug, warning, or error
-message output.
-
-This example reuses the file @file{incl.m4} mentioned earlier
-(@pxref{Include}):
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-define(`foo', ``$0' called at __file__:__line__')
-@result{}
-foo
-@result{}foo called at stdin:2
-include(`incl.m4')
-@result{}Include file start
-@result{}foo called at doc/examples/incl.m4:2
-@result{}Include file end
-@result{}
-@end example
-
-The location of macros invoked during the rescanning of macro expansion
-text corresponds to the location in the file where the expansion was
-triggered, regardless of how many newline characters the expansion text
-contains. As of GNU M4 1.4.8, the location of text wrapped
-with @code{m4wrap} (@pxref{M4wrap}) is the point at which the
-@code{m4wrap} was invoked. Previous versions, however, behaved as
-though wrapped text came from line 0 of the file ``''.
-
-@example
-define(`echo', `$@@')
-@result{}
-define(`foo', `echo(__line__
-__line__)')
-@result{}
-echo(__line__
-__line__)
-@result{}4
-@result{}5
-m4wrap(`foo
-')
-@result{}
-foo(errprint(__line__
-__line__
-))
-@error{}8
-@error{}9
-@result{}8
-@result{}8
-__line__
-@result{}11
-m4wrap(`__line__
-')
-@result{}
-^D
-@result{}6
-@result{}6
-@result{}12
-@end example
-
-The @code{@w{__program__}} macro behaves like @samp{$0} in shell
-terminology. If you invoke @code{m4} through an absolute path or a link
-with a different spelling, rather than by relying on a @env{PATH} search
-for plain @samp{m4}, it will affect how @code{@w{__program__}} expands.
-The intent is that you can use it to produce error messages with the
-same formatting that @code{m4} produces internally. It can also be used
-within @code{syscmd} (@pxref{Syscmd}) to pick the same version of
-@code{m4} that is currently running, rather than whatever version of
-@code{m4} happens to be first in @env{PATH}. It was first introduced in
-GNU M4 1.4.6.
-
-@node M4exit
-@section Exiting from @code{m4}
-
-@cindex exiting from @code{m4}
-@cindex status, setting @code{m4} exit
-If you need to exit from @code{m4} before the entire input has been
-read, you can use @code{m4exit}:
-
-@deffn {Builtin (m4)} m4exit (@ovar{code})
-Causes @code{m4} to exit, with exit status @var{code}. If @var{code} is
-left out, the exit status is zero. If @var{code} cannot be parsed, or
-is outside the range of 0 to 255, the exit status is one. No further
-input is read, and all wrapped and diverted text is discarded.
-@end deffn
-
-@example
-m4wrap(`This text is lost due to `m4exit'.')
-@result{}
-divert(`1') So is this.
-divert
-@result{}
-m4exit And this is never read.
-@end example
-
-A common use of this is to abort processing:
-
-@deffn Composite fatal_error (@var{message})
-Abort processing with an error message and non-zero status. Prefix
-@var{message} with details about where the error occurred, and print the
-resulting string to standard error.
-@end deffn
-
-@comment status: 1
-@example
-define(`fatal_error',
- `errprint(__program__:__file__:__line__`: fatal error: $*
-')m4exit(`1')')
-@result{}
-fatal_error(`this is a BAD one, buster')
-@error{}m4:stdin:4: fatal error: this is a BAD one, buster
-@end example
-
-After this macro call, @code{m4} will exit with exit status 1. This macro
-is only intended for error exits, since the normal exit procedures are
-not followed, i.e., diverted text is not undiverted, and saved text
-(@pxref{M4wrap}) is not reread. (This macro could be made more robust
-to earlier versions of @code{m4}. You should try to see if you can find
-weaknesses and correct them; or @pxref{Improved fatal_error, , Answers}).
-
-Note that it is still possible for the exit status to be different than
-what was requested by @code{m4exit}. If @code{m4} detects some other
-error, such as a write error on standard output, the exit status will be
-non-zero even if @code{m4exit} requested zero.
-
-If standard input is seekable, then the file will be positioned at the
-next unread character. If it is a pipe or other non-seekable file,
-then there are no guarantees how much data @code{m4} might have read
-into buffers, and thus discarded.
-
-@node Syncoutput
-@section Turning on and off sync lines
-
-@cindex toggling synchronization lines
-@cindex synchronization lines
-@cindex location, input
-@cindex input location
-It is possible to adjust whether synclines are printed to output:
-
-@deffn {Builtin (gnu)} syncoutput (@var{truth})
-If @var{truth} matches the extended regular expression
-@samp{^[1yY]|^([oO][nN])}, it causes @code{m4} to emit sync lines of the
-form: @samp{#line <number> ["<file>"]}.
-
-If @var{truth} is empty, or matches the extended regular expression
-@samp{^[0nN]|^([oO][fF])}, it causes @code{m4} to turn sync lines off.
-
-All other arguments are ignored and issue a warning.
-
-The macro @code{syncoutput} is recognized only with parameters.
-This macro was added in M4 2.0.
-@end deffn
-
-@example
-define(`twoline', `1
-2')
-@result{}
-changecom(`/*', `*/')
-@result{}
-define(`comment', `/*1
-2*/')
-@result{}
-twoline
-@result{}1
-@result{}2
-dnl no line
-syncoutput(`on')
-@result{}#line 8 "stdin"
-@result{}
-twoline
-@result{}1
-@result{}#line 9
-@result{}2
-dnl no line
-hello
-@result{}#line 11
-@result{}hello
-comment
-@result{}/*1
-@result{}2*/
-one comment `two
-three'
-@result{}#line 13
-@result{}one /*1
-@result{}2*/ two
-@result{}three
-goodbye
-@result{}#line 15
-@result{}goodbye
-syncoutput(`off')
-@result{}
-twoline
-@result{}1
-@result{}2
-syncoutput(`blah')
-@error{}m4:stdin:18: warning: syncoutput: unknown directive 'blah'
-@result{}
-@end example
-
-Notice that a syncline is output any time a single source line expands
-to multiple output lines, or any time multiple source lines expand to a
-single output line. When there is a one-for-one correspondence, no
-additional synclines are needed.
-
-Synchronization lines can be used to track where input comes from; an
-optional file designation is printed when the syncline algorithm
-detects that consecutive output lines come from different files. You
-can also use the @option{--synclines} command-line option (or
-@option{-s}, @pxref{Preprocessor features, , Invoking m4}) to start
-with synchronization on. This example reuses the file @file{incl.m4}
-mentioned earlier (@pxref{Include}):
-
-@comment examples
-@comment options: -s
-@example
-$ @kbd{m4 --synclines -I doc/examples}
-include(`incl.m4')
-@result{}#line 1 "doc/examples/incl.m4"
-@result{}Include file start
-@result{}foo
-@result{}Include file end
-@result{}#line 1 "stdin"
-@result{}
-@end example
-
-@node Frozen files
-@chapter Fast loading of frozen state
-
-Some bigger @code{m4} applications may be built over a common base
-containing hundreds of definitions and other costly initializations.
-Usually, the common base is kept in one or more declarative files,
-which files are listed on each @code{m4} invocation prior to the
-user's input file, or else each input file uses @code{include}.
-
-Reading the common base of a big application, over and over again, may
-be time consuming. GNU @code{m4} offers some machinery to
-speed up the start of an application using lengthy common bases.
-
-@menu
-* Using frozen files:: Using frozen files
-* Frozen file format 1:: Frozen file format 1
-* Frozen file format 2:: Frozen file format 2
-@end menu
-
-@node Using frozen files
-@section Using frozen files
-
-@cindex fast loading of frozen files
-@cindex frozen files for fast loading
-@cindex initialization, frozen state
-@cindex dumping into frozen file
-@cindex reloading a frozen file
-@cindex GNU extensions
-Suppose a user has a library of @code{m4} initializations in
-@file{base.m4}, which is then used with multiple input files:
-
-@comment ignore
-@example
-$ @kbd{m4 base.m4 input1.m4}
-$ @kbd{m4 base.m4 input2.m4}
-$ @kbd{m4 base.m4 input3.m4}
-@end example
-
-Rather than spending time parsing the fixed contents of @file{base.m4}
-every time, the user might rather execute:
-
-@comment ignore
-@example
-$ @kbd{m4 -F base.m4f base.m4}
-@end example
-
-@noindent
-once, and further execute, as often as needed:
-
-@comment ignore
-@example
-$ @kbd{m4 -R base.m4f input1.m4}
-$ @kbd{m4 -R base.m4f input2.m4}
-$ @kbd{m4 -R base.m4f input3.m4}
-@end example
-
-@noindent
-with the varying input. The first call, containing the @option{-F}
-option, only reads and executes file @file{base.m4}, defining
-various application macros and computing other initializations.
-Once the input file @file{base.m4} has been completely processed, GNU
-@code{m4} produces in @file{base.m4f} a @dfn{frozen} file, that is, a
-file which contains a kind of snapshot of the @code{m4} internal state.
-
-Later calls, containing the @option{-R} option, are able to reload
-the internal state of @code{m4}, from @file{base.m4f},
-@emph{prior} to reading any other input files. This means
-instead of starting with a virgin copy of @code{m4}, input will be
-read after having effectively recovered the effect of a prior run.
-In our example, the effect is the same as if file @file{base.m4} has
-been read anew. However, this effect is achieved a lot faster.
-
-Only one frozen file may be created or read in any one @code{m4}
-invocation. It is not possible to recover two frozen files at once.
-However, frozen files may be updated incrementally, through using
-@option{-R} and @option{-F} options simultaneously. For example, if
-some care is taken, the command:
-
-@comment ignore
-@example
-$ @kbd{m4 file1.m4 file2.m4 file3.m4 file4.m4}
-@end example
-
-@noindent
-could be broken down in the following sequence, accumulating the same
-output:
-
-@comment ignore
-@example
-$ @kbd{m4 -F file1.m4f file1.m4}
-$ @kbd{m4 -R file1.m4f -F file2.m4f file2.m4}
-$ @kbd{m4 -R file2.m4f -F file3.m4f file3.m4}
-$ @kbd{m4 -R file3.m4f file4.m4}
-@end example
-
-Some care is necessary because the frozen file does not save all state
-information. Stacks of macro definitions via @code{pushdef} are
-accurately stored, along with all renamed or undefined builtins, as are
-the current syntax rules such as from @code{changequote}. However, the
-value of @code{sysval} and text saved in @code{m4wrap} are not currently
-preserved. Also, changing command line options between runs may cause
-unexpected behavior. A future release of GNU M4 may improve
-on the quality of frozen files.
-
-When an @code{m4} run is to be frozen, the automatic undiversion
-which takes place at end of execution is inhibited. Instead, all
-positively numbered diversions are saved into the frozen file.
-The active diversion number is also transmitted.
-
-A frozen file to be reloaded need not reside in the current directory.
-It is looked up the same way as an @code{include} file (@pxref{Search
-Path}).
-
-If the frozen file was generated with a newer version of @code{m4}, and
-contains directives that an older @code{m4} cannot parse, attempting to
-load the frozen file with option @option{-R} will cause @code{m4} to
-exit with status 63 to indicate version mismatch.
-
-@node Frozen file format 1
-@section Frozen file format 1
-
-@cindex frozen file format 1
-@cindex file format, frozen file version 1
-Frozen files are sharable across architectures. It is safe to write
-a frozen file on one machine and read it on another, given that the
-second machine uses the same or newer version of GNU @code{m4}.
-It is conventional, but not required, to give a frozen file the suffix
-of @code{.m4f}.
-
-Older versions of GNU @code{m4} create frozen files with
-syntax version 1. These files can be read by the current version, but
-are no longer produced. Version 1 files are mostly text files, although
-any macros or diversions that contained nonprintable characters or long
-lines cause the resulting frozen file to do likewise, since there are no
-escape sequences. The file can be edited to change the state that
-@code{m4} will start with. It is composed of several directives, each
-starting with a single letter and ending with a newline (@key{NL}).
-Wherever a directive is expected, the character @samp{#} can be used
-instead to introduce a comment line; empty lines are also ignored if
-they are not part of an embedded string.
-
-In the following descriptions, each @var{len} refers to the length of a
-corresponding subsequent @var{str}. Numbers are always expressed in
-decimal, and an omitted number defaults to 0. The valid directives in
-version 1 are:
-
-@table @code
-@item V @var{number} @key{NL}
-Confirms the format of the file. Version 1 is recognized when
-@var{number} is 1. This directive must be the first non-comment in the
-file, and may not appear more than once.
-
-@item C @var{len1} , @var{len2} @key{NL} @var{str1} @var{str2} @key{NL}
-Uses @var{str1} and @var{str2} as the begin-comment and
-end-comment strings. If omitted, then @samp{#} and @key{NL} are the
-comment delimiters.
-
-@item D @var{number}, @var{len} @key{NL} @var{str} @key{NL}
-Selects diversion @var{number}, making it current, then copy @var{str}
-in the current diversion. @var{number} may be a negative number for a
-diversion that discards text. To merely specify an active selection,
-use this command with an empty @var{str}. With 0 as the diversion
-@var{number}, @var{str} will be issued on standard output at reload
-time. GNU @code{m4} will not produce the @samp{D} directive
-with non-zero length for diversion 0, but this can be done with manual
-edits. This directive may appear more than once for the same diversion,
-in which case the diversion is the concatenation of the various uses.
-If omitted, then diversion 0 is current.
-
-@item F @var{len1} , @var{len2} @key{NL} @var{str1} @var{str2} @key{NL}
-Defines, through @code{pushdef}, a definition for @var{str1} expanding
-to the function whose builtin name is @var{str2}. If the builtin does
-not exist (for example, if the frozen file was produced by a copy of
-@code{m4} compiled with the now-abandoned @code{changeword} support),
-the reload is silent, but any subsequent use of the definition of
-@var{str1} will result in a warning. This directive may appear more
-than once for the same name, and its order, along with @samp{T}, is
-important. If omitted, you will have no access to any builtins.
-
-@item Q @var{len1} , @var{len2} @key{NL} @var{str1} @var{str2} @key{NL}
-Uses @var{str1} and @var{str2} as the begin-quote and end-quote
-strings. If omitted, then @samp{`} and @samp{'} are the quote
-delimiters.
-
-@item T @var{len1} , @var{len2} @key{NL} @var{str1} @var{str2} @key{NL}
-Defines, though @code{pushdef}, a definition for @var{str1}
-expanding to the text given by @var{str2}. This directive may appear
-more than once for the same name, and its order, along with @samp{F}, is
-important.
-@end table
-
-When loading format 1, the syntax categories @samp{@{} and @samp{@}} are
-disabled (reverting braces to be treated like plain characters). This
-is because frozen files created with M4 1.4.x did not understand
-@samp{$@{@dots{}@}} extended argument notation, and a frozen macro that
-contained this character sequence should not behave differently just
-because a newer version of M4 reloaded the file.
-
-@node Frozen file format 2
-@section Frozen file format 2
-
-@cindex frozen file format 2
-@cindex file format, frozen file version 2
-The syntax of version 1 has some drawbacks; if any macro or diversion
-contained non-printable characters or long lines, the resulting frozen
-file would not qualify as a text file, making it harder to edit with
-some vendor tools. The concatenation of multiple strings on a single
-line, such as for the @samp{T} directive, makes distinguishing the two
-strings a bit more difficult. Finally, the format lacks support for
-several items of @code{m4} state, such that a reloaded file did not
-always behave the same as the original file.
-
-These shortcomings have been addressed in version 2 of the frozen file
-syntax. New directives have been added, and existing directives have
-additional, and sometimes optional, parameters. All @var{str} instances
-in the grammar are now followed by @key{NL}, which makes the split
-between consecutive strings easier to recognize. Strings may now
-contain escape sequences modeled after C, such as @samp{\n} for newline
-or @samp{\0} for @sc{nul}, so that the frozen file can be pure
-@sc{ascii} (although when hand-editing a frozen file, it is still
-acceptable to use the original byte rather than an escape sequence for
-all bytes except @samp{\}). Also in the context of a @var{str}, the
-escape sequence @samp{\@key{NL}} is discarded, allowing a user to split
-lines that are too long for some platform tools.
-
-@table @code
-@item V @var{number} @key{NL}
-Confirms the format of the file. @code{m4} @value{VERSION} only creates
-frozen files where @var{number} is 2. This directive must be the first
-non-comment in the file, and may not appear more than once.
-
-@item C @var{len1} , @var{len2} @key{NL} @var{str1} @key{NL} @var{str2} @key{NL}
-Uses @var{str1} and @var{str2} as the begin-comment and
-end-comment strings. If omitted, then @samp{#} and @key{NL} are the
-comment delimiters.
-
-@item d @var{len} @key{NL} @var{str} @key{NL}
-Sets the debug flags, using @var{str} as the argument to
-@code{debugmode}. If omitted, then the debug flags start in their
-default disabled state.
-
-@item D @var{number} , @var{len} @key{NL} @var{str} @key{NL}
-Selects diversion @var{number}, making it current, then copy @var{str}
-in the current diversion. @var{number} may be a negative number for a
-diversion that discards text. To merely specify an active selection,
-use this command with an empty @var{string}. With 0 as the diversion
-@var{number}, @var{str} will be issued on standard output at reload
-time. GNU @code{m4} will not produce the @samp{D} directive
-with non-zero length for diversion 0, but this can be done with manual
-edits. This directive may appear more than once for the same diversion,
-in which case the diversion is the concatenation of the various uses.
-If omitted, then diversion 0 is current.
-
-@comment FIXME - the first usage, with only one string, is not supported
-@comment in the current code
-@c @item F @var{len1} @key{NL} @var{str1} @key{NL}
-@item F @var{len1} , @var{len2} @key{NL} @var{str1} @key{NL} @var{str2} @key{NL}
-@itemx F @var{len1} , @var{len2} , @var{len3} @key{NL} @var{str1} @key{NL} @var{str2} @key{NL} @var{str3} @key{NL}
-Defines, through @code{pushdef}, a definition for @var{str1} expanding
-to the function whose builtin name is given by @var{str2} (defaulting to
-@var{str1} if not present). With two arguments, the builtin name is
-searched for among the intrinsic builtin functions only; with three
-arguments, the builtin name is searched for amongst the builtin
-functions defined by the module named by @var{str3}.
-
-@item M @var{len} @key{NL} @var{str} @key{NL}
-Names a module which will be searched for according to the module search
-path and loaded. Modules loaded from a frozen file don't add their
-builtin entries to the symbol table. Modules must be loaded prior to
-specifying module-specific builtins via the three-argument @code{F} or
-@code{T}.
-
-@item Q @var{len1} , @var{len2} @key{NL} @var{str1} @key{NL} @var{str2} @key{NL}
-Uses @var{str1} and @var{str2} as the begin-quote and end-quote strings.
-If omitted, then @samp{`} and @samp{'} are the quote delimiters.
-
-@item R @var{len} @key{NL} @var{str} @key{NL}
-Sets the default regexp syntax, where @var{str} encodes one of the
-regular expression syntaxes supported by GNU M4.
-@xref{Changeresyntax}, for more details.
-
-@item S @var{syntax-code} @var{len} @key{NL} @var{str} @key{NL}
-Defines, through @code{changesyntax}, a syntax category for each of the
-characters in @var{str}. The @var{syntax-code} must be one of the
-characters described in @ref{Changesyntax}.
-
-@item t @var{len} @key{NL} @var{str} @key{NL}
-Enables tracing for any macro named @var{str}, similar to using the
-@code{traceon} builtin. This option may occur more than once for
-multiple macros; if omitted, no macro starts out as traced.
-
-@item T @var{len1} , @var{len2} @key{NL} @var{str1} @key{NL} @var{str2} @key{NL}
-@itemx T @var{len1} , @var{len2} , @var{len3} @key{NL} @var{str1} @key{NL} @var{str2} @key{NL} @var{str3} @key{NL}
-Defines, though @code{pushdef}, a definition for @var{str1} expanding to
-the text given by @var{str2}. This directive may appear more than once
-for the same name, and its order, along with @samp{F}, is important. If
-present, the optional third argument associates the macro with a module
-named by @var{str3}.
-@end table
-
-@node Compatibility
-@chapter Compatibility with other versions of @code{m4}
-
-@cindex compatibility
-This chapter describes the many of the differences between this
-implementation of @code{m4}, and of other implementations found under
-UNIX, such as System V Release 4, Solaris, and BSD flavors.
-In particular, it lists the known differences and extensions to
-POSIX. However, the list is not necessarily comprehensive.
-
-At the time of this writing, POSIX 2001 (also known as IEEE
-Std 1003.1-2001) is the latest standard, although a new version of
-POSIX is under development and includes several proposals for
-modifying what @code{m4} is required to do. The requirements for
-@code{m4} are shared between SUSv3 and POSIX, and
-can be viewed at
-@uref{http://www.opengroup.org/onlinepubs/@/000095399/@/utilities/@/m4.html}.
-
-@menu
-* Extensions:: Extensions in GNU M4
-* Incompatibilities:: Other incompatibilities
-* Experiments:: Experimental features in GNU M4
-@end menu
-
-@node Extensions
-@section Extensions in GNU M4
-
-@cindex GNU extensions
-@cindex POSIX
-@cindex @env{POSIXLY_CORRECT}
-This version of @code{m4} contains a few facilities that do not exist
-in System V @code{m4}. These extra facilities are all suppressed by
-using the @option{-G} command line option, unless overridden by other
-command line options.
-Most of these extensions are compatible with
-@uref{http://www.unix.org/single_unix_specification/,
-POSIX}; the few exceptions are suppressed if the
-@env{POSIXLY_CORRECT} environment variable is set.
-
-@itemize @bullet
-@item
-In the @code{$@var{n}} notation for macro arguments, @var{n} can contain
-several digits, while the System V @code{m4} only accepts one digit.
-This allows macros in GNU @code{m4} to take any number of
-arguments, and not only nine (@pxref{Arguments}).
-POSIX does not allow this extension, so it is disabled if
-@env{POSIXLY_CORRECT} is set.
-@c FIXME - update this bullet when ${11} is implemented.
-
-@item
-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.
-
-@item
-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 @option{-I} option and the
-@samp{M4PATH} environment variable (@pxref{Search Path}).
-
-@item
-Arguments to @code{undivert} can be non-numeric, in which case the named
-file will be included uninterpreted in the output (@pxref{Undivert}).
-
-@item
-Formatted output is supported through the @code{format} builtin, which
-is modeled after the C library function @code{printf} (@pxref{Format}).
-
-@item
-Searches and text substitution through regular expressions are supported
-by the @code{regexp} (@pxref{Regexp}) and @code{patsubst}
-(@pxref{Patsubst}) builtins.
-
-The syntax of regular expressions in M4 has never been clearly
-formalized. While OpenBSD M4 uses extended regular
-expressions for @code{regexp} and @code{patsubst}, GNU M4
-defaults to basic regular expressions, but provides
-@code{changeresyntax} (@pxref{Changeresyntax}) to change the flavor of
-regular expression syntax in use.
-
-@item
-The output of shell commands can be read into @code{m4} with
-@code{esyscmd} (@pxref{Esyscmd}).
-
-@item
-There is indirect access to any builtin macro with @code{builtin}
-(@pxref{Builtin}).
-
-@item
-Macros can be called indirectly through @code{indir} (@pxref{Indir}).
-
-@item
-The name of the program, the current input file, and the current input
-line number are accessible through the builtins @code{@w{__program__}},
-@code{@w{__file__}}, and @code{@w{__line__}} (@pxref{Location}).
-
-@item
-The generation of sync lines can be controlled through @code{syncoutput}
-(@pxref{Syncoutput}).
-
-@item
-The format of the output from @code{dumpdef} and macro tracing can be
-controlled with @code{debugmode} (@pxref{Debugmode}).
-
-@item
-The destination of trace and debug output can be controlled with
-@code{debugfile} (@pxref{Debugfile}).
-
-@item
-The @code{maketemp} (@pxref{Mkstemp}) macro behaves like @code{mkstemp},
-creating a new file with a unique name on every invocation, rather than
-following the insecure behavior of replacing the trailing @samp{X}
-characters with the @code{m4} process id. POSIX does not
-allow this extension, so @code{maketemp} is insecure if
-@env{POSIXLY_CORRECT} is set, but you should be using @code{mkstemp} in
-the first place.
-
-@item
-POSIX only requires support for the command line options
-@option{-s}, @option{-D}, and @option{-U}, so all other options accepted
-by GNU M4 are extensions. @xref{Invoking m4}, for a
-description of these options.
-
-@item
-The debugging and tracing facilities in GNU @code{m4} are much
-more extensive than in most other versions of @code{m4}.
-
-@item
-Some traditional implementations only allow reading standard input
-once, but GNU @code{m4} correctly handles multiple instances
-of @samp{-} on the command line.
-
-@item
-POSIX requires @code{m4wrap} (@pxref{M4wrap}) to act in FIFO
-(first-in, first-out) order, and most other implementations obey this.
-However, versions of GNU @code{m4} earlier than 1.6 used
-LIFO order. Furthermore, POSIX states that only the first
-argument to @code{m4wrap} is saved for later evaluation, but
-GNU @code{m4} saves and processes all arguments, with output
-separated by spaces.
-
-@item
-POSIX states that builtins that require arguments, but are
-called without arguments, have undefined behavior. Traditional
-implementations simply 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.
-@end itemize
-
-@node Incompatibilities
-@section Other incompatibilities
-
-There are a few other incompatibilities between this implementation of
-@code{m4}, and what POSIX requires, or what the System V
-version implemented.
-
-@itemize @bullet
-@item
-Traditional implementations handle @code{define(`f',`1')} (@pxref{Define})
-by undefining the entire stack of previous definitions, and if doing
-@code{undefine(`f')} first. GNU @code{m4} replaces just the top
-definition on the stack, as if doing @code{popdef(`f')} followed by
-@code{pushdef(`f',`1')}. POSIX allows either behavior.
-
-@item
-At one point, POSIX required @code{changequote(@var{arg})}
-(@pxref{Changequote}) to use newline as the close quote, but this was a
-bug, and the next version of POSIX is anticipated to state
-that using empty strings or just one argument is unspecified.
-Meanwhile, the GNU @code{m4} behavior of treating an empty
-end-quote delimiter as @samp{'} is not portable, as Solaris treats it as
-repeating the start-quote delimiter, and BSD treats it as leaving the
-previous end-quote delimiter unchanged. For predictable results, never
-call changequote with just one argument, or with empty strings for
-arguments.
-
-@item
-At one point, POSIX required @code{changecom(@var{arg},)}
-(@pxref{Changecom}) to make it impossible to end a comment, but this is
-a bug, and the next version of POSIX is anticipated to state
-that using empty strings is unspecified. Meanwhile, the GNU
-@code{m4} behavior of treating an empty end-comment delimiter as newline
-is not portable, as BSD treats it as leaving the previous end-comment
-delimiter unchanged. It is also impossible in BSD implementations to
-disable comments, even though that is required by POSIX. For
-predictable results, never call changecom with empty strings for
-arguments.
-
-@item
-Traditional implementations allow argument collection, but not string
-and comment processing, to span file boundaries. Thus, if @file{a.m4}
-contains @samp{len(}, and @file{b.m4} contains @samp{abc)},
-@kbd{m4 a.m4 b.m4} outputs @samp{3} with traditional @code{m4}, but
-gives an error message that the end of file was encountered inside a
-macro with GNU @code{m4}. On the other hand, traditional
-implementations do end of file processing for files included with
-@code{include} or @code{sinclude} (@pxref{Include}), while GNU
-@code{m4} seamlessly integrates the content of those files. Thus
-@code{include(`a.m4')include(`b.m4')} will output @samp{3} instead of
-giving an error.
-
-@item
-POSIX requires @code{eval} (@pxref{Eval}) to treat all
-operators with the same precedence as C@. However, earlier versions of
-GNU @code{m4} followed the traditional behavior of other
-@code{m4} implementations, where bitwise and logical negation (@samp{~}
-and @samp{!}) have lower precedence than equality operators; and where
-equality operators (@samp{==} and @samp{!=}) had the same precedence as
-relational operators (such as @samp{<}). Use explicit parentheses to
-ensure proper precedence. As extensions to POSIX,
-GNU @code{m4} gives well-defined semantics to operations that
-C leaves undefined, such as when overflow occurs, when shifting negative
-numbers, or when performing division by zero. POSIX also
-requires @samp{=} to cause an error, but many traditional
-implementations allowed it as an alias for @samp{==}.
-
-@item
-POSIX 2001 requires @code{translit} (@pxref{Translit}) to
-treat each character of the second and third arguments literally.
-However, it is anticipated that the next version of POSIX will
-allow the GNU @code{m4} behavior of treating @samp{-} as a
-range operator.
-
-@item
-POSIX requires @code{m4} to honor the locale environment
-variables of @env{LANG}, @env{LC_ALL}, @env{LC_CTYPE},
-@env{LC_MESSAGES}, and @env{NLSPATH}, but this has not yet been
-implemented in GNU @code{m4}.
-
-@item
-GNU @code{m4} implements sync lines differently from System V
-@code{m4}, when text is being diverted. GNU @code{m4} outputs
-the sync lines when the text is being diverted, and System V @code{m4}
-when the diverted text is being brought back.
-
-The problem is which lines and file names should be attached to text
-that is being, or has been, diverted. System V @code{m4} regards all
-the diverted text as being generated by the source line containing the
-@code{undivert} call, whereas GNU @code{m4} regards the
-diverted text as being generated at the time it is diverted.
-
-The sync line option is used mostly when using @code{m4} as
-a front end to a compiler. If a diverted line causes a compiler error,
-the error messages should most probably refer to the place where the
-diversion was made, and not where it was inserted again.
-
-@comment options: -s
-@example
-divert(2)2
-divert(1)1
-divert`'0
-@result{}#line 3 "stdin"
-@result{}0
-^D
-@result{}#line 2 "stdin"
-@result{}1
-@result{}#line 1 "stdin"
-@result{}2
-@end example
-
-@comment FIXME - this needs to be fixed before 2.0.
-The current @code{m4} implementation has a limitation that the syncline
-output at the start of each diversion occurs no matter what, even if the
-previous diversion did not end with a newline. This goes contrary to
-the claim that synclines appear on a line by themselves, so this
-limitation may be corrected in a future version of @code{m4}. In the
-meantime, when using @option{-s}, it is wisest to make sure all
-diversions end with newline.
-
-@item
-GNU @code{m4} makes no attempt at prohibiting self-referential
-definitions like:
-
-@comment ignore
-@example
-define(`x', `x')
-@result{}
-define(`x', `x ')
-@result{}
-@end example
-
-@cindex rescanning
-There is nothing inherently wrong with defining @samp{x} to
-return @samp{x}. The wrong thing is to expand @samp{x} unquoted,
-because that would cause an infinite rescan loop.
-In @code{m4}, one might use macros to hold strings, as we do for
-variables in other programming languages, further checking them with:
-
-@comment ignore
-@example
-ifelse(defn(`@var{holder}'), `@var{value}', @dots{})
-@end example
-
-@noindent
-In cases like this one, an interdiction for a macro to hold its own name
-would be a useless limitation. Of course, this leaves more rope for the
-GNU @code{m4} user to hang himself! Rescanning hangs may be
-avoided through careful programming, a little like for endless loops in
-traditional programming languages.
-
-@item
-POSIX states that only unquoted leading newlines and blanks
-(that is, space and tab) are ignored when collecting macro arguments.
-However, this appears to be a bug in POSIX, since most
-traditional implementations also ignore all whitespace (formfeed,
-carriage return, and vertical tab). GNU @code{m4} follows
-tradition and ignores all leading unquoted whitespace.
-@end itemize
-
-@node Experiments
-@section Experimental features in GNU M4
-
-Certain features of GNU @code{m4} are experimental.
-
-Some are only available if activated by an option given to
-@file{m4-@value{VERSION}/@/configure} at GNU @code{m4} installation
-time. The functionality
-might change or even go away in the future. @emph{Do not rely on it}.
-Please direct your comments about it the same way you would do for bugs.
-
-@section Changesyntax
-
-An experimental feature, which improves the flexibility of @code{m4},
-allows for changing the way the input is parsed (@pxref{Changesyntax}).
-No compile time option is needed for @code{changesyntax}. The
-implementation is careful to not slow down @code{m4} parsing, unlike the
-withdrawn experiment of @code{changeword} that appeared earlier in M4
-1.4.x.
-
-@section Multiple precision arithmetic
-
-Another experimental feature, which would improve @code{m4} usefulness,
-allows for multiple precision rational arithmetic similar to
-@code{eval}. You must have the GNU multi-precision (gmp)
-library installed, and should use @kbd{./configure --with-gmp} if you
-want this feature compiled in. The current implementation is unproven
-and might go away. Do not count on it yet.
-
-@node Answers
-@chapter Correct version of some examples
-
-Some of the examples in this manuals are buggy or not very robust, for
-demonstration purposes. Improved versions of these composite macros are
-presented here.
-
-@menu
-* Improved exch:: Solution for @code{exch}
-* Improved forloop:: Solution for @code{forloop}
-* Improved foreach:: Solution for @code{foreach}
-* Improved copy:: Solution for @code{copy}
-* Improved m4wrap:: Solution for @code{m4wrap}
-* Improved cleardivert:: Solution for @code{cleardivert}
-* Improved capitalize:: Solution for @code{capitalize}
-* Improved fatal_error:: Solution for @code{fatal_error}
-@end menu
-
-@node Improved exch
-@section Solution for @code{exch}
-
-The @code{exch} macro (@pxref{Arguments}) as presented requires clients
-to double quote their arguments. A nicer definition, which lets
-clients follow the rule of thumb of one level of quoting per level of
-parentheses, involves adding quotes in the definition of @code{exch}, as
-follows:
-
-@example
-define(`exch', ``$2', `$1'')
-@result{}
-define(exch(`expansion text', `macro'))
-@result{}
-macro
-@result{}expansion text
-@end example
-
-@node Improved forloop
-@section Solution for @code{forloop}
-
-The @code{forloop} macro (@pxref{Forloop}) as presented earlier can go
-into an infinite loop if given an iterator that is not parsed as a macro
-name. It does not do any sanity checking on its numeric bounds, and
-only permits decimal numbers for bounds. Here is an improved version,
-shipped as @file{m4-@value{VERSION}/@/doc/examples/@/forloop2.m4}; this
-version also optimizes overhead by calling four macros instead of six
-per iteration (excluding those in @var{text}), by not dereferencing the
-@var{iterator} in the helper @code{@w{_forloop}}.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-undivert(`forloop2.m4')dnl
-@result{}divert(`-1')
-@result{}# forloop(var, from, to, stmt) - improved version:
-@result{}# works even if VAR is not a strict macro name
-@result{}# performs sanity check that FROM is larger than TO
-@result{}# allows complex numerical expressions in TO and FROM
-@result{}define(`forloop', `ifelse(eval(`($2) <= ($3)'), `1',
-@result{} `pushdef(`$1')_$0(`$1', eval(`$2'),
-@result{} eval(`$3'), `$4')popdef(`$1')')')
-@result{}define(`_forloop',
-@result{} `define(`$1', `$2')$4`'ifelse(`$2', `$3', `',
-@result{} `$0(`$1', incr(`$2'), `$3', `$4')')')
-@result{}divert`'dnl
-include(`forloop2.m4')
-@result{}
-forloop(`i', `2', `1', `no iteration occurs')
-@result{}
-forloop(`', `1', `2', ` odd iterator name')
-@result{} odd iterator name odd iterator name
-forloop(`i', `5 + 5', `0xc', ` 0x`'eval(i, `16')')
-@result{} 0xa 0xb 0xc
-forloop(`i', `a', `b', `non-numeric bounds')
-@error{}m4:stdin:6: warning: eval: bad input: '(a) <= (b)'
-@result{}
-@end example
-
-One other change to notice is that the improved version used @samp{_$0}
-rather than @samp{_foreach} to invoke the helper routine. In general,
-this is a good practice to follow, because then the set of macros can be
-uniformly transformed. The following example shows a transformation
-that doubles the current quoting and appends a suffix @samp{2} to each
-transformed macro. If @code{foreach} refers to the literal
-@samp{_foreach}, then @code{foreach2} invokes @code{_foreach} instead of
-the intended @code{_foreach2}, and the mixing of quoting paradigms leads
-to an infinite recursion loop in this example.
-
-@comment options: -L9
-@comment status: 1
-@comment examples
-@example
-$ @kbd{m4 -d -L 9 -I doc/examples}
-define(`arg1', `$1')include(`forloop2.m4')include(`quote.m4')
-@result{}
-define(`double', `define(`$1'`2',
- arg1(patsubst(dquote(defn(`$1')), `[`']', `\&\&')))')
-@result{}
-double(`forloop')double(`_forloop')defn(`forloop2')
-@result{}ifelse(eval(``($2) <= ($3)''), ``1'',
-@result{} ``pushdef(``$1'')_$0(``$1'', eval(``$2''),
-@result{} eval(``$3''), ``$4'')popdef(``$1'')'')
-forloop(i, 1, 5, `ifelse(')forloop(i, 1, 5, `)')
-@result{}
-changequote(`[', `]')changequote([``], [''])
-@result{}
-forloop2(i, 1, 5, ``ifelse('')forloop2(i, 1, 5, ``)'')
-@result{}
-changequote`'include(`forloop.m4')
-@result{}
-double(`forloop')double(`_forloop')defn(`forloop2')
-@result{}pushdef(``$1'', ``$2'')_forloop($@@)popdef(``$1'')
-forloop(i, 1, 5, `ifelse(')forloop(i, 1, 5, `)')
-@result{}
-changequote(`[', `]')changequote([``], [''])
-@result{}
-forloop2(i, 1, 5, ``ifelse('')forloop2(i, 1, 5, ``)'')
-@error{}m4:stdin:12: recursion limit of 9 exceeded, use -L<N> to change it
-@end example
-
-One more optimization is still possible. Instead of repeatedly
-assigning a variable then invoking or dereferencing it, it is possible
-to pass the current iterator value as a single argument. Coupled with
-@code{curry} if other arguments are needed (@pxref{Composition}), or
-with helper macros if the argument is needed in more than one place in
-the expansion, the output can be generated with three, rather than four,
-macros of overhead per iteration. Notice how the file
-@file{m4-@value{VERSION}/@/doc/examples/@/forloop3.m4} rearranges the
-arguments of the helper @code{_forloop} to take two arguments that are
-placed around the current value. By splitting a balanced set of
-parantheses across multiple arguments, the helper macro can now be
-shared by @code{forloop} and the new @code{forloop_arg}.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`forloop3.m4')
-@result{}
-undivert(`forloop3.m4')dnl
-@result{}divert(`-1')
-@result{}# forloop_arg(from, to, macro) - invoke MACRO(value) for
-@result{}# each value between FROM and TO, without define overhead
-@result{}define(`forloop_arg', `ifelse(eval(`($1) <= ($2)'), `1',
-@result{} `_forloop(`$1', eval(`$2'), `$3(', `)')')')
-@result{}# forloop(var, from, to, stmt) - refactored to share code
-@result{}define(`forloop', `ifelse(eval(`($2) <= ($3)'), `1',
-@result{} `pushdef(`$1')_forloop(eval(`$2'), eval(`$3'),
-@result{} `define(`$1',', `)$4')popdef(`$1')')')
-@result{}define(`_forloop',
-@result{} `$3`$1'$4`'ifelse(`$1', `$2', `',
-@result{} `$0(incr(`$1'), `$2', `$3', `$4')')')
-@result{}divert`'dnl
-forloop(`i', `1', `3', ` i')
-@result{} 1 2 3
-define(`echo', `$@@')
-@result{}
-forloop_arg(`1', `3', ` echo')
-@result{} 1 2 3
-include(`curry.m4')
-@result{}
-forloop_arg(`1', `3', `curry(`pushdef', `a')')
-@result{}
-a
-@result{}3
-popdef(`a')a
-@result{}2
-popdef(`a')a
-@result{}1
-popdef(`a')a
-@result{}a
-@end example
-
-Of course, it is possible to make even more improvements, such as
-adding an optional step argument, or allowing iteration through
-descending sequences. GNU Autoconf provides some of these
-additional bells and whistles in its @code{m4_for} macro.
-
-@node Improved foreach
-@section Solution for @code{foreach}
-
-The @code{foreach} and @code{foreachq} macros (@pxref{Foreach}) as
-presented earlier each have flaws. First, we will examine and fix the
-quadratic behavior of @code{foreachq}:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`foreachq.m4')
-@result{}
-traceon(`shift')debugmode(`aq')
-@result{}
-foreachq(`x', ``1', `2', `3', `4'', `x
-')dnl
-@result{}1
-@error{}m4trace: -3- shift(`1', `2', `3', `4')
-@error{}m4trace: -2- shift(`1', `2', `3', `4')
-@result{}2
-@error{}m4trace: -4- shift(`1', `2', `3', `4')
-@error{}m4trace: -3- shift(`2', `3', `4')
-@error{}m4trace: -3- shift(`1', `2', `3', `4')
-@error{}m4trace: -2- shift(`2', `3', `4')
-@result{}3
-@error{}m4trace: -5- shift(`1', `2', `3', `4')
-@error{}m4trace: -4- shift(`2', `3', `4')
-@error{}m4trace: -3- shift(`3', `4')
-@error{}m4trace: -4- shift(`1', `2', `3', `4')
-@error{}m4trace: -3- shift(`2', `3', `4')
-@error{}m4trace: -2- shift(`3', `4')
-@result{}4
-@error{}m4trace: -6- shift(`1', `2', `3', `4')
-@error{}m4trace: -5- shift(`2', `3', `4')
-@error{}m4trace: -4- shift(`3', `4')
-@error{}m4trace: -3- shift(`4')
-@end example
-
-@cindex quadratic behavior, avoiding
-@cindex avoiding quadratic behavior
-Each successive iteration was adding more quoted @code{shift}
-invocations, and the entire list contents were passing through every
-iteration. In general, when recursing, it is a good idea to make the
-recursion use fewer arguments, rather than adding additional quoted
-uses of @code{shift}. By doing so, @code{m4} uses less memory, invokes
-fewer macros, is less likely to run into machine limits, and most
-importantly, performs faster. The fixed version of @code{foreachq} can
-be found in @file{m4-@value{VERSION}/@/doc/examples/@/foreachq2.m4}:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`foreachq2.m4')
-@result{}
-undivert(`foreachq2.m4')dnl
-@result{}include(`quote.m4')dnl
-@result{}divert(`-1')
-@result{}# foreachq(x, `item_1, item_2, ..., item_n', stmt)
-@result{}# quoted list, improved version
-@result{}define(`foreachq', `pushdef(`$1')_$0($@@)popdef(`$1')')
-@result{}define(`_arg1q', ``$1'')
-@result{}define(`_rest', `ifelse(`$#', `1', `', `dquote(shift($@@))')')
-@result{}define(`_foreachq', `ifelse(`$2', `', `',
-@result{} `define(`$1', _arg1q($2))$3`'$0(`$1', _rest($2), `$3')')')
-@result{}divert`'dnl
-traceon(`shift')debugmode(`aq')
-@result{}
-foreachq(`x', ``1', `2', `3', `4'', `x
-')dnl
-@result{}1
-@error{}m4trace: -3- shift(`1', `2', `3', `4')
-@result{}2
-@error{}m4trace: -3- shift(`2', `3', `4')
-@result{}3
-@error{}m4trace: -3- shift(`3', `4')
-@result{}4
-@end example
-
-Note that the fixed version calls unquoted helper macros in
-@code{@w{_foreachq}} to trim elements immediately; those helper macros
-in turn must re-supply the layer of quotes lost in the macro invocation.
-Contrast the use of @code{@w{_arg1q}}, which quotes the first list
-element, with @code{@w{_arg1}} of the earlier implementation that
-returned the first list element directly. Additionally, by calling the
-helper method immediately, the @samp{defn(`@var{iterator}')} no longer
-contains unexpanded macros.
-
-The astute m4 programmer might notice that the solution above still uses
-more macro invocations than strictly necessary. Note that @samp{$2},
-which contains an arbitrarily long quoted list, is expanded and
-rescanned three times per iteration of @code{_foreachq}. Furthermore,
-every iteration of the algorithm effectively unboxes then reboxes the
-list, which costs a couple of macro invocations. It is possible to
-rewrite the algorithm by swapping the order of the arguments to
-@code{_foreachq} in order to operate on an unboxed list in the first
-place, and by using the fixed-length @samp{$#} instead of an arbitrary
-length list as the key to end recursion. The result is an overhead of
-six macro invocations per loop (excluding any macros in @var{text}),
-instead of eight. This alternative approach is available as
-@file{m4-@value{VERSION}/@/doc/examples/@/foreach3.m4}:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`foreachq3.m4')
-@result{}
-undivert(`foreachq3.m4')dnl
-@result{}divert(`-1')
-@result{}# foreachq(x, `item_1, item_2, ..., item_n', stmt)
-@result{}# quoted list, alternate improved version
-@result{}define(`foreachq', `ifelse(`$2', `', `',
-@result{} `pushdef(`$1')_$0(`$1', `$3', `', $2)popdef(`$1')')')
-@result{}define(`_foreachq', `ifelse(`$#', `3', `',
-@result{} `define(`$1', `$4')$2`'$0(`$1', `$2',
-@result{} shift(shift(shift($@@))))')')
-@result{}divert`'dnl
-traceon(`shift')debugmode(`aq')
-@result{}
-foreachq(`x', ``1', `2', `3', `4'', `x
-')dnl
-@result{}1
-@error{}m4trace: -4- shift(`x', `x
-@error{}', `', `1', `2', `3', `4')
-@error{}m4trace: -3- shift(`x
-@error{}', `', `1', `2', `3', `4')
-@error{}m4trace: -2- shift(`', `1', `2', `3', `4')
-@result{}2
-@error{}m4trace: -4- shift(`x', `x
-@error{}', `1', `2', `3', `4')
-@error{}m4trace: -3- shift(`x
-@error{}', `1', `2', `3', `4')
-@error{}m4trace: -2- shift(`1', `2', `3', `4')
-@result{}3
-@error{}m4trace: -4- shift(`x', `x
-@error{}', `2', `3', `4')
-@error{}m4trace: -3- shift(`x
-@error{}', `2', `3', `4')
-@error{}m4trace: -2- shift(`2', `3', `4')
-@result{}4
-@error{}m4trace: -4- shift(`x', `x
-@error{}', `3', `4')
-@error{}m4trace: -3- shift(`x
-@error{}', `3', `4')
-@error{}m4trace: -2- shift(`3', `4')
-@end example
-
-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.6 to reuse results of
-previous scans, both styles of @code{foreachq} become linear in the
-number of bytes scanned, but the @file{foreachq3.m4} version remains
-noticeably faster because of fewer macro invocations. Notice how the
-implementation injects an empty argument prior to expanding @samp{$2}
-within @code{foreachq}; the helper macro @code{_foreachq} then ignores
-the third argument altogether, and ends recursion when there are three
-arguments left because there was nothing left to pass through
-@code{shift}. Thus, each iteration only needs one @code{ifelse}, rather
-than the two conditionals used in the version from @file{foreachq2.m4}.
-
-@cindex nine arguments, more than
-@cindex more than nine arguments
-@cindex arguments, more than nine
-So far, all of the implementations of @code{foreachq} presented have
-been quadratic with M4 1.4.x. But @code{forloop} is linear, because
-each iteration parses a constant amount of arguments. So, it is
-possible to design a variant that uses @code{forloop} to do the
-iteration, then uses @samp{$@@} only once at the end, giving a linear
-result even with older M4 implementations. This implementation relies
-on the GNU extension that @samp{$10} expands to the tenth
-argument rather than the first argument concatenated with @samp{0}. The
-trick is to define an intermediate macro that repeats the text
-@code{m4_define(`$1', `$@var{n}')$2`'}, with @samp{n} set to successive
-integers corresponding to each argument. The helper macro
-@code{_foreachq_} is needed in order to generate the literal sequences
-such as @samp{$1} into the intermediate macro, rather than expanding
-them as the arguments of @code{_foreachq}. With this approach, no
-@code{shift} calls are even needed! However, when linear recursion is
-available in new enough M4, the time and memory cost of using
-@code{forloop} to build an intermediate macro outweigh the costs of any
-of the previous implementations (there are seven macros of overhead per
-iteration instead of six in @file{foreachq3.m4}, and the entire
-intermediate macro must be built in memory before any iteration is
-expanded). Additionally, this approach will need adjustment when a
-future version of M4 follows POSIX by no longer treating
-@samp{$10} as the tenth argument; the anticipation is that
-@samp{$@{10@}} can be used instead, although that alternative syntax is
-not yet supported.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`foreachq4.m4')
-@result{}
-undivert(`foreachq4.m4')dnl
-@result{}include(`forloop2.m4')dnl
-@result{}divert(`-1')
-@result{}# foreachq(x, `item_1, item_2, ..., item_n', stmt)
-@result{}# quoted list, version based on forloop
-@result{}define(`foreachq',
-@result{}`ifelse(`$2', `', `', `_$0(`$1', `$3', $2)')')
-@result{}define(`_foreachq',
-@result{}`pushdef(`$1', forloop(`$1', `3', `$#',
-@result{} `$0_(`1', `2', indir(`$1'))')`popdef(
-@result{} `$1')')indir(`$1', $@@)')
-@result{}define(`_foreachq_',
-@result{}``define(`$$1', `$$3')$$2`''')
-@result{}divert`'dnl
-traceon(`shift')debugmode(`aq')
-@result{}
-foreachq(`x', ``1', `2', `3', `4'', `x
-')dnl
-@result{}1
-@result{}2
-@result{}3
-@result{}4
-@end example
-
-For yet another approach, the improved version of @code{foreach},
-available in @file{m4-@value{VERSION}/@/doc/examples/@/foreach2.m4},
-simply overquotes the arguments to @code{@w{_foreach}} to begin with,
-using @code{dquote_elt}. Then @code{@w{_foreach}} can just use
-@code{@w{_arg1}} to remove the extra layer of quoting that was added up
-front:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`foreach2.m4')
-@result{}
-undivert(`foreach2.m4')dnl
-@result{}include(`quote.m4')dnl
-@result{}divert(`-1')
-@result{}# foreach(x, (item_1, item_2, ..., item_n), stmt)
-@result{}# parenthesized list, improved version
-@result{}define(`foreach', `pushdef(`$1')_$0(`$1',
-@result{} (dquote(dquote_elt$2)), `$3')popdef(`$1')')
-@result{}define(`_arg1', `$1')
-@result{}define(`_foreach', `ifelse(`$2', `(`')', `',
-@result{} `define(`$1', _arg1$2)$3`'$0(`$1', (dquote(shift$2)), `$3')')')
-@result{}divert`'dnl
-traceon(`shift')debugmode(`aq')
-@result{}
-foreach(`x', `(`1', `2', `3', `4')', `x
-')dnl
-@error{}m4trace: -4- shift(`1', `2', `3', `4')
-@error{}m4trace: -4- shift(`2', `3', `4')
-@error{}m4trace: -4- shift(`3', `4')
-@result{}1
-@error{}m4trace: -3- shift(``1'', ``2'', ``3'', ``4'')
-@result{}2
-@error{}m4trace: -3- shift(``2'', ``3'', ``4'')
-@result{}3
-@error{}m4trace: -3- shift(``3'', ``4'')
-@result{}4
-@error{}m4trace: -3- shift(``4'')
-@end example
-
-It is likewise possible to write a variant of @code{foreach} that
-performs in linear time on M4 1.4.x; the easiest method is probably
-writing a version of @code{foreach} that unboxes its list, then invokes
-@code{_foreachq} as previously defined in @file{foreachq4.m4}.
-
-@cindex filtering defined symbols
-@cindex subset of defined symbols
-@cindex defined symbols, filtering
-With a robust @code{foreachq} implementation, it is possible to create a
-filter on a list of defined symbols. This next example will find all
-symbols that contain @samp{if} or @samp{def}, via two different
-approaches. In the first approach, @code{dquote_elt} is used to
-overquote each list element, then @code{dquote} forms the list; that
-way, the iterator @code{macro} can be expanded in place because its
-contents are already quoted. This approach also uses a self-modifying
-macro @code{sep} to provide the correct number of commas. In the second
-approach, the iterator @code{macro} contains live text, so it must be
-used with @code{defn} to avoid unintentional expansion. The correct
-number of commas is achieved by using @code{shift} to ignore the first
-one, although a leading space still remains.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`quote.m4')include(`foreachq2.m4')
-@result{}
-pushdef(`sep', `define(`sep', ``, '')')
-@result{}
-foreachq(`macro', dquote(dquote_elt(m4symbols)),
- `regexp(macro, `.*if.*', `sep`\&'')')
-@result{}ifdef, ifelse, shift
-popdef(`sep')
-@result{}
-shift(foreachq(`macro', dquote(m4symbols),
- `regexp(defn(`macro'), `def', `,` ''dquote(defn(`macro')))'))
-@result{} define, defn, dumpdef, ifdef, popdef, pushdef, undefine
-@end example
-
-In summary, recursion over list elements is trickier than it appeared at
-first glance, but provides a powerful idiom within @code{m4} processing.
-As a final demonstration, both list styles are now able to handle
-several scenarios that would wreak havoc on one or both of the original
-implementations. This points out one other difference between the
-list styles. @code{foreach} evaluates unquoted list elements only once,
-in preparation for calling @code{@w{_foreach}}, similary for
-@code{foreachq} as provided by @file{foreachq3.m4} or
-@file{foreachq4.m4}. But
-@code{foreachq}, as provided by @file{foreachq2.m4},
-evaluates unquoted list elements twice while visiting the first list
-element, once in @code{@w{_arg1q}} and once in @code{@w{_rest}}. When
-deciding which list style to use, one must take into account whether
-repeating the side effects of unquoted list elements will have any
-detrimental effects.
-
-@comment examples
-@example
-$ @kbd{m4 -d -I doc/examples}
-include(`foreach2.m4')
-@result{}
-include(`foreachq2.m4')
-@result{}
-dnl 0-element list:
-foreach(`x', `', `<x>') / foreachq(`x', `', `<x>')
-@result{} /@w{ }
-dnl 1-element list of empty element
-foreach(`x', `()', `<x>') / foreachq(`x', ``'', `<x>')
-@result{}<> / <>
-dnl 2-element list of empty elements
-foreach(`x', `(`',`')', `<x>') / foreachq(`x', ``',`'', `<x>')
-@result{}<><> / <><>
-dnl 1-element list of a comma
-foreach(`x', `(`,')', `<x>') / foreachq(`x', ``,'', `<x>')
-@result{}<,> / <,>
-dnl 2-element list of unbalanced parentheses
-foreach(`x', `(`(', `)')', `<x>') / foreachq(`x', ``(', `)'', `<x>')
-@result{}<(><)> / <(><)>
-define(`ab', `oops')dnl using defn(`iterator')
-foreach(`x', `(`a', `b')', `defn(`x')') /dnl
- foreachq(`x', ``a', `b'', `defn(`x')')
-@result{}ab / ab
-define(`active', `ACT, IVE')
-@result{}
-traceon(`active')
-@result{}
-dnl list of unquoted macros; expansion occurs before recursion
-foreach(`x', `(active, active)', `<x>
-')dnl
-@error{}m4trace: -4- active -> `ACT, IVE'
-@error{}m4trace: -4- active -> `ACT, IVE'
-@result{}<ACT>
-@result{}<IVE>
-@result{}<ACT>
-@result{}<IVE>
-foreachq(`x', `active, active', `<x>
-')dnl
-@error{}m4trace: -3- active -> `ACT, IVE'
-@error{}m4trace: -3- active -> `ACT, IVE'
-@result{}<ACT>
-@error{}m4trace: -3- active -> `ACT, IVE'
-@error{}m4trace: -3- active -> `ACT, IVE'
-@result{}<IVE>
-@result{}<ACT>
-@result{}<IVE>
-dnl list of quoted macros; expansion occurs during recursion
-foreach(`x', `(`active', `active')', `<x>
-')dnl
-@error{}m4trace: -1- active -> `ACT, IVE'
-@result{}<ACT, IVE>
-@error{}m4trace: -1- active -> `ACT, IVE'
-@result{}<ACT, IVE>
-foreachq(`x', ``active', `active'', `<x>
-')dnl
-@error{}m4trace: -1- active -> `ACT, IVE'
-@result{}<ACT, IVE>
-@error{}m4trace: -1- active -> `ACT, IVE'
-@result{}<ACT, IVE>
-dnl list of double-quoted macro names; no expansion
-foreach(`x', `(``active'', ``active'')', `<x>
-')dnl
-@result{}<active>
-@result{}<active>
-foreachq(`x', ```active'', ``active''', `<x>
-')dnl
-@result{}<active>
-@result{}<active>
-@end example
-
-@node Improved copy
-@section Solution for @code{copy}
-
-The macro @code{copy} presented above works with M4 1.6 and newer, but
-is unable to handle builtin tokens with M4 1.4.x, because it tries to
-pass the builtin token through the macro @code{curry}, where it is
-silently flattened to an empty string (@pxref{Composition}). Rather
-than using the problematic @code{curry} to work around the limitation
-that @code{stack_foreach} expects to invoke a macro that takes exactly
-one argument, we can write a new macro that lets us form the exact
-two-argument @code{pushdef} call sequence needed, so that we are no
-longer passing a builtin token through a text macro.
-
-@deffn Composite stack_foreach_sep (@var{macro}, @var{pre}, @var{post}, @
- @var{sep})
-@deffnx Composite stack_foreach_sep_lifo (@var{macro}, @var{pre}, @
- @var{post}, @var{sep})
-For each of the @code{pushdef} definitions associated with @var{macro},
-expand the sequence @samp{@var{pre}`'definition`'@var{post}}.
-Additionally, expand @var{sep} between definitions.
-@code{stack_foreach_sep} visits the oldest definition first, while
-@code{stack_foreach_sep_lifo} visits the current definition first. The
-expansion may dereference @var{macro}, but should not modify it. There
-are a few special macros, such as @code{defn}, which cannot be used as
-the @var{macro} parameter.
-@end deffn
-
-Note that @code{stack_foreach(`@var{macro}', `@var{action}')} is
-equivalent to @code{stack_foreach_sep(`@var{macro}', `@var{action}(',
-`)')}. By supplying explicit parentheses, split among the @var{pre} and
-@var{post} arguments to @code{stack_foreach_sep}, it is now possible to
-construct macro calls with more than one argument, without passing
-builtin tokens through a macro call. It is likewise possible to
-directly reference the stack definitions without a macro call, by
-leaving @var{pre} and @var{post} empty. Thus, in addition to fixing
-@code{copy} on builtin tokens, it also executes with fewer macro
-invocations.
-
-The new macro also adds a separator that is only output after the first
-iteration of the helper @code{_stack_reverse_sep}, implemented by
-prepending the original @var{sep} to @var{pre} and omitting a @var{sep}
-argument in subsequent iterations. Note that the empty string that
-separates @var{sep} from @var{pre} is provided as part of the fourth
-argument when originally calling @code{_stack_reverse_sep}, and not by
-writing @code{$4`'$3} as the third argument in the recursive call; while
-the other approach would give the same output, it does so at the expense
-of increasing the argument size on each iteration of
-@code{_stack_reverse_sep}, which results in quadratic instead of linear
-execution time. The improved stack walking macros are available in
-@file{m4-@value{VERSION}/@/doc/examples/@/stack_sep.m4}:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`stack_sep.m4')
-@result{}
-define(`copy', `ifdef(`$2', `errprint(`$2 already defined
-')m4exit(`1')',
- `stack_foreach_sep(`$1', `pushdef(`$2',', `)')')')dnl
-pushdef(`a', `1')pushdef(`a', defn(`divnum'))
-@result{}
-copy(`a', `b')
-@result{}
-b
-@result{}0
-popdef(`b')
-@result{}
-b
-@result{}1
-pushdef(`c', `1')pushdef(`c', `2')
-@result{}
-stack_foreach_sep_lifo(`c', `', `', `, ')
-@result{}2, 1
-undivert(`stack_sep.m4')dnl
-@result{}divert(`-1')
-@result{}# stack_foreach_sep(macro, pre, post, sep)
-@result{}# Invoke PRE`'defn`'POST with a single argument of each definition
-@result{}# from the definition stack of MACRO, starting with the oldest, and
-@result{}# separated by SEP between definitions.
-@result{}define(`stack_foreach_sep',
-@result{}`_stack_reverse_sep(`$1', `tmp-$1')'dnl
-@result{}`_stack_reverse_sep(`tmp-$1', `$1', `$2`'defn(`$1')$3', `$4`'')')
-@result{}# stack_foreach_sep_lifo(macro, pre, post, sep)
-@result{}# Like stack_foreach_sep, but starting with the newest definition.
-@result{}define(`stack_foreach_sep_lifo',
-@result{}`_stack_reverse_sep(`$1', `tmp-$1', `$2`'defn(`$1')$3', `$4`'')'dnl
-@result{}`_stack_reverse_sep(`tmp-$1', `$1')')
-@result{}define(`_stack_reverse_sep',
-@result{}`ifdef(`$1', `pushdef(`$2', defn(`$1'))$3`'popdef(`$1')$0(
-@result{} `$1', `$2', `$4$3')')')
-@result{}divert`'dnl
-@end example
-
-@node Improved m4wrap
-@section Solution for @code{m4wrap}
-
-The replacement @code{m4wrap} versions presented above, designed to
-guarantee FIFO or LIFO order regardless of the underlying M4
-implementation, share a bug when dealing with wrapped text that looks
-like parameter expansion. Note how the invocation of
-@code{m4wrap@var{n}} interprets these parameters, while using the
-builtin preserves them for their intended use.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`wraplifo.m4')
-@result{}
-m4wrap(`define(`foo', ``$0:'-$1-$*-$#-')foo(`a', `b')
-')
-@result{}
-builtin(`m4wrap', ``'define(`bar', ``$0:'-$1-$*-$#-')bar(`a', `b')
-')
-@result{}
-^D
-@result{}m4wrap0:---0-
-@result{}bar:-a-a,b-2-
-@end example
-
-Additionally, the computation of @code{_m4wrap_level} and creation of
-multiple @code{m4wrap@var{n}} placeholders in the original examples is
-more expensive in time and memory than strictly necessary. Notice how
-the improved version grabs the wrapped text via @code{defn} to avoid
-parameter expansion, then undefines @code{_m4wrap_text}, before
-stripping a level of quotes with @code{_arg1} to expand the text. That
-way, each level of wrapping reuses the single placeholder, which starts
-each nesting level in an undefined state.
-
-Finally, it is worth emulating the GNU M4 extension of saving
-all arguments to @code{m4wrap}, separated by a space, rather than saving
-just the first argument. This is done with the @code{join} macro
-documented previously (@pxref{Shift}). The improved LIFO example is
-shipped as @file{m4-@value{VERSION}/@/doc/examples/@/wraplifo2.m4}, and
-can easily be converted to a FIFO solution by swapping the adjacent
-invocations of @code{joinall} and @code{defn}.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`wraplifo2.m4')
-@result{}
-undivert(`wraplifo2.m4')dnl
-@result{}dnl Redefine m4wrap to have LIFO semantics, improved example.
-@result{}include(`join.m4')dnl
-@result{}define(`_m4wrap', defn(`m4wrap'))dnl
-@result{}define(`_arg1', `$1')dnl
-@result{}define(`m4wrap',
-@result{}`ifdef(`_$0_text',
-@result{} `define(`_$0_text', joinall(` ', $@@)defn(`_$0_text'))',
-@result{} `_$0(`_arg1(defn(`_$0_text')undefine(`_$0_text'))')dnl
-@result{}define(`_$0_text', joinall(` ', $@@))')')dnl
-m4wrap(`define(`foo', ``$0:'-$1-$*-$#-')foo(`a', `b')
-')
-@result{}
-m4wrap(`lifo text
-m4wrap(`nested', `', `$@@
-')')
-@result{}
-^D
-@result{}lifo text
-@result{}foo:-a-a,b-2-
-@result{}nested $@@
-@end example
-
-@node Improved cleardivert
-@section Solution for @code{cleardivert}
-
-The @code{cleardivert} macro (@pxref{Cleardivert}) cannot, as it stands, be
-called without arguments to clear all pending diversions. That is
-because using undivert with an empty string for an argument is different
-than using it with no arguments at all. Compare the earlier definition
-with one that takes the number of arguments into account:
-
-@example
-define(`cleardivert',
- `pushdef(`_n', divnum)divert(`-1')undivert($@@)divert(_n)popdef(`_n')')
-@result{}
-divert(`1')one
-divert
-@result{}
-cleardivert
-@result{}
-undivert
-@result{}one
-@result{}
-define(`cleardivert',
- `pushdef(`_num', divnum)divert(`-1')ifelse(`$#', `0',
- `undivert`'', `undivert($@@)')divert(_num)popdef(`_num')')
-@result{}
-divert(`2')two
-divert
-@result{}
-cleardivert
-@result{}
-undivert
-@result{}
-@end example
-
-@node Improved capitalize
-@section Solution for @code{capitalize}
-
-The @code{capitalize} macro (@pxref{Patsubst}) as presented earlier does
-not allow clients to follow the quoting rule of thumb. Consider the
-three macros @code{active}, @code{Active}, and @code{ACTIVE}, and the
-difference between calling @code{capitalize} with the expansion of a
-macro, expanding the result of a case change, and changing the case of a
-double-quoted string:
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`capitalize.m4')dnl
-define(`active', `act1, ive')dnl
-define(`Active', `Act2, Ive')dnl
-define(`ACTIVE', `ACT3, IVE')dnl
-upcase(active)
-@result{}ACT1,IVE
-upcase(`active')
-@result{}ACT3, IVE
-upcase(``active'')
-@result{}ACTIVE
-downcase(ACTIVE)
-@result{}act3,ive
-downcase(`ACTIVE')
-@result{}act1, ive
-downcase(``ACTIVE'')
-@result{}active
-capitalize(active)
-@result{}Act1
-capitalize(`active')
-@result{}Active
-capitalize(``active'')
-@result{}_capitalize(`active')
-define(`A', `OOPS')
-@result{}
-capitalize(active)
-@result{}OOPSct1
-capitalize(`active')
-@result{}OOPSctive
-@end example
-
-First, when @code{capitalize} is called with more than one argument, it
-was throwing away later arguments, whereas @code{upcase} and
-@code{downcase} used @samp{$*} to collect them all. The fix is simple:
-use @samp{$*} consistently.
-
-Next, with single-quoting, @code{capitalize} outputs a single character,
-a set of quotes, then the rest of the characters, making it impossible
-to invoke @code{Active} after the fact, and allowing the alternate macro
-@code{A} to interfere. Here, the solution is to use additional quoting
-in the helper macros, then pass the final over-quoted output string
-through @code{_arg1} to remove the extra quoting and finally invoke the
-concatenated portions as a single string.
-
-Finally, when passed a double-quoted string, the nested macro
-@code{_capitalize} is never invoked because it ended up nested inside
-quotes. This one is the toughest to fix. In short, we have no idea how
-many levels of quotes are in effect on the substring being altered by
-@code{patsubst}. If the replacement string cannot be expressed entirely
-in terms of literal text and backslash substitutions, then we need a
-mechanism to guarantee that the helper macros are invoked outside of
-quotes. In other words, this sounds like a job for @code{changequote}
-(@pxref{Changequote}). By changing the active quoting characters, we
-can guarantee that replacement text injected by @code{patsubst} always
-occurs in the middle of a string that has exactly one level of
-over-quoting using alternate quotes; so the replacement text closes the
-quoted string, invokes the helper macros, then reopens the quoted
-string. In turn, that means the replacement text has unbalanced quotes,
-necessitating another round of @code{changequote}.
-
-In the fixed version below, (also shipped as
-@file{m4-@value{VERSION}/@/doc/examples/@/capitalize.m4}),
-@code{capitalize} uses the alternate quotes of @samp{<<[} and @samp{]>>}
-(the longer strings are chosen so as to be less likely to appear in the
-text being converted). The helpers @code{_to_alt} and @code{_from_alt}
-merely reduce the number of characters required to perform a
-@code{changequote}, since the definition changes twice. The outermost
-pair means that @code{patsubst} and @code{_capitalize_alt} are invoked
-with alternate quoting; the innermost pair is used so that the third
-argument to @code{patsubst} can contain an unbalanced
-@samp{]>>}/@samp{<<[} pair. Note that @code{upcase} and @code{downcase}
-must be redefined as @code{_upcase_alt} and @code{_downcase_alt}, since
-they contain nested quotes but are invoked with the alternate quoting
-scheme in effect.
-
-@comment examples
-@example
-$ @kbd{m4 -I doc/examples}
-include(`capitalize2.m4')dnl
-define(`active', `act1, ive')dnl
-define(`Active', `Act2, Ive')dnl
-define(`ACTIVE', `ACT3, IVE')dnl
-define(`A', `OOPS')dnl
-capitalize(active; `active'; ``active''; ```actIVE''')
-@result{}Act1,Ive; Act2, Ive; Active; `Active'
-undivert(`capitalize2.m4')dnl
-@result{}divert(`-1')
-@result{}# upcase(text)
-@result{}# downcase(text)
-@result{}# capitalize(text)
-@result{}# change case of text, improved version
-@result{}define(`upcase', `translit(`$*', `a-z', `A-Z')')
-@result{}define(`downcase', `translit(`$*', `A-Z', `a-z')')
-@result{}define(`_arg1', `$1')
-@result{}define(`_to_alt', `changequote(`<<[', `]>>')')
-@result{}define(`_from_alt', `changequote(<<[`]>>, <<[']>>)')
-@result{}define(`_upcase_alt', `translit(<<[$*]>>, <<[a-z]>>, <<[A-Z]>>)')
-@result{}define(`_downcase_alt', `translit(<<[$*]>>, <<[A-Z]>>, <<[a-z]>>)')
-@result{}define(`_capitalize_alt',
-@result{} `regexp(<<[$1]>>, <<[^\(\w\)\(\w*\)]>>,
-@result{} <<[_upcase_alt(<<[<<[\1]>>]>>)_downcase_alt(<<[<<[\2]>>]>>)]>>)')
-@result{}define(`capitalize',
-@result{} `_arg1(_to_alt()patsubst(<<[<<[$*]>>]>>, <<[\w+]>>,
-@result{} _from_alt()`]>>_$0_alt(<<[\&]>>)<<['_to_alt())_from_alt())')
-@result{}divert`'dnl
-@end example
-
-@node Improved fatal_error
-@section Solution for @code{fatal_error}
-
-The @code{fatal_error} macro (@pxref{M4exit}) is not robust to versions
-of GNU M4 earlier than 1.4.8, where invoking @code{@w{__file__}}
-(@pxref{Location}) inside @code{m4wrap} would result in an empty string,
-and @code{@w{__line__}} resulted in @samp{0} even though all files start
-at line 1. Furthermore, versions earlier than 1.4.6 did not support the
-@code{@w{__program__}} macro. If you want @code{fatal_error} to work
-across the entire 1.4.x release series, a better implementation would
-be:
-
-@comment status: 1
-@example
-define(`fatal_error',
- `errprint(ifdef(`__program__', `__program__', ``m4'')'dnl
-`:ifelse(__line__, `0', `',
- `__file__:__line__:')` fatal error: $*
-')m4exit(`1')')
-@result{}
-m4wrap(`divnum(`demo of internal message')
-fatal_error(`inside wrapped text')')
-@result{}
-^D
-@error{}m4:stdin:6: warning: divnum: extra arguments ignored: 1 > 0
-@result{}0
-@error{}m4:stdin:6: fatal error: inside wrapped text
-@end example
-
-@c ========================================================== Appendices
-
-@node Copying This Package
-@appendix How to make copies of the overall M4 package
-@cindex License, code
-
-This appendix covers the license for copying the source code of the
-overall M4 package. This manual is under a different set of
-restrictions, covered later (@pxref{Copying This Manual}).
-
-@menu
-* GNU General Public License:: License for copying the M4 package
-@end menu
-
-@node GNU General Public License
-@appendixsec License for copying the M4 package
-@cindex GPL, GNU General Public License
-@cindex GNU General Public License
-@cindex General Public License (GPL), GNU
-@include gpl-3.0.texi
-
-@node Copying This Manual
-@appendix How to make copies of this manual
-@cindex License, manual
-
-This appendix covers the license for copying this manual. Note that
-some of the longer examples in this manual are also distributed in the
-directory @file{m4-@value{VERSION}/@/doc/examples/}, where a more
-permissive license is in effect when copying just the examples.
-
-@menu
-* GNU Free Documentation License:: License for copying this manual
-@end menu
-
-@node GNU Free Documentation License
-@appendixsec License for copying this manual
-@cindex FDL, GNU Free Documentation License
-@cindex GNU Free Documentation License
-@cindex Free Documentation License (FDL), GNU
-@include fdl-1.3.texi
-
-@node Indices
-@appendix Indices of concepts and macros
-
-@menu
-* Macro index:: Index for all @code{m4} macros
-* Concept index:: Index for many concepts
-@end menu
-
-@node Macro index
-@appendixsec Index for all @code{m4} macros
-
-This index covers all @code{m4} builtins, as well as several useful
-composite macros. References are exclusively to the places where a
-macro is introduced the first time.
-
-@printindex fn
-
-@node Concept index
-@appendixsec Index for many concepts
-
-@printindex cp
-
-@bye
-
-@c Local Variables:
-@c fill-column: 72
-@c ispell-local-dictionary: "american"
-@c indent-tabs-mode: nil
-@c whitespace-check-buffer-indent: nil
-@c End:
diff --git a/m4/builtin.c b/m4/builtin.c
deleted file mode 100644
index 19db0872..00000000
--- a/m4/builtin.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 1999-2000, 2005-2008, 2010, 2013-2014, 2017
- Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Code for all builtin macros, initialisation of symbol table, and
- expansion of user defined macros. */
-
-#include <config.h>
-
-#include "m4private.h"
-
-/* Comparison function, for use in bsearch, which compares NAME
- against the name of BUILTIN. */
-static int
-compare_builtin_name_CB (const void *name, const void *b)
-{
- const m4__builtin *builtin = (const m4__builtin *) b;
- return strcmp ((const char *) name, builtin->builtin.name);
-}
-
-/* Find the builtin which has NAME. If MODULE is not NULL, then
- search only in MODULE's builtin table. The result is a malloc'd
- symbol value, suitable for use in the symbol table or for an
- argument to m4_push_builtin. */
-m4_symbol_value * M4_GNUC_PURE
-m4_builtin_find_by_name (m4 *context, m4_module *module, const char *name)
-{
- m4_module *cur = module ? module : m4_module_next (context, NULL);
- m4__builtin *bp;
-
- do
- {
- bp = (m4__builtin *) bsearch (name, cur->builtins, cur->builtins_len,
- sizeof *bp, compare_builtin_name_CB);
- if (bp)
- {
- m4_symbol_value *token = (m4_symbol_value *) xzalloc (sizeof *token);
- m4__set_symbol_value_builtin (token, bp);
- return token;
- }
- }
- while (!module && (cur = m4_module_next (context, cur)));
-
- return NULL;
-}
-
-/* Find the builtin which has FUNC. If MODULE argument is supplied
- then search only in MODULE's builtin table. The result is a
- malloc'd symbol value, suitable for use in the symbol table or for
- an argument to m4_push_builtin. */
-m4_symbol_value * M4_GNUC_PURE
-m4_builtin_find_by_func (m4 *context, m4_module *module, m4_builtin_func *func)
-{
- m4_module *cur = module ? module : m4_module_next (context, NULL);
- size_t i;
-
- do
- {
- for (i = 0; i < cur->builtins_len; i++)
- if (cur->builtins[i].builtin.func == func)
- {
- m4_symbol_value *token =
- (m4_symbol_value *) xzalloc (sizeof *token);
- m4__set_symbol_value_builtin (token, &cur->builtins[i]);
- return token;
- }
- }
- while (!module && (cur = m4_module_next (context, cur)));
-
- return 0;
-}
-
-/* Print a representation of FUNC to OBS, optionally including the
- MODULE it came from. If FLATTEN, output QUOTES around an empty
- string; if CHAIN, append the builtin to the chain; otherwise print
- the name of FUNC. */
-void
-m4__builtin_print (m4_obstack *obs, const m4__builtin *func, bool flatten,
- m4__symbol_chain **chain, const m4_string_pair *quotes,
- bool module)
-{
- assert (func);
- if (flatten)
- {
- if (quotes)
- {
- obstack_grow (obs, quotes->str1, quotes->len1);
- obstack_grow (obs, quotes->str2, quotes->len2);
- }
- module = false;
- }
- else if (chain)
- m4__append_builtin (obs, func, NULL, chain);
- else
- {
- obstack_1grow (obs, '<');
- obstack_grow (obs, func->builtin.name, strlen (func->builtin.name));
- obstack_1grow (obs, '>');
- }
- if (module)
- {
- const char *text = m4_get_module_name (func->module);
- obstack_1grow (obs, '{');
- obstack_grow (obs, text, strlen (text));
- obstack_1grow (obs, '}');
- }
-}
diff --git a/m4/debug.c b/m4/debug.c
deleted file mode 100644
index eb0e32fd..00000000
--- a/m4/debug.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1991-1994, 2006-2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include <sys/stat.h>
-#include <stdarg.h>
-
-#include "m4private.h"
-#include "close-stream.h"
-
-static void set_debug_file (m4 *, const m4_call_info *, FILE *);
-
-
-
-/* Function to decode the debugging flags OPTS of length LEN; or
- SIZE_MAX if OPTS is NUL-terminated. If OPTS is NULL, use the
- default flags. Used by main while processing option -d, and by the
- builtin debugmode (). */
-int
-m4_debug_decode (m4 *context, const char *opts, size_t len)
-{
- int previous = context->debug_level;
- int level;
- char mode = '\0';
-
- if (!opts)
- opts = "";
- if (len == SIZE_MAX)
- len = strlen (opts);
- if (!len)
- level = M4_DEBUG_TRACE_DEFAULT | previous;
- else
- {
- if (*opts == '-' || *opts == '+')
- {
- len--;
- mode = *opts++;
- }
- for (level = 0; len--; opts++)
- {
- switch (*opts)
- {
- case 'a':
- level |= M4_DEBUG_TRACE_ARGS;
- break;
-
- case 'e':
- level |= M4_DEBUG_TRACE_EXPANSION;
- break;
-
- case 'q':
- level |= M4_DEBUG_TRACE_QUOTE;
- break;
-
- case 't':
- level |= M4_DEBUG_TRACE_ALL;
- break;
-
- case 'l':
- level |= M4_DEBUG_TRACE_LINE;
- break;
-
- case 'f':
- level |= M4_DEBUG_TRACE_FILE;
- break;
-
- case 'p':
- level |= M4_DEBUG_TRACE_PATH;
- break;
-
- case 'c':
- level |= M4_DEBUG_TRACE_CALL;
- break;
-
- case 'i':
- level |= M4_DEBUG_TRACE_INPUT;
- break;
-
- case 'x':
- level |= M4_DEBUG_TRACE_CALLID;
- break;
-
- case 'm':
- level |= M4_DEBUG_TRACE_MODULE;
- break;
-
- case 's':
- level |= M4_DEBUG_TRACE_STACK;
- break;
-
- case 'd':
- level |= M4_DEBUG_TRACE_DEREF;
- break;
-
- case 'o':
- level |= M4_DEBUG_TRACE_OUTPUT_DUMPDEF;
- break;
-
- case 'V':
- level |= M4_DEBUG_TRACE_VERBOSE;
- break;
-
- default:
- return -1;
- }
- }
- }
-
- switch (mode)
- {
- case '\0':
- /* Replace old level. */
- break;
-
- case '-':
- /* Subtract flags. */
- level = previous & ~level;
- break;
-
- case '+':
- /* Add flags. */
- level |= previous;
- break;
-
- default:
- assert (!"m4_debug_decode");
- }
- context->debug_level = level;
- return level;
-}
-
-/* Change the debug output stream to FP. If the underlying file is the
- same as stdout, use stdout instead so that debug messages appear in the
- correct relative position. Report errors on behalf of CALLER. */
-static void
-set_debug_file (m4 *context, const m4_call_info *caller, FILE *fp)
-{
- FILE *debug_file;
- struct stat stdout_stat, debug_stat;
-
- assert (context);
-
- debug_file = m4_get_debug_file (context);
- if (debug_file != NULL && debug_file != stderr && debug_file != stdout
- && close_stream (debug_file) != 0)
- m4_error (context, 0, errno, caller, _("error writing to debug stream"));
-
- debug_file = fp;
- m4_set_debug_file (context, fp);
-
- if (debug_file != NULL && debug_file != stdout)
- {
- if (fstat (fileno (stdout), &stdout_stat) < 0)
- return;
- if (fstat (fileno (debug_file), &debug_stat) < 0)
- return;
-
- /* mingw has a bug where fstat on a regular file reports st_ino
- of 0. On normal system, st_ino should never be 0. */
- if (stdout_stat.st_ino == debug_stat.st_ino
- && stdout_stat.st_dev == debug_stat.st_dev
- && stdout_stat.st_ino != 0)
- {
- if (debug_file != stderr && close_stream (debug_file) != 0)
- m4_error (context, 0, errno, caller,
- _("error writing to debug stream"));
- m4_set_debug_file (context, stdout);
- }
- }
-}
-
-/* Change the debug output to file NAME. If NAME is NULL, debug
- output is reverted to stderr, and if empty debug output is
- discarded. Return true iff the output stream was changed. Report
- errors on behalf of CALLER. */
-bool
-m4_debug_set_output (m4 *context, const m4_call_info *caller, const char *name)
-{
- FILE *fp;
-
- assert (context);
-
- if (name == NULL)
- set_debug_file (context, caller, stderr);
- else if (*name == '\0')
- set_debug_file (context, caller, NULL);
- else
- {
- fp = fopen (name, "a");
- if (fp == NULL)
- return false;
-
- if (set_cloexec_flag (fileno (fp), true) != 0)
- m4_warn (context, errno, caller,
- _("cannot protect debug file across forks"));
- set_debug_file (context, caller, fp);
- }
- return true;
-}
-
-/* Print the header of a one-line debug message, starting with "m4debug:". */
-void
-m4_debug_message_prefix (m4 *context)
-{
- FILE *debug_file;
-
- assert (context);
-
- debug_file = m4_get_debug_file (context);
- fputs ("m4debug:", debug_file);
- if (m4_get_current_line (context))
- {
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_FILE))
- xfprintf (debug_file, "%s:", m4_get_current_file (context));
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_LINE))
- xfprintf (debug_file, "%d:", m4_get_current_line (context));
- }
- putc (' ', debug_file);
-}
-
-/* If the current debug mode includes MODE, and there is a current
- debug file, then output a debug message described by FORMAT. A
- message header is supplied, as well as a trailing newline. */
-void
-m4_debug_message (m4 *context, int mode, const char *format, ...)
-{
- /* Check that mode has exactly one bit set. */
- assert (mode && (mode & (mode - 1)) == 0);
- assert (format);
-
- if (m4_get_debug_file (context) != NULL
- && m4_is_debug_bit (context, mode))
- {
- va_list args;
-
- m4_debug_message_prefix (context);
- va_start (args, format);
- xvfprintf (m4_get_debug_file (context), format, args);
- va_end (args);
- putc ('\n', m4_get_debug_file (context));
- }
-}
diff --git a/m4/hash.c b/m4/hash.c
deleted file mode 100644
index 01b90648..00000000
--- a/m4/hash.c
+++ /dev/null
@@ -1,671 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2001, 2006-2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
- Written by Gary V. Vaughan <gary@gnu.org>
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* TODO:
- - Use an obstack to manage the node memory.
- - Implement the macroized magic values with the API.
- */
-
-#include <config.h>
-
-#include "hash.h"
-#include "m4private.h"
-
-#include "bitrotate.h"
-#include <limits.h>
-
-typedef struct hash_node hash_node;
-
-struct m4_hash
-{
- size_t size; /* number of buckets allocated */
- size_t length; /* number of elements inserted */
- m4_hash_hash_func *hash_func;
- m4_hash_cmp_func *cmp_func;
- hash_node **buckets;
-#ifndef NDEBUG
- m4_hash_iterator *iter; /* current iterator */
-#endif
-};
-
-struct hash_node
-{
- hash_node *next;
- const void *key;
- void *value;
-};
-
-
-struct m4_hash_iterator
-{
- const m4_hash *hash; /* contains the buckets */
- hash_node * place; /* the node we are about to return */
- hash_node * next; /* the next node, incase PLACE is removed */
- size_t next_bucket; /* the next bucket index following NEXT */
-#ifndef NDEBUG
- m4_hash_iterator *chain; /* multiple iterators visiting one hash */
-#endif
-};
-
-
-#define HASH_SIZE(hash) ((hash)->size)
-#define HASH_LENGTH(hash) ((hash)->length)
-#define HASH_BUCKETS(hash) ((hash)->buckets)
-#define HASH_HASH_FUNC(hash) ((hash)->hash_func)
-#define HASH_CMP_FUNC(hash) ((hash)->cmp_func)
-
-#define NODE_NEXT(node) ((node)->next)
-#define NODE_KEY(node) ((node)->key)
-#define NODE_VALUE(node) ((node)->value)
-
-#define ITERATOR_HASH(i) ((i)->hash)
-#define ITERATOR_PLACE(i) ((i)->place)
-#define ITERATOR_NEXT(i) ((i)->next)
-#define ITERATOR_NEXT_BUCKET(i) ((i)->next_bucket)
-
-/*#define ITERATOR_NEXT_NEXT(i) NODE_NEXT (ITERATOR_PLACE (i))*/
-
-/* Helper macros. */
-#define BUCKET_NTH(hash, n) (HASH_BUCKETS (hash)[n])
-#define BUCKET_COUNT(hash, key) \
- ((*HASH_HASH_FUNC (hash))(key) % HASH_SIZE (hash))
-#define BUCKET_KEY(hash, key) \
- (BUCKET_NTH ((hash), BUCKET_COUNT ((hash), (key))))
-
-/* Debugging macros. */
-#ifdef NDEBUG
-# define HASH_ITER(hash) 0
-# define ITER_CHAIN(iter) 0
-#else
-# define HASH_ITER(hash) (((m4_hash *) hash)->iter)
-# define ITER_CHAIN(iter) ((iter)->chain)
-#endif
-
-
-static void bucket_insert (m4_hash *hash, hash_node *bucket);
-static void bucket_delete (m4_hash *hash, size_t i);
-static hash_node * node_new (const void *key, void *value);
-static void node_insert (m4_hash *hash, hash_node *node);
-static hash_node * node_lookup (m4_hash *hash, const void *key);
-static void node_delete (m4_hash *hash, hash_node *node);
-static void maybe_grow (m4_hash *hash);
-
-
-
-static hash_node *free_list = NULL;
-
-
-
-/* Allocate and return a new, unpopulated but initialised m4_hash with
- SIZE buckets, where HASH_FUNC will be used to generate bucket numbers
- and CMP_FUNC will be called to compare keys. */
-m4_hash *
-m4_hash_new (size_t size, m4_hash_hash_func *hash_func,
- m4_hash_cmp_func *cmp_func)
-{
- m4_hash *hash;
-
- assert (hash_func);
- assert (cmp_func);
-
- if (size == 0)
- size = M4_HASH_DEFAULT_SIZE;
-
- hash = (m4_hash *) xmalloc (sizeof *hash);
- HASH_SIZE (hash) = size;
- HASH_LENGTH (hash) = 0;
- HASH_BUCKETS (hash) = (hash_node **) xcalloc (size,
- sizeof *HASH_BUCKETS (hash));
- HASH_HASH_FUNC (hash) = hash_func;
- HASH_CMP_FUNC (hash) = cmp_func;
-#ifndef NDEBUG
- HASH_ITER (hash) = NULL;
-#endif
-
- return hash;
-}
-
-m4_hash *
-m4_hash_dup (m4_hash *src, m4_hash_copy_func *copy)
-{
- m4_hash *dest;
-
- assert (src);
- assert (copy);
-
- dest = m4_hash_new (HASH_SIZE (src), HASH_HASH_FUNC (src),
- HASH_CMP_FUNC (src));
-
- m4_hash_apply (src, (m4_hash_apply_func *) copy, dest);
-
- return dest;
-}
-
-/* Recycle each of the nodes in HASH onto the free list, and release
- the rest of the memory used by the table. Memory addressed by the
- recycled nodes is _NOT_ freed: this needs to be done manually to
- prevent memory leaks. This is not safe to call while HASH is being
- iterated. */
-void
-m4_hash_delete (m4_hash *hash)
-{
- size_t i;
-
- assert (hash);
- assert (!HASH_ITER (hash));
-
- for (i = 0; i < HASH_SIZE (hash); ++i)
- if (BUCKET_NTH (hash, i))
- bucket_delete (hash, i);
- free (HASH_BUCKETS (hash));
- free (hash);
-}
-
-/* Check that the nodes in bucket I have been cleared, and recycle
- each of the nodes in the bucket to the free list. Bucket I must
- not be empty when this function is called. */
-static void
-bucket_delete (m4_hash *hash, size_t i)
-{
- hash_node *node;
-
- assert (hash);
- assert (BUCKET_NTH (hash, i));
- assert (i < HASH_SIZE (hash));
-
- for (node = BUCKET_NTH (hash, i); node->next; node = NODE_NEXT (node))
- {
- assert (NODE_KEY (node) == NULL);
- --HASH_LENGTH (hash);
- }
-
- assert (NODE_KEY (node) == NULL);
- --HASH_LENGTH (hash);
-
- NODE_NEXT (node) = free_list;
- free_list = BUCKET_NTH (hash, i);
- BUCKET_NTH (hash, i) = NULL;
-}
-
-/* Create and initialise a new node with KEY and VALUE, by reusing a
- node from the free list if possible. */
-static hash_node *
-node_new (const void *key, void *value)
-{
- hash_node *node = NULL;
-
- if (free_list)
- {
- node = free_list;
- free_list = NODE_NEXT (free_list);
- }
- else
- node = (hash_node *) xmalloc (sizeof *node);
-
- assert (node);
-
- NODE_NEXT (node) = NULL;
- NODE_KEY (node) = key;
- NODE_VALUE (node) = value;
-
- return node;
-}
-
-/* Check that NODE has been cleared, and recycle it to the free list. */
-static void
-node_delete (m4_hash *hash, hash_node *node)
-{
- assert (node);
- assert (NODE_KEY (node) == NULL);
-
- NODE_NEXT (node) = free_list;
- free_list = node;
-
- --HASH_LENGTH (hash);
-}
-
-/* Create a new entry in HASH with KEY and VALUE, making use of nodes
- in the free list if possible, and potentially growing the size of
- the table if node density is too high. This is not safe to call
- while HASH is being iterated. Currently, it is not safe to call
- this if another entry already matches KEY. */
-const void *
-m4_hash_insert (m4_hash *hash, const void *key, void *value)
-{
- hash_node *node;
-
- assert (hash);
- assert (!HASH_ITER (hash));
-
- node = node_new (key, value);
- node_insert (hash, node);
- maybe_grow (hash);
-
- return key;
-}
-
-/* Push the unconnected NODE on to the front of the appropriate
- bucket, effectively preventing retrieval of other nodes with
- the same key (where "sameness" is determined by HASH's
- cmp_func). */
-static void
-node_insert (m4_hash *hash, hash_node *node)
-{
- size_t n;
-
- assert (hash);
- assert (node);
- assert (NODE_NEXT (node) == NULL);
-
- n = BUCKET_COUNT (hash, NODE_KEY (node));
- NODE_NEXT (node) = BUCKET_NTH (hash, n);
- BUCKET_NTH (hash, n) = node;
-
- ++HASH_LENGTH (hash);
-}
-
-/* Remove from HASH, the first node with key KEY; comparing keys with
- HASH's cmp_func. Any nodes with the same KEY previously hidden by
- the removed node will become visible again. The key field of the
- removed node is returned, or NULL if there was no match. This is
- unsafe if multiple iterators are visiting HASH, or when a lone
- iterator is visiting on a different key. */
-void *
-m4_hash_remove (m4_hash *hash, const void *key)
-{
- size_t n;
- hash_node *node = NULL;
-
-#ifndef NDEBUG
- m4_hash_iterator *iter = HASH_ITER (hash);
-
- assert (hash);
- if (HASH_ITER (hash))
- {
- assert (!ITER_CHAIN (iter));
- assert (ITERATOR_PLACE (iter));
- }
-#endif
-
- n = BUCKET_COUNT (hash, key);
- do
- {
- hash_node *next = node ? NODE_NEXT (node) : BUCKET_NTH (hash, n);
-
- if (next && ((*HASH_CMP_FUNC (hash)) (NODE_KEY (next), key) == 0))
- {
- if (node)
- NODE_NEXT (node) = NODE_NEXT (next);
- else
- BUCKET_NTH (hash, n) = NODE_NEXT (next);
-
- key = NODE_KEY (next);
-#ifndef NDEBUG
- if (iter)
- assert (ITERATOR_PLACE (iter) == next);
- NODE_KEY (next) = NULL;
-#endif
- node_delete (hash, next);
- return (void *) key; /* Cast away const. */
- }
- node = next;
- }
- while (node);
-
- return NULL;
-}
-
-/* Return the address of the value field of the first node in HASH
- that has a matching KEY. The address is returned so that an
- explicit NULL value can be distinguished from a failed lookup (also
- NULL). Fortuitously for M4, this also means that the value field
- can be changed `in situ' to implement a value stack. Safe to call
- even when an iterator is in force. */
-void **
-m4_hash_lookup (m4_hash *hash, const void *key)
-{
- hash_node *node;
-
- assert (hash);
-
- node = node_lookup (hash, key);
-
- return node ? &NODE_VALUE (node) : NULL;
-}
-
-/* Return the first node in HASH that has a matching KEY. */
-static hash_node *
-node_lookup (m4_hash *hash, const void *key)
-{
- hash_node *node;
-
- assert (hash);
-
- node = BUCKET_KEY (hash, key);
-
- while (node && (*HASH_CMP_FUNC (hash)) (NODE_KEY (node), key))
- node = NODE_NEXT (node);
-
- return node;
-}
-
-/* How many entries are currently contained by HASH. Safe to call
- even during an interation. */
-size_t M4_GNUC_PURE
-m4_get_hash_length (m4_hash *hash)
-{
- assert (hash);
-
- return HASH_LENGTH (hash);
-}
-
-#if 0
-/* Force the number of buckets to be the given value. You probably ought
- not to be using this function once the table has been in use, since
- the maximum density algorithm will grow the number of buckets back to
- what was there before if you try to shrink the table. It is useful
- to set a smaller or larger initial size if you know in advance what
- order of magnitude of entries will be in the table. Be aware that
- the efficiency of the lookup and grow features require that the size
- always be 1 less than a power of 2. Unsafe if HASH is being visited
- by an iterator. */
-void
-m4_hash_resize (m4_hash *hash, size_t size)
-{
- hash_node **original_buckets;
- size_t original_size;
-
- assert (hash);
- assert (!HASH_ITER (hash));
-
- original_size = HASH_SIZE (hash);
- original_buckets = HASH_BUCKETS (hash);
-
- HASH_SIZE (hash) = size;
- HASH_BUCKETS (hash) = (hash_node **) xcalloc (size,
- sizeof *HASH_BUCKETS (hash));
-
- {
- size_t i;
- for (i = 0; i < original_size; ++i)
- if (original_buckets[i])
- bucket_insert (hash, original_buckets[i]);
- }
-
- free (original_buckets);
-}
-#endif
-
-/* If the node density breaks the threshold, increase the size of
- HASH and repopulate with the original nodes. */
-static void
-maybe_grow (m4_hash *hash)
-{
- float nodes_per_bucket;
-
- assert (hash);
-
- nodes_per_bucket = (float) HASH_LENGTH (hash) / (float) HASH_SIZE (hash);
-
- if (nodes_per_bucket > (float) M4_HASH_MAXIMUM_DENSITY)
- {
- size_t original_size = HASH_SIZE (hash);
- hash_node **original_buckets = HASH_BUCKETS (hash);
-
- /* HASH sizes are always 1 less than a power of 2. */
- HASH_SIZE (hash) = (2 * (1 + original_size)) -1;
- HASH_BUCKETS (hash) =
- (hash_node **) xcalloc (HASH_SIZE (hash), sizeof *HASH_BUCKETS (hash));
-
- {
- size_t i;
- for (i = 0; i < original_size; ++i)
- if (original_buckets[i])
- bucket_insert (hash, original_buckets[i]);
- }
-
- free (original_buckets);
- }
-}
-
-/* Insert each node in BUCKET into HASH. Relative ordering of nodes
- is not preserved. This would need to change if we were to
- guarantee relative ordering within a bucket for identical keys. */
-static void
-bucket_insert (m4_hash *hash, hash_node *bucket)
-{
- assert (hash);
- assert (bucket);
-
- do
- {
- hash_node *next = NODE_NEXT (bucket);
-
- /* Break link to rest of the bucket before reinserting. */
- NODE_NEXT (bucket) = NULL;
- node_insert (hash, bucket);
-
- bucket = next;
- }
- while (bucket);
-}
-
-/* Reclaim all memory used by free nodes. Safe to call at any time,
- although only worth calling at program shutdown to verify no
- leaks. */
-void
-m4_hash_exit (void)
-{
- while (free_list)
- {
- hash_node *stale = free_list;
- free_list = NODE_NEXT (stale);
- free (stale);
- }
-}
-
-
-
-/* Iterate over a given HASH. Start with PLACE being NULL, then
- repeat with PLACE being the previous return value. The return
- value is the current location of the iterator, or NULL when the
- walk is complete. Call m4_free_hash_iterator to abort iteration.
- During the iteration, it is safe to search the list, and if no
- other iterator is active, it is safe to remove the key pointed to
- by this iterator. All other actions that modify HASH are
- unsafe. */
-m4_hash_iterator *
-m4_get_hash_iterator_next (const m4_hash *hash, m4_hash_iterator *place)
-{
- assert (hash);
- assert (!place || (ITERATOR_HASH (place) == hash));
-
- /* On the first iteration, allocate an iterator. */
- if (!place)
- {
- place = (m4_hash_iterator *) xzalloc (sizeof *place);
- ITERATOR_HASH (place) = hash;
-#ifndef NDEBUG
- ITER_CHAIN (place) = HASH_ITER (hash);
- HASH_ITER (hash) = place;
-#endif
- }
-
- next:
- ITERATOR_PLACE (place) = ITERATOR_NEXT (place);
-
- /* If there is another node in the current bucket, select it. */
- if (ITERATOR_NEXT (place) && NODE_NEXT (ITERATOR_NEXT (place)))
- {
- ITERATOR_NEXT (place) = NODE_NEXT (ITERATOR_NEXT (place));
- }
- else
- {
- /* Find the next non-empty bucket. */
- while ((ITERATOR_NEXT_BUCKET (place) < HASH_SIZE (hash))
- && (BUCKET_NTH (hash, ITERATOR_NEXT_BUCKET (place)) == NULL))
- {
- ++ITERATOR_NEXT_BUCKET (place);
- }
-
- /* Select the first node in the new bucket. */
- if (ITERATOR_NEXT_BUCKET (place) < HASH_SIZE (hash))
- {
- ITERATOR_NEXT (place)
- = BUCKET_NTH (hash, ITERATOR_NEXT_BUCKET (place));
- }
- else
- ITERATOR_NEXT (place) = NULL;
-
- /* Advance the `next' reference. */
- ++ITERATOR_NEXT_BUCKET (place);
- }
-
- /* If there are no more nodes to return, recycle the iterator memory. */
- if (! (ITERATOR_PLACE (place) || ITERATOR_NEXT (place)))
- {
- m4_free_hash_iterator (hash, place);
- return NULL;
- }
-
- /* On the first call we need to put the 1st node in PLACE and
- the 2nd node in NEXT. */
- if (ITERATOR_NEXT (place) && !ITERATOR_PLACE (place))
- goto next;
-
- assert (place && ITERATOR_PLACE (place));
-
- return place;
-}
-
-/* Clean up the iterator PLACE within HASH when aborting an iteration
- early. */
-void
-m4_free_hash_iterator (const m4_hash *hash, m4_hash_iterator *place)
-{
-#ifndef NDEBUG
- m4_hash_iterator *iter = NULL;
- m4_hash_iterator *next;
-
- assert (hash);
- assert (place && (ITERATOR_HASH (place) == hash));
-
- do
- {
- next = iter ? ITER_CHAIN (iter) : HASH_ITER (hash);
- if (place == next)
- {
- if (iter)
- ITER_CHAIN (iter) = ITER_CHAIN (next);
- else
- HASH_ITER (hash) = ITER_CHAIN (next);
- break;
- }
- iter = next;
- }
- while (iter);
- assert (next);
-#endif
- free (place);
-}
-
-/* Return the key being visited by the iterator PLACE. */
-const void * M4_GNUC_PURE
-m4_get_hash_iterator_key (m4_hash_iterator *place)
-{
- assert (place);
-
- return NODE_KEY (ITERATOR_PLACE (place));
-}
-
-/* Return the value being visited by the iterator PLACE. */
-void * M4_GNUC_PURE
-m4_get_hash_iterator_value (m4_hash_iterator *place)
-{
- assert (place);
-
- return NODE_VALUE (ITERATOR_PLACE (place));
-}
-
-/* The following function is used for the cases where we want to do
- something to each and every entry in HASH. This function traverses
- the hash table, and calls a specified function FUNC for each entry
- in the table. FUNC is called with a pointer to the entry key,
- value, and the passed DATA argument. If FUNC returns non-NULL,
- abort the iteration and return that value; a return of NULL implies
- success on all entries. */
-void *
-m4_hash_apply (m4_hash *hash, m4_hash_apply_func *func, void *userdata)
-{
- m4_hash_iterator *place = NULL;
- void * result = NULL;
-
- assert (hash);
- assert (func);
-
- while ((place = m4_get_hash_iterator_next (hash, place)))
- {
- result = (*func) (hash, m4_get_hash_iterator_key (place),
- m4_get_hash_iterator_value (place), userdata);
-
- if (result != NULL)
- {
- m4_free_hash_iterator (hash, place);
- break;
- }
- }
-
- return result;
-}
-
-
-/* Using a string (char * and size_t pair) as the hash key is common
- enough that we provide implementations here for use in client hash
- table routines. */
-
-/* Return a hash value for a string, similar to gnulib's hash module,
- but with length factored in. */
-size_t M4_GNUC_PURE
-m4_hash_string_hash (const void *ptr)
-{
- const m4_string *key = (const m4_string *) ptr;
- const char *s = key->str;
- size_t len = key->len;
- size_t val = len;
-
- while (len--)
- val = rotl_sz (val, 7) + to_uchar (*s++);
- return val;
-}
-
-/* Comparison function for hash keys -- used by the underlying
- hash table ADT when searching for a key match during name lookup. */
-int M4_GNUC_PURE
-m4_hash_string_cmp (const void *key, const void *try)
-{
- const m4_string *a = (const m4_string *) key;
- const m4_string *b = (const m4_string *) try;
- if (a->len < b->len)
- return -1;
- if (b->len < a->len)
- return 1;
- return memcmp (a->str, b->str, a->len);
-}
diff --git a/m4/hash.h b/m4/hash.h
deleted file mode 100644
index 46f0eeeb..00000000
--- a/m4/hash.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2001, 2006-2007, 2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
- Written by Gary V. Vaughan <gary@gnu.org>
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef M4_HASH_H
-#define M4_HASH_H 1
-
-#include <m4/system.h>
-
-/* Must be 1 less than a power of 2 for the resize algorithm to
- be efficient. */
-#define M4_HASH_DEFAULT_SIZE 511
-
-/* When the average number of values per bucket breaks this value
- the table will be grown to reduce the density accordingly. */
-#define M4_HASH_MAXIMUM_DENSITY 3.0
-
-BEGIN_C_DECLS
-
-typedef struct m4_hash m4_hash;
-
-typedef size_t m4_hash_hash_func (const void *key);
-typedef int m4_hash_cmp_func (const void *key, const void *try);
-typedef void * m4_hash_copy_func (m4_hash *src, const void *key, void *value,
- m4_hash *dest);
-
-extern m4_hash *m4_hash_new (size_t size, m4_hash_hash_func *hash_func,
- m4_hash_cmp_func *cmp_func);
-extern m4_hash *m4_hash_dup (m4_hash *hash, m4_hash_copy_func *copy);
-extern void m4_hash_delete (m4_hash *hash);
-extern void m4_hash_exit (void);
-
-extern size_t m4_get_hash_length (m4_hash *hash);
-
-extern void ** m4_hash_lookup (m4_hash *hash, const void *key);
-extern void * m4_hash_remove (m4_hash *hash, const void *key);
-extern const void * m4_hash_insert (m4_hash *hash, const void *key,
- void *value);
-
-
-
-extern size_t m4_hash_string_hash (const void *key);
-extern int m4_hash_string_cmp (const void *key, const void *try);
-
-
-
-typedef struct m4_hash_iterator m4_hash_iterator;
-typedef void * m4_hash_apply_func (m4_hash *hash, const void *key,
- void *value, void *userdata);
-
-extern void * m4_hash_apply (m4_hash *hash, m4_hash_apply_func *func,
- void *userdata);
-
-extern const void * m4_get_hash_iterator_key (m4_hash_iterator *place);
-extern void * m4_get_hash_iterator_value (m4_hash_iterator *place);
-extern m4_hash_iterator *m4_get_hash_iterator_next (const m4_hash *hash,
- m4_hash_iterator *place);
-extern void m4_free_hash_iterator (const m4_hash *hash,
- m4_hash_iterator *place);
-
-
-END_C_DECLS
-
-#endif /* !M4_HASH_H */
diff --git a/m4/input.c b/m4/input.c
deleted file mode 100644
index edce12e4..00000000
--- a/m4/input.c
+++ /dev/null
@@ -1,2223 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2006-2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Handling of different input sources, and lexical analysis. */
-
-#include <config.h>
-
-#include "m4private.h"
-
-#include "freadptr.h"
-#include "freadseek.h"
-#include "memchr2.h"
-
-/* Define this to see runtime debug info. Implied by DEBUG. */
-/*#define DEBUG_INPUT */
-
-/* Maximum number of bytes where it is more efficient to inline the
- reference as a string than it is to track reference bookkeeping for
- those bytes. */
-#define INPUT_INLINE_THRESHOLD 16
-
-/*
- Unread input can be either files that should be read (from the
- command line or by include/sinclude), strings which should be
- rescanned (normal macro expansion text), or quoted builtin
- definitions (as returned by the builtin "defn"). Unread input is
- organized in a stack, implemented with an obstack. Each input
- source is described by a "struct m4_input_block". The obstack is
- "input_stack". The top of the input stack is "isp".
-
- Each input_block has an associated struct input_funcs, which is a
- vtable that defines polymorphic functions for peeking, reading,
- unget, cleanup, and printing in trace output. Getting a single
- character at a time is inefficient, so there are also functions for
- accessing the readahead buffer and consuming bulk input. All input
- is done through the function pointers of the input_funcs on the
- given input_block, and all characters are unsigned, to distinguish
- between stdio EOF and between special sentinel characters. When a
- input_block is exhausted, its reader returns CHAR_RETRY which
- causes the input_block to be popped from the input_stack.
-
- The macro "m4wrap" places the text to be saved on another input
- stack, on the obstack "wrapup_stack", whose top is "wsp". When EOF
- is seen on normal input (eg, when "current_input" is empty), input
- is switched over to "wrapup_stack", and the original
- "current_input" is freed. A new stack is allocated for
- "wrapup_stack", which will accept any text produced by calls to
- "m4wrap" from within the wrapped text. This process of shuffling
- "wrapup_stack" to "current_input" can continue indefinitely, even
- generating infinite loops (e.g. "define(`f',`m4wrap(`f')')f"),
- without memory leaks. Adding wrapped data is done through
- m4__push_wrapup_init/m4__push_wrapup_finish().
-
- Pushing new input on the input stack is done by m4_push_file(), the
- conceptual m4_push_string(), and m4_push_builtin() (for builtin
- definitions). As an optimization, since most macro expansions
- result in strings, m4_push_string() is split in two parts,
- push_string_init(), which returns a pointer to the obstack for
- growing the output, and push_string_finish(), which returns a
- pointer to the finished input_block. Thus, instead of creating a
- new input block for every character pushed, macro expansion need
- only add text to the top of the obstack. However, it is not safe
- to alter the input stack while a string is being constructed. This
- means the input engine is one of two states: consuming input, or
- collecting a macro's expansion. The input_block *next is used to
- manage the coordination between the different push routines.
-
- Normally, input sources behave in LIFO order, resembling a stack.
- But thanks to the defn and m4wrap macros, when collecting the
- expansion of a macro, it is possible that we must intermix multiple
- input blocks in FIFO order. Therefore, when collecting an
- expansion, a meta-input block is formed which will visit its
- children in FIFO order, without losing data when the obstack is
- cleared in LIFO order.
-
- The current file and line number are stored in the context, for use
- by the error handling functions in utility.c. When collecting a
- macro's expansion, these variables can be temporarily inconsistent
- in order to provide better error message locations, but they must
- be restored before further parsing takes place. Each input block
- maintains its own notion of the current file and line, so swapping
- between input blocks must update the context accordingly. */
-
-typedef struct m4_input_block m4_input_block;
-
-static int file_peek (m4_input_block *, m4 *, bool);
-static int file_read (m4_input_block *, m4 *, bool, bool,
- bool);
-static void file_unget (m4_input_block *, int);
-static bool file_clean (m4_input_block *, m4 *, bool);
-static void file_print (m4_input_block *, m4 *, m4_obstack *,
- int);
-static const char * file_buffer (m4_input_block *, m4 *, size_t *,
- bool);
-static void file_consume (m4_input_block *, m4 *, size_t);
-static int string_peek (m4_input_block *, m4 *, bool);
-static int string_read (m4_input_block *, m4 *, bool, bool,
- bool);
-static void string_unget (m4_input_block *, int);
-static void string_print (m4_input_block *, m4 *, m4_obstack *,
- int);
-static const char * string_buffer (m4_input_block *, m4 *, size_t *,
- bool);
-static void string_consume (m4_input_block *, m4 *, size_t);
-static int composite_peek (m4_input_block *, m4 *, bool);
-static int composite_read (m4_input_block *, m4 *, bool, bool,
- bool);
-static void composite_unget (m4_input_block *, int);
-static bool composite_clean (m4_input_block *, m4 *, bool);
-static void composite_print (m4_input_block *, m4 *, m4_obstack *,
- int);
-static const char * composite_buffer (m4_input_block *, m4 *, size_t *,
- bool);
-static void composite_consume (m4_input_block *, m4 *, size_t);
-static int eof_peek (m4_input_block *, m4 *, bool);
-static int eof_read (m4_input_block *, m4 *, bool, bool,
- bool);
-static void eof_unget (m4_input_block *, int);
-static const char * eof_buffer (m4_input_block *, m4 *, size_t *,
- bool);
-
-static void init_builtin_token (m4 *, m4_obstack *,
- m4_symbol_value *);
-static void append_quote_token (m4 *, m4_obstack *,
- m4_symbol_value *);
-static bool match_input (m4 *, const char *, size_t, bool);
-static int next_char (m4 *, bool, bool, bool);
-static int peek_char (m4 *, bool);
-static bool pop_input (m4 *, bool);
-static void unget_input (int);
-static const char * next_buffer (m4 *, size_t *, bool);
-static void consume_buffer (m4 *, size_t);
-static bool consume_syntax (m4 *, m4_obstack *, unsigned int);
-
-#ifdef DEBUG_INPUT
-# include "quotearg.h"
-
-static int m4_print_token (m4 *, const char *, m4__token_type,
- m4_symbol_value *);
-#endif
-
-/* Vtable of callbacks for each input method. */
-struct input_funcs
-{
- /* Peek at input, return an unsigned char, CHAR_BUILTIN if it is a
- builtin, or CHAR_RETRY if none available. If ALLOW_ARGV, then
- CHAR_ARGV may be returned. */
- int (*peek_func) (m4_input_block *, m4 *, bool);
-
- /* Read input, return an unsigned char, CHAR_BUILTIN if it is a
- builtin, or CHAR_RETRY if none available. If ALLOW_QUOTE, then
- CHAR_QUOTE may be returned. If ALLOW_ARGV, then CHAR_ARGV may be
- returned. If ALLOW_UNGET, then ensure that the next unget_func
- will work with the returned character. */
- int (*read_func) (m4_input_block *, m4 *, bool allow_quote,
- bool allow_argv, bool allow_unget);
-
- /* Unread a single unsigned character or CHAR_BUILTIN, must be the
- same character previously read by read_func. */
- void (*unget_func) (m4_input_block *, int);
-
- /* Optional function to perform cleanup at end of input. If
- CLEANUP, it is safe to perform non-recoverable cleanup actions.
- Return true only if no cleanup remains to be done. */
- bool (*clean_func) (m4_input_block *, m4 *, bool cleanup);
-
- /* Add a representation of the input block to the obstack, for use
- in trace expansion output. */
- void (*print_func) (m4_input_block *, m4 *, m4_obstack *, int);
-
- /* Return a pointer to the current readahead buffer, and set LEN to
- the length of the result. If ALLOW_QUOTE, do not return a buffer
- for a quoted string. If there is data, but the result of
- next_char() would not fit in a char (for example, CHAR_EOF or
- CHAR_QUOTE) or there is no readahead data available, return NULL,
- and the caller must use next_char(). If there is no more data,
- return buffer_retry. The buffer is only valid until the next
- consume_buffer() or next_char(). */
- const char *(*buffer_func) (m4_input_block *, m4 *, size_t *, bool);
-
- /* Optional function to consume data from a readahead buffer
- previously obtained through buffer_func. */
- void (*consume_func) (m4_input_block *, m4 *, size_t);
-};
-
-/* A block of input to be scanned. */
-struct m4_input_block
-{
- m4_input_block *prev; /* Previous input_block on the input stack. */
- struct input_funcs *funcs; /* Virtual functions of this input_block. */
- const char *file; /* File where this input is from. */
- int line; /* Line where this input is from. */
-
- union
- {
- struct
- {
- char *str; /* String value. */
- size_t len; /* Remaining length. */
- }
- u_s; /* See string_funcs. */
- struct
- {
- FILE *fp; /* Input file handle. */
- bool_bitfield end : 1; /* True iff peek returned EOF. */
- bool_bitfield close : 1; /* True to close file on pop. */
- bool_bitfield line_start : 1; /* Saved start_of_input_line state. */
- }
- u_f; /* See file_funcs. */
- struct
- {
- m4__symbol_chain *chain; /* Current link in chain. */
- m4__symbol_chain *end; /* Last link in chain. */
- }
- u_c; /* See composite_funcs. */
- }
- u;
-};
-
-
-/* Obstack for storing individual tokens. */
-static m4_obstack token_stack;
-
-/* Obstack for storing input file names. */
-static m4_obstack file_names;
-
-/* Wrapup input stack. */
-static m4_obstack *wrapup_stack;
-
-/* Current stack, from input or wrapup. */
-static m4_obstack *current_input;
-
-/* Bottom of token_stack, for obstack_free. */
-static void *token_bottom;
-
-/* Pointer to top of current_input, never NULL. */
-static m4_input_block *isp;
-
-/* Pointer to top of wrapup_stack, never NULL. */
-static m4_input_block *wsp;
-
-/* Auxiliary for handling split m4_push_string (), NULL when not
- pushing text for rescanning. */
-static m4_input_block *next;
-
-/* Flag for next_char () to increment current_line. */
-static bool start_of_input_line;
-
-/* Flag for next_char () to recognize change in input block. */
-static bool input_change;
-
-/* Vtable for handling input from files. */
-static struct input_funcs file_funcs = {
- file_peek, file_read, file_unget, file_clean, file_print, file_buffer,
- file_consume
-};
-
-/* Vtable for handling input from strings. */
-static struct input_funcs string_funcs = {
- string_peek, string_read, string_unget, NULL, string_print, string_buffer,
- string_consume
-};
-
-/* Vtable for handling input from composite chains. */
-static struct input_funcs composite_funcs = {
- composite_peek, composite_read, composite_unget, composite_clean,
- composite_print, composite_buffer, composite_consume
-};
-
-/* Vtable for recognizing end of input. */
-static struct input_funcs eof_funcs = {
- eof_peek, eof_read, eof_unget, NULL, NULL, eof_buffer, NULL
-};
-
-/* Marker at end of an input stack. */
-static m4_input_block input_eof = { NULL, &eof_funcs, "", 0 };
-
-/* Marker for buffer_func when current block has no more data. */
-static const char buffer_retry[1];
-
-
-/* Input files, from command line or [s]include. */
-static int
-file_peek (m4_input_block *me, m4 *context M4_GNUC_UNUSED,
- bool allow_argv M4_GNUC_UNUSED)
-{
- int ch;
-
- ch = me->u.u_f.end ? EOF : getc (me->u.u_f.fp);
- if (ch == EOF)
- {
- me->u.u_f.end = true;
- return CHAR_RETRY;
- }
-
- ungetc (ch, me->u.u_f.fp);
- return ch;
-}
-
-static int
-file_read (m4_input_block *me, m4 *context, bool allow_quote M4_GNUC_UNUSED,
- bool allow_argv M4_GNUC_UNUSED, bool allow_unget M4_GNUC_UNUSED)
-{
- int ch;
-
- if (start_of_input_line)
- {
- start_of_input_line = false;
- m4_set_current_line (context, ++me->line);
- }
-
- /* If stdin is a terminal, calling getc after peek_char already
- called it would make the user have to hit ^D twice to quit. */
- ch = me->u.u_f.end ? EOF : getc (me->u.u_f.fp);
- if (ch == EOF)
- {
- me->u.u_f.end = true;
- return CHAR_RETRY;
- }
-
- if (ch == '\n')
- start_of_input_line = true;
- return ch;
-}
-
-static void
-file_unget (m4_input_block *me, int ch)
-{
- assert (ch < CHAR_EOF);
- if (ungetc (ch, me->u.u_f.fp) < 0)
- {
- assert (!"INTERNAL ERROR: failed ungetc!");
- abort (); /* ungetc should not be called without a previous read. */
- }
- me->u.u_f.end = false;
- if (ch == '\n')
- start_of_input_line = false;
-}
-
-static bool
-file_clean (m4_input_block *me, m4 *context, bool cleanup)
-{
- if (!cleanup)
- return false;
- if (me->prev != &input_eof)
- m4_debug_message (context, M4_DEBUG_TRACE_INPUT,
- _("input reverted to %s, line %d"),
- me->prev->file, me->prev->line);
- else
- m4_debug_message (context, M4_DEBUG_TRACE_INPUT, _("input exhausted"));
-
- if (ferror (me->u.u_f.fp))
- {
- m4_error (context, 0, 0, NULL, _("error reading %s"),
- quotearg_style (locale_quoting_style, me->file));
- if (me->u.u_f.close)
- fclose (me->u.u_f.fp);
- }
- else if (me->u.u_f.close && fclose (me->u.u_f.fp) == EOF)
- m4_error (context, 0, errno, NULL, _("error reading %s"),
- quotearg_style (locale_quoting_style, me->file));
- start_of_input_line = me->u.u_f.line_start;
- m4_set_output_line (context, -1);
- return true;
-}
-
-static void
-file_print (m4_input_block *me, m4 *context M4_GNUC_UNUSED, m4_obstack *obs,
- int debug_level M4_GNUC_UNUSED)
-{
- const char *text = me->file;
- assert (obstack_object_size (current_input) == 0);
- obstack_grow (obs, "<file: ", strlen ("<file: "));
- obstack_grow (obs, text, strlen (text));
- obstack_1grow (obs, '>');
-}
-
-static const char *
-file_buffer (m4_input_block *me, m4 *context M4_GNUC_UNUSED, size_t *len,
- bool allow_quote M4_GNUC_UNUSED)
-{
- if (start_of_input_line)
- {
- start_of_input_line = false;
- m4_set_current_line (context, ++me->line);
- }
- if (me->u.u_f.end)
- return buffer_retry;
- return freadptr (isp->u.u_f.fp, len);
-}
-
-static void
-file_consume (m4_input_block *me, m4 *context, size_t len)
-{
- const char *buf;
- const char *p;
- size_t buf_len;
- assert (!start_of_input_line);
- buf = freadptr (me->u.u_f.fp, &buf_len);
- assert (buf && len <= buf_len);
- buf_len = 0;
- while ((p = (char *) memchr (buf + buf_len, '\n', len - buf_len)))
- {
- if (p == buf + len - 1)
- start_of_input_line = true;
- else
- m4_set_current_line (context, ++me->line);
- buf_len = p - buf + 1;
- }
- if (freadseek (isp->u.u_f.fp, len) != 0)
- assert (false);
-}
-
-/* m4_push_file () pushes an input file FP with name TITLE on the
- input stack, saving the current file name and line number. If next
- is non-NULL, this push invalidates a call to m4_push_string_init (),
- whose storage is consequently released. If CLOSE, then close FP at
- end of file.
-
- file_read () manages line numbers for error messages, so they do not
- get wrong due to lookahead. The token consisting of a newline
- alone is taken as belonging to the line it ends, and the current
- line number is not incremented until the next character is read. */
-void
-m4_push_file (m4 *context, FILE *fp, const char *title, bool close_file)
-{
- m4_input_block *i;
-
- if (next != NULL)
- {
- obstack_free (current_input, next);
- next = NULL;
- }
-
- m4_debug_message (context, M4_DEBUG_TRACE_INPUT, _("input read from %s"),
- quotearg_style (locale_quoting_style, title));
-
- i = (m4_input_block *) obstack_alloc (current_input, sizeof *i);
- i->funcs = &file_funcs;
- /* Save title on a separate obstack, so that wrapped text can refer
- to it even after the file is popped. */
- i->file = obstack_copy0 (&file_names, title, strlen (title));
- i->line = 1;
-
- i->u.u_f.fp = fp;
- i->u.u_f.end = false;
- i->u.u_f.close = close_file;
- i->u.u_f.line_start = start_of_input_line;
-
- m4_set_output_line (context, -1);
-
- i->prev = isp;
- isp = i;
- input_change = true;
-}
-
-
-/* Handle string expansion text. */
-static int
-string_peek (m4_input_block *me, m4 *context M4_GNUC_UNUSED,
- bool allow_argv M4_GNUC_UNUSED)
-{
- return me->u.u_s.len ? to_uchar (*me->u.u_s.str) : CHAR_RETRY;
-}
-
-static int
-string_read (m4_input_block *me, m4 *context M4_GNUC_UNUSED,
- bool allow_quote M4_GNUC_UNUSED, bool allow_argv M4_GNUC_UNUSED,
- bool allow_unget M4_GNUC_UNUSED)
-{
- if (!me->u.u_s.len)
- return CHAR_RETRY;
- me->u.u_s.len--;
- return to_uchar (*me->u.u_s.str++);
-}
-
-static void
-string_unget (m4_input_block *me, int ch)
-{
- assert (ch < CHAR_EOF && to_uchar (me->u.u_s.str[-1]) == ch);
- me->u.u_s.str--;
- me->u.u_s.len++;
-}
-
-static void
-string_print (m4_input_block *me, m4 *context, m4_obstack *obs,
- int debug_level)
-{
- bool quote = (debug_level & M4_DEBUG_TRACE_QUOTE) != 0;
- size_t arg_length = m4_get_max_debug_arg_length_opt (context);
-
- assert (!me->u.u_s.len);
- m4_shipout_string_trunc (obs, (char *) obstack_base (current_input),
- obstack_object_size (current_input),
- quote ? m4_get_syntax_quotes (M4SYNTAX) : NULL,
- &arg_length);
-}
-
-static const char *
-string_buffer (m4_input_block *me, m4 *context M4_GNUC_UNUSED, size_t *len,
- bool allow_quote M4_GNUC_UNUSED)
-{
- if (!me->u.u_s.len)
- return buffer_retry;
- *len = me->u.u_s.len;
- return me->u.u_s.str;
-}
-
-static void
-string_consume (m4_input_block *me, m4 *context M4_GNUC_UNUSED, size_t len)
-{
- assert (len <= me->u.u_s.len);
- me->u.u_s.len -= len;
- me->u.u_s.str += len;
-}
-
-/* First half of m4_push_string (). The pointer next points to the
- new input_block. FILE and LINE describe the location where the
- macro starts that is generating the expansion (even if the location
- has advanced in the meantime). Return the obstack that will
- collect the expansion text. */
-m4_obstack *
-m4_push_string_init (m4 *context, const char *file, int line)
-{
- /* Free any memory occupied by completely parsed input. */
- assert (!next);
- while (pop_input (context, false));
-
- /* Reserve the next location on the obstack. */
- next = (m4_input_block *) obstack_alloc (current_input, sizeof *next);
- next->funcs = &string_funcs;
- next->file = file;
- next->line = line;
- next->u.u_s.len = 0;
-
- return current_input;
-}
-
-/* This function allows gathering input from multiple locations,
- rather than copying everything consecutively onto the input stack.
- Must be called between push_string_init and push_string_finish.
-
- Convert the current input block into a chain if it is not one
- already, and add the contents of VALUE as a new link in the chain.
- LEVEL describes the current expansion level, or SIZE_MAX if VALUE
- is composite, its contents reside entirely on the current_input
- stack, and VALUE lives in temporary storage. If VALUE is a simple
- string, then it belongs to the current macro expansion. If VALUE
- is composite, then each text link has a level of SIZE_MAX if it
- belongs to the current macro expansion, otherwise it is a
- back-reference where level tracks which stack it came from. The
- resulting input block chain contains links with a level of SIZE_MAX
- if the text belongs to the input stack, otherwise the level where
- the back-reference comes from.
-
- Return true only if a reference was created to the contents of
- VALUE, in which case, LEVEL is less than SIZE_MAX and the lifetime
- of VALUE and its contents must last as long as the input engine can
- parse references from it. INUSE determines whether composite
- symbols should favor creating back-references or copying text. */
-bool
-m4__push_symbol (m4 *context, m4_symbol_value *value, size_t level, bool inuse)
-{
- m4__symbol_chain *src_chain = NULL;
- m4__symbol_chain *chain;
-
- assert (next);
-
- /* Speed consideration - for short enough symbols, the speed and
- memory overhead of parsing another INPUT_CHAIN link outweighs the
- time to inline the symbol text. But don't copy text if it
- already lives on the obstack. */
- if (m4_is_symbol_value_text (value))
- {
- assert (level < SIZE_MAX);
- if (m4_get_symbol_value_len (value) <= INPUT_INLINE_THRESHOLD)
- {
- obstack_grow (current_input, m4_get_symbol_value_text (value),
- m4_get_symbol_value_len (value));
- return false;
- }
- }
- else if (m4_is_symbol_value_func (value))
- {
- if (next->funcs == &string_funcs)
- {
- next->funcs = &composite_funcs;
- next->u.u_c.chain = next->u.u_c.end = NULL;
- }
- m4__append_builtin (current_input, value->u.builtin, &next->u.u_c.chain,
- &next->u.u_c.end);
- return false;
- }
- else
- {
- /* For composite values, if argv is already in use, creating
- additional references for long text segments is more
- efficient in time. But if argv is not yet in use, and we
- have a composite value, then the value must already contain a
- back-reference, and memory usage is more efficient if we can
- avoid using the current expand_macro, even if it means larger
- copies. */
- assert (value->type == M4_SYMBOL_COMP);
- src_chain = value->u.u_c.chain;
- while (level < SIZE_MAX && src_chain && src_chain->type == M4__CHAIN_STR
- && (src_chain->u.u_s.len <= INPUT_INLINE_THRESHOLD
- || (!inuse && src_chain->u.u_s.level == SIZE_MAX)))
- {
- obstack_grow (current_input, src_chain->u.u_s.str,
- src_chain->u.u_s.len);
- src_chain = src_chain->next;
- }
- if (!src_chain)
- return false;
- }
-
- if (next->funcs == &string_funcs)
- {
- next->funcs = &composite_funcs;
- next->u.u_c.chain = next->u.u_c.end = NULL;
- }
- m4__make_text_link (current_input, &next->u.u_c.chain, &next->u.u_c.end);
- if (m4_is_symbol_value_text (value))
- {
- chain = (m4__symbol_chain *) obstack_alloc (current_input,
- sizeof *chain);
- if (next->u.u_c.end)
- next->u.u_c.end->next = chain;
- else
- next->u.u_c.chain = chain;
- next->u.u_c.end = chain;
- chain->next = NULL;
- chain->type = M4__CHAIN_STR;
- chain->quote_age = m4_get_symbol_value_quote_age (value);
- chain->u.u_s.str = m4_get_symbol_value_text (value);
- chain->u.u_s.len = m4_get_symbol_value_len (value);
- chain->u.u_s.level = level;
- m4__adjust_refcount (context, level, true);
- inuse = true;
- }
- while (src_chain)
- {
- if (src_chain->type == M4__CHAIN_FUNC)
- {
- m4__append_builtin (current_input, src_chain->u.builtin,
- &next->u.u_c.chain, &next->u.u_c.end);
- src_chain = src_chain->next;
- continue;
- }
- if (level == SIZE_MAX)
- {
- /* Nothing to copy, since link already lives on obstack. */
- assert (src_chain->type != M4__CHAIN_STR
- || src_chain->u.u_s.level == SIZE_MAX);
- chain = src_chain;
- }
- else
- {
- /* Allow inlining the final link with subsequent text. */
- if (!src_chain->next && src_chain->type == M4__CHAIN_STR
- && (src_chain->u.u_s.len <= INPUT_INLINE_THRESHOLD
- || (!inuse && src_chain->u.u_s.level == SIZE_MAX)))
- {
- obstack_grow (current_input, src_chain->u.u_s.str,
- src_chain->u.u_s.len);
- break;
- }
- /* We must clone each link in the chain, since next_char
- destructively modifies the chain it is parsing. */
- chain = (m4__symbol_chain *) obstack_copy (current_input, src_chain,
- sizeof *chain);
- chain->next = NULL;
- if (chain->type == M4__CHAIN_STR && chain->u.u_s.level == SIZE_MAX)
- {
- if (chain->u.u_s.len <= INPUT_INLINE_THRESHOLD || !inuse)
- chain->u.u_s.str = (char *) obstack_copy (current_input,
- chain->u.u_s.str,
- chain->u.u_s.len);
- else
- {
- chain->u.u_s.level = level;
- inuse = true;
- }
- }
- }
- if (next->u.u_c.end)
- next->u.u_c.end->next = chain;
- else
- next->u.u_c.chain = chain;
- next->u.u_c.end = chain;
- if (chain->type == M4__CHAIN_ARGV)
- {
- assert (!chain->u.u_a.comma && !chain->u.u_a.skip_last);
- inuse |= m4__arg_adjust_refcount (context, chain->u.u_a.argv, true);
- }
- else if (chain->type == M4__CHAIN_STR && chain->u.u_s.level < SIZE_MAX)
- m4__adjust_refcount (context, chain->u.u_s.level, true);
- src_chain = src_chain->next;
- }
- return inuse;
-}
-
-/* Last half of m4_push_string (). If next is now NULL, a call to
- m4_push_file () has pushed a different input block to the top of
- the stack. Otherwise, all unfinished text on the obstack returned
- from push_string_init is collected into the input stack. If the
- new object is empty, we do not push it. */
-void
-m4_push_string_finish (void)
-{
- size_t len = obstack_object_size (current_input);
-
- if (next == NULL)
- {
- assert (!len);
- return;
- }
-
- if (len || next->funcs == &composite_funcs)
- {
- if (next->funcs == &string_funcs)
- {
- next->u.u_s.str = (char *) obstack_finish (current_input);
- next->u.u_s.len = len;
- }
- else
- m4__make_text_link (current_input, &next->u.u_c.chain,
- &next->u.u_c.end);
- next->prev = isp;
- isp = next;
- input_change = true;
- }
- else
- obstack_free (current_input, next);
- next = NULL;
-}
-
-
-/* A composite block contains multiple sub-blocks which are processed
- in FIFO order, even though the obstack allocates memory in LIFO
- order. */
-static int
-composite_peek (m4_input_block *me, m4 *context, bool allow_argv)
-{
- m4__symbol_chain *chain = me->u.u_c.chain;
- size_t argc;
-
- while (chain)
- {
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- if (chain->u.u_s.len)
- return to_uchar (chain->u.u_s.str[0]);
- break;
- case M4__CHAIN_FUNC:
- if (chain->u.builtin)
- return CHAR_BUILTIN;
- break;
- case M4__CHAIN_ARGV:
- argc = m4_arg_argc (chain->u.u_a.argv);
- if (chain->u.u_a.index == argc)
- break;
- if (chain->u.u_a.comma)
- return ','; /* FIXME - support M4_SYNTAX_COMMA. */
- /* Only return a reference in the quoting is correct and the
- reference has more than one argument left. */
- if (allow_argv && chain->quote_age == m4__quote_age (M4SYNTAX)
- && chain->u.u_a.quotes && chain->u.u_a.index + 1 < argc)
- return CHAR_ARGV;
- /* Rather than directly parse argv here, we push another
- input block containing the next unparsed argument from
- argv. */
- m4_push_string_init (context, me->file, me->line);
- m4__push_arg_quote (context, current_input, chain->u.u_a.argv,
- chain->u.u_a.index,
- m4__quote_cache (M4SYNTAX, NULL,
- chain->quote_age,
- chain->u.u_a.quotes));
- chain->u.u_a.index++;
- chain->u.u_a.comma = true;
- m4_push_string_finish ();
- return peek_char (context, allow_argv);
- case M4__CHAIN_LOC:
- break;
- default:
- assert (!"composite_peek");
- abort ();
- }
- chain = chain->next;
- }
- return CHAR_RETRY;
-}
-
-static int
-composite_read (m4_input_block *me, m4 *context, bool allow_quote,
- bool allow_argv, bool allow_unget)
-{
- m4__symbol_chain *chain = me->u.u_c.chain;
- size_t argc;
- while (chain)
- {
- if (allow_quote && chain->quote_age == m4__quote_age (M4SYNTAX))
- return CHAR_QUOTE;
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- if (chain->u.u_s.len)
- {
- /* Partial consumption invalidates quote age. */
- chain->quote_age = 0;
- chain->u.u_s.len--;
- return to_uchar (*chain->u.u_s.str++);
- }
- if (chain->u.u_s.level < SIZE_MAX)
- m4__adjust_refcount (context, chain->u.u_s.level, false);
- break;
- case M4__CHAIN_FUNC:
- if (chain->u.builtin)
- return CHAR_BUILTIN;
- break;
- case M4__CHAIN_ARGV:
- argc = m4_arg_argc (chain->u.u_a.argv);
- if (chain->u.u_a.index == argc)
- {
- m4__arg_adjust_refcount (context, chain->u.u_a.argv, false);
- break;
- }
- if (chain->u.u_a.comma)
- {
- chain->u.u_a.comma = false;
- return ','; /* FIXME - support M4_SYNTAX_COMMA. */
- }
- /* Only return a reference in the quoting is correct and the
- reference has more than one argument left. */
- if (allow_argv && chain->quote_age == m4__quote_age (M4SYNTAX)
- && chain->u.u_a.quotes && chain->u.u_a.index + 1 < argc)
- return CHAR_ARGV;
- /* Rather than directly parse argv here, we push another
- input block containing the next unparsed argument from
- argv. */
- m4_push_string_init (context, me->file, me->line);
- m4__push_arg_quote (context, current_input, chain->u.u_a.argv,
- chain->u.u_a.index,
- m4__quote_cache (M4SYNTAX, NULL,
- chain->quote_age,
- chain->u.u_a.quotes));
- chain->u.u_a.index++;
- chain->u.u_a.comma = true;
- m4_push_string_finish ();
- return next_char (context, allow_quote, allow_argv, allow_unget);
- case M4__CHAIN_LOC:
- me->file = chain->u.u_l.file;
- me->line = chain->u.u_l.line;
- input_change = true;
- me->u.u_c.chain = chain->next;
- return next_char (context, allow_quote, allow_argv, allow_unget);
- default:
- assert (!"composite_read");
- abort ();
- }
- me->u.u_c.chain = chain = chain->next;
- }
- return CHAR_RETRY;
-}
-
-static void
-composite_unget (m4_input_block *me, int ch)
-{
- m4__symbol_chain *chain = me->u.u_c.chain;
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- assert (ch < CHAR_EOF && to_uchar (chain->u.u_s.str[-1]) == ch);
- chain->u.u_s.str--;
- chain->u.u_s.len++;
- break;
- case M4__CHAIN_FUNC:
- assert (ch == CHAR_BUILTIN && chain->u.builtin);
- break;
- case M4__CHAIN_ARGV:
- /* FIXME - support M4_SYNTAX_COMMA. */
- assert (ch == ',' && !chain->u.u_a.comma);
- chain->u.u_a.comma = true;
- break;
- default:
- assert (!"composite_unget");
- abort ();
- }
-}
-
-static bool
-composite_clean (m4_input_block *me, m4 *context, bool cleanup)
-{
- m4__symbol_chain *chain = me->u.u_c.chain;
- assert (!chain || !cleanup);
- while (chain)
- {
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- if (chain->u.u_s.len)
- {
- assert (!cleanup);
- return false;
- }
- if (chain->u.u_s.level < SIZE_MAX)
- m4__adjust_refcount (context, chain->u.u_s.level, false);
- break;
- case M4__CHAIN_FUNC:
- if (chain->u.builtin)
- return false;
- break;
- case M4__CHAIN_ARGV:
- if (chain->u.u_a.index < m4_arg_argc (chain->u.u_a.argv))
- {
- assert (!cleanup);
- return false;
- }
- m4__arg_adjust_refcount (context, chain->u.u_a.argv, false);
- break;
- case M4__CHAIN_LOC:
- return false;
- default:
- assert (!"composite_clean");
- abort ();
- }
- me->u.u_c.chain = chain = chain->next;
- }
- return true;
-}
-
-static void
-composite_print (m4_input_block *me, m4 *context, m4_obstack *obs,
- int debug_level)
-{
- bool quote = (debug_level & M4_DEBUG_TRACE_QUOTE) != 0;
- size_t maxlen = m4_get_max_debug_arg_length_opt (context);
- m4__symbol_chain *chain = me->u.u_c.chain;
- const m4_string_pair *quotes = m4_get_syntax_quotes (M4SYNTAX);
- bool module = (debug_level & M4_DEBUG_TRACE_MODULE) != 0;
- bool done = false;
- size_t len = obstack_object_size (current_input);
-
- if (quote)
- m4_shipout_string (context, obs, quotes->str1, quotes->len1, false);
- while (chain && !done)
- {
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- if (m4_shipout_string_trunc (obs, chain->u.u_s.str,
- chain->u.u_s.len, NULL, &maxlen))
- done = true;
- break;
- case M4__CHAIN_FUNC:
- m4__builtin_print (obs, chain->u.builtin, false, NULL, NULL, module);
- break;
- case M4__CHAIN_ARGV:
- assert (!chain->u.u_a.comma);
- if (m4__arg_print (context, obs, chain->u.u_a.argv,
- chain->u.u_a.index,
- m4__quote_cache (M4SYNTAX, NULL, chain->quote_age,
- chain->u.u_a.quotes),
- chain->u.u_a.flatten, NULL, NULL, &maxlen, false,
- module))
- done = true;
- break;
- default:
- assert (!"composite_print");
- abort ();
- }
- chain = chain->next;
- }
- if (len)
- m4_shipout_string_trunc (obs, (char *) obstack_base (current_input), len,
- NULL, &maxlen);
- if (quote)
- m4_shipout_string (context, obs, quotes->str2, quotes->len2, false);
-}
-
-static const char *
-composite_buffer (m4_input_block *me, m4 *context, size_t *len,
- bool allow_quote)
-{
- m4__symbol_chain *chain = me->u.u_c.chain;
- while (chain)
- {
- if (allow_quote && chain->quote_age == m4__quote_age (M4SYNTAX))
- return NULL; /* CHAR_QUOTE doesn't fit in buffer. */
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- if (chain->u.u_s.len)
- {
- *len = chain->u.u_s.len;
- return chain->u.u_s.str;
- }
- if (chain->u.u_s.level < SIZE_MAX)
- m4__adjust_refcount (context, chain->u.u_s.level, false);
- break;
- case M4__CHAIN_FUNC:
- if (chain->u.builtin)
- return NULL; /* CHAR_BUILTIN doesn't fit in buffer. */
- break;
- case M4__CHAIN_ARGV:
- if (chain->u.u_a.index == m4_arg_argc (chain->u.u_a.argv))
- {
- m4__arg_adjust_refcount (context, chain->u.u_a.argv, false);
- break;
- }
- return NULL; /* No buffer to provide. */
- case M4__CHAIN_LOC:
- me->file = chain->u.u_l.file;
- me->line = chain->u.u_l.line;
- input_change = true;
- me->u.u_c.chain = chain->next;
- return next_buffer (context, len, allow_quote);
- default:
- assert (!"composite_buffer");
- abort ();
- }
- me->u.u_c.chain = chain = chain->next;
- }
- return buffer_retry;
-}
-
-static void
-composite_consume (m4_input_block *me, m4 *context M4_GNUC_UNUSED, size_t len)
-{
- m4__symbol_chain *chain = me->u.u_c.chain;
- assert (chain && chain->type == M4__CHAIN_STR && len <= chain->u.u_s.len);
- /* Partial consumption invalidates quote age. */
- chain->quote_age = 0;
- chain->u.u_s.len -= len;
- chain->u.u_s.str += len;
-}
-
-/* Given an obstack OBS, capture any unfinished text as a link in the
- chain that starts at *START and ends at *END. START may be NULL if
- *END is non-NULL. */
-void
-m4__make_text_link (m4_obstack *obs, m4__symbol_chain **start,
- m4__symbol_chain **end)
-{
- m4__symbol_chain *chain;
- size_t len = obstack_object_size (obs);
-
- assert (end && (start || *end));
- if (len)
- {
- char *str = (char *) obstack_finish (obs);
- chain = (m4__symbol_chain *) obstack_alloc (obs, sizeof *chain);
- if (*end)
- (*end)->next = chain;
- else
- *start = chain;
- *end = chain;
- chain->next = NULL;
- chain->type = M4__CHAIN_STR;
- chain->quote_age = 0;
- chain->u.u_s.str = str;
- chain->u.u_s.len = len;
- chain->u.u_s.level = SIZE_MAX;
- }
-}
-
-/* Given an obstack OBS, capture any unfinished text as a link, then
- append the builtin FUNC as the next link in the chain that starts
- at *START and ends at *END. START may be NULL if *END is
- non-NULL. */
-void
-m4__append_builtin (m4_obstack *obs, const m4__builtin *func,
- m4__symbol_chain **start, m4__symbol_chain **end)
-{
- m4__symbol_chain *chain;
-
- assert (func);
- m4__make_text_link (obs, start, end);
- chain = (m4__symbol_chain *) obstack_alloc (obs, sizeof *chain);
- if (*end)
- (*end)->next = chain;
- else
- *start = chain;
- *end = chain;
- chain->next = NULL;
- chain->type = M4__CHAIN_FUNC;
- chain->quote_age = 0;
- chain->u.builtin = func;
-}
-
-/* Push TOKEN, which contains a builtin's definition, onto the obstack
- OBS, which is either input stack or the wrapup stack. */
-void
-m4_push_builtin (m4 *context, m4_obstack *obs, m4_symbol_value *token)
-{
- m4_input_block *i = (obs == current_input ? next : wsp);
- assert (i);
- if (i->funcs == &string_funcs)
- {
- i->funcs = &composite_funcs;
- i->u.u_c.chain = i->u.u_c.end = NULL;
- }
- else
- assert (i->funcs == &composite_funcs);
- m4__append_builtin (obs, token->u.builtin, &i->u.u_c.chain, &i->u.u_c.end);
-}
-
-
-/* End of input optimization. By providing these dummy callback
- functions, we guarantee that the input stack is never NULL, and
- thus make fewer execution branches. */
-static int
-eof_peek (m4_input_block *me, m4 *context M4_GNUC_UNUSED,
- bool allow_argv M4_GNUC_UNUSED)
-{
- assert (me == &input_eof);
- return CHAR_EOF;
-}
-
-static int
-eof_read (m4_input_block *me, m4 *context M4_GNUC_UNUSED,
- bool allow_quote M4_GNUC_UNUSED, bool allow_argv M4_GNUC_UNUSED,
- bool allow_unget M4_GNUC_UNUSED)
-{
- assert (me == &input_eof);
- return CHAR_EOF;
-}
-
-static void
-eof_unget (m4_input_block *me M4_GNUC_UNUSED, int ch)
-{
- assert (ch == CHAR_EOF);
-}
-
-static const char *
-eof_buffer (m4_input_block *me M4_GNUC_UNUSED, m4 *context M4_GNUC_UNUSED,
- size_t *len M4_GNUC_UNUSED, bool allow_unget M4_GNUC_UNUSED)
-{
- return NULL;
-}
-
-
-/* When tracing, print a summary of the contents of the input block
- created by push_string_init/push_string_finish to OBS. Use
- DEBUG_LEVEL to determine whether to add quotes or module
- designations. */
-void
-m4_input_print (m4 *context, m4_obstack *obs, int debug_level)
-{
- m4_input_block *block = next ? next : isp;
- assert (context && obs && (debug_level & M4_DEBUG_TRACE_EXPANSION));
- assert (block->funcs->print_func);
- block->funcs->print_func (block, context, obs, debug_level);
-}
-
-/* Return an obstack ready for direct expansion of wrapup text, and
- set *END to the location that should be updated if any builtin
- tokens are wrapped. Store the location of CALLER with the wrapped
- text. This should be followed by m4__push_wrapup_finish (). */
-m4_obstack *
-m4__push_wrapup_init (m4 *context, const m4_call_info *caller,
- m4__symbol_chain ***end)
-{
- m4_input_block *i;
- m4__symbol_chain *chain;
-
- assert (obstack_object_size (wrapup_stack) == 0);
- if (wsp != &input_eof)
- {
- i = wsp;
- assert (i->funcs == &composite_funcs && i->u.u_c.end
- && i->u.u_c.end->type != M4__CHAIN_LOC);
- }
- else
- {
- i = (m4_input_block *) obstack_alloc (wrapup_stack, sizeof *i);
- i->prev = wsp;
- i->funcs = &composite_funcs;
- i->file = caller->file;
- i->line = caller->line;
- i->u.u_c.chain = i->u.u_c.end = NULL;
- wsp = i;
- }
- chain = (m4__symbol_chain *) obstack_alloc (wrapup_stack, sizeof *chain);
- if (i->u.u_c.end)
- i->u.u_c.end->next = chain;
- else
- i->u.u_c.chain = chain;
- i->u.u_c.end = chain;
- chain->next = NULL;
- chain->type = M4__CHAIN_LOC;
- chain->quote_age = 0;
- chain->u.u_l.file = caller->file;
- chain->u.u_l.line = caller->line;
- *end = &i->u.u_c.end;
- return wrapup_stack;
-}
-
-/* After pushing wrapup text, this completes the bookkeeping. */
-void
-m4__push_wrapup_finish (void)
-{
- m4__make_text_link (wrapup_stack, &wsp->u.u_c.chain, &wsp->u.u_c.end);
- assert (wsp->u.u_c.end->type != M4__CHAIN_LOC);
-}
-
-
-/* The function pop_input () pops one level of input sources. If
- CLEANUP, the current_file and current_line are restored as needed.
- The return value is false if cleanup is still required, or if the
- current input source is not at the end. */
-static bool
-pop_input (m4 *context, bool cleanup)
-{
- m4_input_block *tmp = isp->prev;
-
- assert (isp);
- if (isp->funcs->clean_func
- ? !isp->funcs->clean_func (isp, context, cleanup)
- : (isp->funcs->peek_func (isp, context, true) != CHAR_RETRY))
- return false;
-
- obstack_free (current_input, isp);
- m4__quote_uncache (M4SYNTAX);
- next = NULL; /* might be set in m4_push_string_init () */
-
- isp = tmp;
- input_change = true;
- return true;
-}
-
-/* To switch input over to the wrapup stack, main calls pop_wrapup.
- Since wrapup text can install new wrapup text, pop_wrapup ()
- returns true if there is more wrapped text to parse. */
-bool
-m4_pop_wrapup (m4 *context)
-{
- static size_t level = 0;
-
- next = NULL;
- obstack_free (current_input, NULL);
- free (current_input);
-
- if (wsp == &input_eof)
- {
- obstack_free (wrapup_stack, NULL);
- m4_set_current_file (context, NULL);
- m4_set_current_line (context, 0);
- m4_debug_message (context, M4_DEBUG_TRACE_INPUT,
- _("input from m4wrap exhausted"));
- current_input = NULL;
- DELETE (wrapup_stack);
- return false;
- }
-
- m4_debug_message (context, M4_DEBUG_TRACE_INPUT,
- _("input from m4wrap recursion level %zu"), ++level);
-
- current_input = wrapup_stack;
- wrapup_stack = (m4_obstack *) xmalloc (sizeof *wrapup_stack);
- obstack_init (wrapup_stack);
-
- isp = wsp;
- wsp = &input_eof;
- input_change = true;
-
- return true;
-}
-
-/* Populate TOKEN with the builtin token at the top of the input
- stack, then consume the input. If OBS, TOKEN will be converted to
- a composite token using storage from OBS as necessary; otherwise,
- if TOKEN is NULL, the builtin token is discarded. */
-static void
-init_builtin_token (m4 *context, m4_obstack *obs, m4_symbol_value *token)
-{
- m4__symbol_chain *chain;
- assert (isp->funcs == &composite_funcs);
- chain = isp->u.u_c.chain;
- assert (!chain->quote_age && chain->type == M4__CHAIN_FUNC
- && chain->u.builtin);
- if (obs)
- {
- assert (token);
- if (token->type == M4_SYMBOL_VOID)
- {
- token->type = M4_SYMBOL_COMP;
- token->u.u_c.chain = token->u.u_c.end = NULL;
- token->u.u_c.wrapper = false;
- token->u.u_c.has_func = false;
- }
- assert (token->type == M4_SYMBOL_COMP);
- m4__append_builtin (obs, chain->u.builtin, &token->u.u_c.chain,
- &token->u.u_c.end);
- }
- else if (token)
- {
- assert (token->type == M4_SYMBOL_VOID);
- m4__set_symbol_value_builtin (token, chain->u.builtin);
- }
- chain->u.builtin = NULL;
-}
-
-/* When a QUOTE token is seen, convert VALUE to a composite (if it is
- not one already), consisting of any unfinished text on OBS, as well
- as the quoted token from the top of the input stack. Use OBS for
- any additional allocations needed to store the token chain. */
-static void
-append_quote_token (m4 *context, m4_obstack *obs, m4_symbol_value *value)
-{
- m4__symbol_chain *src_chain = isp->u.u_c.chain;
- m4__symbol_chain *chain;
- assert (isp->funcs == &composite_funcs && obs && m4__quote_age (M4SYNTAX));
- isp->u.u_c.chain = src_chain->next;
-
- /* Speed consideration - for short enough symbols, the speed and
- memory overhead of parsing another INPUT_CHAIN link outweighs the
- time to inline the symbol text. */
- if (src_chain->type == M4__CHAIN_STR
- && src_chain->u.u_s.len <= INPUT_INLINE_THRESHOLD)
- {
- assert (src_chain->u.u_s.level <= SIZE_MAX);
- obstack_grow (obs, src_chain->u.u_s.str, src_chain->u.u_s.len);
- m4__adjust_refcount (context, src_chain->u.u_s.level, false);
- return;
- }
-
- if (value->type == M4_SYMBOL_VOID)
- {
- value->type = M4_SYMBOL_COMP;
- value->u.u_c.chain = value->u.u_c.end = NULL;
- value->u.u_c.wrapper = value->u.u_c.has_func = false;
- }
- assert (value->type == M4_SYMBOL_COMP);
- m4__make_text_link (obs, &value->u.u_c.chain, &value->u.u_c.end);
- chain = (m4__symbol_chain *) obstack_copy (obs, src_chain, sizeof *chain);
- if (value->u.u_c.end)
- value->u.u_c.end->next = chain;
- else
- value->u.u_c.chain = chain;
- value->u.u_c.end = chain;
- if (chain->type == M4__CHAIN_ARGV && chain->u.u_a.has_func)
- value->u.u_c.has_func = true;
- chain->next = NULL;
-}
-
-/* When an ARGV token is seen, convert VALUE to point to it via a
- composite chain. Use OBS for any additional allocations
- needed. */
-static void
-init_argv_symbol (m4 *context, m4_obstack *obs, m4_symbol_value *value)
-{
- m4__symbol_chain *src_chain;
- m4__symbol_chain *chain;
- int ch;
- const m4_string_pair *comments = m4_get_syntax_comments (M4SYNTAX);
-
- assert (value->type == M4_SYMBOL_VOID && isp->funcs == &composite_funcs
- && isp->u.u_c.chain->type == M4__CHAIN_ARGV
- && obs && obstack_object_size (obs) == 0);
-
- src_chain = isp->u.u_c.chain;
- isp->u.u_c.chain = src_chain->next;
- value->type = M4_SYMBOL_COMP;
- /* Clone the link, since the input will be discarded soon. */
- chain = (m4__symbol_chain *) obstack_copy (obs, src_chain, sizeof *chain);
- value->u.u_c.chain = value->u.u_c.end = chain;
- value->u.u_c.wrapper = true;
- value->u.u_c.has_func = chain->u.u_a.has_func;
- chain->next = NULL;
-
- /* If the next character is not ',' or ')', then unlink the last
- argument from argv and schedule it for reparsing. This way,
- expand_argument never has to deal with concatenation of argv with
- arbitrary text. Note that the implementation of safe_quotes
- ensures peek_input won't return CHAR_ARGV if the user is perverse
- enough to mix comment delimiters with argument separators:
-
- define(n,`$#')define(echo,$*)changecom(`,,',`)')n(echo(a,`,b`)'',c))
- => 2 (not 3)
-
- Therefore, we do not have to worry about calling MATCH, and thus
- do not have to worry about pop_input being called and
- invalidating the argv reference.
-
- When the $@ ref is used unchanged, we completely bypass the
- decrement of the argv refcount in next_char, since the ref is
- still live via the current collect_arguments. However, when the
- last element of the $@ ref is reparsed, we must increase the argv
- refcount here, to compensate for the fact that it will be
- decreased once the final element is parsed. */
- assert (!comments->len1
- || (!m4_has_syntax (M4SYNTAX, *comments->str1,
- M4_SYNTAX_COMMA | M4_SYNTAX_CLOSE)
- && *comments->str1 != *src_chain->u.u_a.quotes->str1));
- ch = peek_char (context, true);
- if (!m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_COMMA | M4_SYNTAX_CLOSE))
- {
- isp->u.u_c.chain = src_chain;
- src_chain->u.u_a.index = m4_arg_argc (chain->u.u_a.argv) - 1;
- src_chain->u.u_a.comma = true;
- chain->u.u_a.skip_last = true;
- m4__arg_adjust_refcount (context, chain->u.u_a.argv, true);
- }
-}
-
-
-/* Low level input is done a character at a time. The function
- next_char () is used to read and advance the input to the next
- character. If ALLOW_QUOTE, and the current input matches the
- current quote age, return CHAR_QUOTE and leave consumption of data
- for append_quote_token; otherwise, if ALLOW_ARGV, and the current
- input matches an argv reference with the correct quoting, return
- CHAR_ARGV and leave consumption of data for init_argv_symbol. If
- ALLOW_UNGET, then pop input to avoid returning CHAR_RETRY, and
- ensure that unget_input can safely be called next. */
-static int
-next_char (m4 *context, bool allow_quote, bool allow_argv, bool allow_unget)
-{
- int ch;
-
- while (1)
- {
- if (input_change)
- {
- m4_set_current_file (context, isp->file);
- m4_set_current_line (context, isp->line);
- input_change = false;
- }
-
- assert (isp->funcs->read_func);
- while (((ch = isp->funcs->read_func (isp, context, allow_quote,
- allow_argv, allow_unget))
- != CHAR_RETRY)
- || allow_unget)
- {
- /* if (!IS_IGNORE (ch)) */
- return ch;
- }
-
- /* End of input source --- pop one level. */
- pop_input (context, true);
- }
-}
-
-/* The function peek_char () is used to look at the next character in
- the input stream. At any given time, it reads from the input_block
- on the top of the current input stack. If ALLOW_ARGV, then return
- CHAR_ARGV if an entire $@ reference is available for use. */
-static int
-peek_char (m4 *context, bool allow_argv)
-{
- int ch;
- m4_input_block *block = isp;
-
- while (1)
- {
- assert (block->funcs->peek_func);
- ch = block->funcs->peek_func (block, context, allow_argv);
- if (ch != CHAR_RETRY)
- {
-/* if (IS_IGNORE (ch)) */
-/* return next_char (context, false, true, false); */
- return ch;
- }
-
- block = block->prev;
- }
-}
-
-/* The function unget_input () puts back a character on the input
- stack, using an existing input_block if possible. This is not safe
- to call except immediately after next_char(context, aq, aa, true). */
-static void
-unget_input (int ch)
-{
- assert (isp->funcs->unget_func != NULL);
- isp->funcs->unget_func (isp, ch);
-}
-
-/* Return a pointer to the available bytes of the current input block,
- and set *LEN to the length of the result. If ALLOW_QUOTE, do not
- return a buffer for a quoted string. If the result does not fit in
- a char (for example, CHAR_EOF or CHAR_QUOTE), or if there is no
- readahead data available, return NULL, and the caller must fall
- back to next_char(). The buffer is only valid until the next
- consume_buffer() or next_char(). */
-static const char *
-next_buffer (m4 *context, size_t *len, bool allow_quote)
-{
- const char *buf;
- while (1)
- {
- assert (isp);
- if (input_change)
- {
- m4_set_current_file (context, isp->file);
- m4_set_current_line (context, isp->line);
- input_change = false;
- }
-
- assert (isp->funcs->buffer_func);
- buf = isp->funcs->buffer_func (isp, context, len, allow_quote);
- if (buf != buffer_retry)
- return buf;
- /* End of input source --- pop one level. */
- pop_input (context, true);
- }
-}
-
-/* Consume LEN bytes from the current input block, as though by LEN
- calls to next_char(). LEN must be less than or equal to the
- previous length returned by a successful call to next_buffer(). */
-static void
-consume_buffer (m4 *context, size_t len)
-{
- assert (isp && !input_change);
- if (len)
- {
- assert (isp->funcs->consume_func);
- isp->funcs->consume_func (isp, context, len);
- }
-}
-
-/* skip_line () simply discards all immediately following characters,
- up to the first newline. It is only used from m4_dnl (). Report
- errors on behalf of CALLER. */
-void
-m4_skip_line (m4 *context, const m4_call_info *caller)
-{
- int ch;
-
- while (1)
- {
- size_t len;
- const char *buffer = next_buffer (context, &len, false);
- if (buffer)
- {
- const char *p = (char *) memchr (buffer, '\n', len);
- if (p)
- {
- consume_buffer (context, p - buffer + 1);
- ch = '\n';
- break;
- }
- consume_buffer (context, len);
- }
- else
- {
- ch = next_char (context, false, false, false);
- if (ch == CHAR_EOF || ch == '\n')
- break;
- }
- }
- if (ch == CHAR_EOF)
- m4_warn (context, 0, caller, _("end of file treated as newline"));
-}
-
-
-/* If the string S of length LEN matches the next characters of the
- input stream, return true. If CONSUME, the first byte has already
- been matched. If a match is found and CONSUME is true, the input
- is discarded; otherwise any characters read are pushed back again.
- The function is used only when multicharacter quotes or comment
- delimiters are used.
-
- All strings herein should be unsigned. Otherwise sign-extension
- of individual chars might break quotes with 8-bit chars in it.
-
- FIXME - when matching multiquotes that cross file boundaries, we do
- not properly restore the current input file and line when we
- restore unconsumed characters. */
-static bool
-match_input (m4 *context, const char *s, size_t len, bool consume)
-{
- int n; /* number of characters matched */
- int ch; /* input character */
- const char *t;
- m4_obstack *st;
- bool result = false;
- size_t buf_len;
-
- if (consume)
- {
- s++;
- len--;
- }
- /* Try a buffer match first. */
- assert (len);
- t = next_buffer (context, &buf_len, false);
- if (t && len <= buf_len && memcmp (s, t, len) == 0)
- {
- if (consume)
- consume_buffer (context, len);
- return true;
- }
- /* Fall back on byte matching. */
- ch = peek_char (context, false);
- if (ch != to_uchar (*s))
- return false;
-
- if (len == 1)
- {
- if (consume)
- next_char (context, false, false, false);
- return true; /* short match */
- }
-
- next_char (context, false, false, false);
- for (n = 1, t = s++; peek_char (context, false) == to_uchar (*s++); )
- {
- next_char (context, false, false, false);
- n++;
- if (--len == 1) /* long match */
- {
- if (consume)
- return true;
- result = true;
- break;
- }
- }
-
- /* Failed or shouldn't consume, push back input. */
- st = m4_push_string_init (context, m4_get_current_file (context),
- m4_get_current_line (context));
- obstack_grow (st, t, n);
- m4_push_string_finish ();
- return result;
-}
-
-/* Check whether the current input matches a delimiter, which either
- belongs to syntax category CAT or matches the string S of length
- LEN. The first character is handled inline for speed, and S[LEN]
- must be safe to dereference (it is faster to do character
- comparison prior to length checks). This improves efficiency for
- the common case of single character quotes and comment delimiters,
- while being safe for disabled delimiters as well as longer
- delimiters. If CONSUME, then CH is the result of next_char, and a
- successful match will discard the matched string. Otherwise, CH is
- the result of peek_char, and the input stream is effectively
- unchanged. */
-#define MATCH(C, ch, cat, s, len, consume) \
- (m4_has_syntax (m4_get_syntax_table (C), ch, cat) \
- || (to_uchar ((s)[0]) == (ch) \
- && ((len) >> 1 ? match_input (C, s, len, consume) : (len))))
-
-/* While the current input character has the given SYNTAX, append it
- to OBS. Take care not to pop input source unless the next source
- would continue the chain. Return true if the chain ended with
- CHAR_EOF. */
-static bool
-consume_syntax (m4 *context, m4_obstack *obs, unsigned int syntax)
-{
- int ch;
- bool allow = m4__safe_quotes (M4SYNTAX);
- assert (syntax);
- while (1)
- {
- /* Start with a buffer search. */
- size_t len;
- const char *buffer = next_buffer (context, &len, allow);
- if (buffer)
- {
- const char *p = buffer;
- while (len && m4_has_syntax (M4SYNTAX, *p, syntax))
- {
- len--;
- p++;
- }
- obstack_grow (obs, buffer, p - buffer);
- consume_buffer (context, p - buffer);
- if (len)
- return false;
- }
- /* Fall back to byte-wise search. It is safe to call next_char
- without first checking peek_char, except at input source
- boundaries, which we detect by CHAR_RETRY. */
- ch = next_char (context, allow, allow, true);
- if (ch < CHAR_EOF && m4_has_syntax (M4SYNTAX, ch, syntax))
- {
- obstack_1grow (obs, ch);
- continue;
- }
- if (ch == CHAR_RETRY || ch == CHAR_QUOTE || ch == CHAR_ARGV)
- {
- ch = peek_char (context, false);
- /* We exploit the fact that CHAR_EOF, CHAR_BUILTIN,
- CHAR_QUOTE, and CHAR_ARGV do not satisfy any syntax
- categories. */
- if (m4_has_syntax (M4SYNTAX, ch, syntax))
- {
- assert (ch < CHAR_EOF);
- obstack_1grow (obs, ch);
- next_char (context, false, false, false);
- continue;
- }
- return ch == CHAR_EOF;
- }
- unget_input (ch);
- return false;
- }
-}
-
-
-/* Initialize input stacks. */
-void
-m4_input_init (m4 *context)
-{
- obstack_init (&file_names);
- m4_set_current_file (context, NULL);
- m4_set_current_line (context, 0);
-
- current_input = (m4_obstack *) xmalloc (sizeof *current_input);
- obstack_init (current_input);
- wrapup_stack = (m4_obstack *) xmalloc (sizeof *wrapup_stack);
- obstack_init (wrapup_stack);
-
- /* Allocate an object in the current chunk, so that obstack_free
- will always work even if the first token parsed spills to a new
- chunk. */
- obstack_init (&token_stack);
- token_bottom = obstack_finish (&token_stack);
-
- isp = &input_eof;
- wsp = &input_eof;
- next = NULL;
-
- start_of_input_line = false;
-}
-
-/* Free memory used by the input engine. */
-void
-m4_input_exit (void)
-{
- assert (!current_input && isp == &input_eof);
- assert (!wrapup_stack && wsp == &input_eof);
- obstack_free (&file_names, NULL);
- obstack_free (&token_stack, NULL);
-}
-
-
-/* Parse and return a single token from the input stream, constructed
- into TOKEN. See m4__token_type for the valid return types, along
- with a description of what TOKEN will contain. If LINE is not
- NULL, set *LINE to the line number where the token starts. If OBS,
- expand safe tokens (strings and comments) directly into OBS rather
- than in a temporary staging area. If ALLOW_ARGV, OBS must be
- non-NULL, and an entire series of arguments can be returned if a $@
- reference is encountered. Report errors (unterminated comments or
- strings) on behalf of CALLER, if non-NULL.
-
- If OBS is NULL or the token expansion is unknown, the token text is
- collected on the obstack token_stack, which never contains more
- than one token text at a time. The storage pointed to by the
- fields in TOKEN is therefore subject to change the next time
- m4__next_token () is called. */
-m4__token_type
-m4__next_token (m4 *context, m4_symbol_value *token, int *line,
- m4_obstack *obs, bool allow_argv, const m4_call_info *caller)
-{
- int ch;
- int quote_level;
- m4__token_type type;
- const char *file = NULL;
- size_t len;
- /* The obstack where token data is stored. Generally token_stack,
- for tokens where argument collection might not use the literal
- token. But for comments and strings, we can output directly into
- the argument collection obstack OBS, if provided. */
- m4_obstack *obs_safe = &token_stack;
-
- assert (next == NULL);
- memset (token, '\0', sizeof *token);
- do {
- obstack_free (&token_stack, token_bottom);
-
- /* Must consume an input character. */
- ch = next_char (context, false, allow_argv && m4__quote_age (M4SYNTAX),
- false);
- if (line)
- {
- *line = m4_get_current_line (context);
- file = m4_get_current_file (context);
- }
- if (ch == CHAR_EOF) /* EOF */
- {
-#ifdef DEBUG_INPUT
- xfprintf (stderr, "next_token -> EOF\n");
-#endif
- return M4_TOKEN_EOF;
- }
-
- if (ch == CHAR_BUILTIN) /* BUILTIN TOKEN */
- {
- init_builtin_token (context, obs, token);
-#ifdef DEBUG_INPUT
- m4_print_token (context, "next_token", M4_TOKEN_MACDEF, token);
-#endif
- return M4_TOKEN_MACDEF;
- }
- if (ch == CHAR_ARGV)
- {
- init_argv_symbol (context, obs, token);
-#ifdef DEBUG_INPUT
- m4_print_token (context, "next_token", M4_TOKEN_ARGV, token);
-#endif
- return M4_TOKEN_ARGV;
- }
-
- if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_ESCAPE))
- { /* ESCAPED WORD */
- obstack_1grow (&token_stack, ch);
- if ((ch = next_char (context, false, false, false)) < CHAR_EOF)
- {
- obstack_1grow (&token_stack, ch);
- if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_ALPHA))
- consume_syntax (context, &token_stack,
- M4_SYNTAX_ALPHA | M4_SYNTAX_NUM);
- type = M4_TOKEN_WORD;
- }
- else
- type = M4_TOKEN_SIMPLE; /* escape before eof */
- }
- else if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_ALPHA))
- {
- type = (m4_is_syntax_macro_escaped (M4SYNTAX)
- ? M4_TOKEN_STRING : M4_TOKEN_WORD);
- if (type == M4_TOKEN_STRING && obs)
- obs_safe = obs;
- obstack_1grow (obs_safe, ch);
- consume_syntax (context, obs_safe, M4_SYNTAX_ALPHA | M4_SYNTAX_NUM);
- }
- else if (MATCH (context, ch, M4_SYNTAX_LQUOTE,
- context->syntax->quote.str1,
- context->syntax->quote.len1, true))
- { /* QUOTED STRING */
- if (obs)
- obs_safe = obs;
- quote_level = 1;
- type = M4_TOKEN_STRING;
- while (1)
- {
- /* Start with buffer search for either potential delimiter. */
- size_t len;
- const char *buffer = next_buffer (context, &len,
- obs && m4__quote_age (M4SYNTAX));
- if (buffer)
- {
- const char *p = buffer;
- if (m4_is_syntax_single_quotes (M4SYNTAX))
- do
- {
- p = (char *) memchr2 (p, *context->syntax->quote.str1,
- *context->syntax->quote.str2,
- buffer + len - p);
- }
- while (p && m4__quote_age (M4SYNTAX)
- && (*p++ == *context->syntax->quote.str2
- ? --quote_level : ++quote_level));
- else
- {
- size_t remaining = len;
- assert (context->syntax->quote.len1 == 1
- && context->syntax->quote.len2 == 1);
- while (remaining && !m4_has_syntax (M4SYNTAX, *p,
- (M4_SYNTAX_LQUOTE
- | M4_SYNTAX_RQUOTE)))
- {
- p++;
- remaining--;
- }
- if (!remaining)
- p = NULL;
- }
- if (p)
- {
- if (m4__quote_age (M4SYNTAX))
- {
- assert (!quote_level
- && context->syntax->quote.len1 == 1
- && context->syntax->quote.len2 == 1);
- obstack_grow (obs_safe, buffer, p - buffer - 1);
- consume_buffer (context, p - buffer);
- break;
- }
- obstack_grow (obs_safe, buffer, p - buffer);
- ch = to_uchar (*p);
- consume_buffer (context, p - buffer + 1);
- }
- else
- {
- obstack_grow (obs_safe, buffer, len);
- consume_buffer (context, len);
- continue;
- }
- }
- /* Fall back to byte-wise search. */
- else
- ch = next_char (context, obs && m4__quote_age (M4SYNTAX), false,
- false);
- if (ch == CHAR_EOF)
- {
- if (!caller)
- {
- assert (line);
- m4_set_current_file (context, file);
- m4_set_current_line (context, *line);
- }
- m4_error (context, EXIT_FAILURE, 0, caller,
- _("end of file in string"));
- }
- if (ch == CHAR_BUILTIN)
- init_builtin_token (context, obs, obs ? token : NULL);
- else if (ch == CHAR_QUOTE)
- append_quote_token (context, obs, token);
- else if (MATCH (context, ch, M4_SYNTAX_RQUOTE,
- context->syntax->quote.str2,
- context->syntax->quote.len2, true))
- {
- if (--quote_level == 0)
- break;
- if (1 < context->syntax->quote.len2)
- obstack_grow (obs_safe, context->syntax->quote.str2,
- context->syntax->quote.len2);
- else
- obstack_1grow (obs_safe, ch);
- }
- else if (MATCH (context, ch, M4_SYNTAX_LQUOTE,
- context->syntax->quote.str1,
- context->syntax->quote.len1, true))
- {
- quote_level++;
- if (1 < context->syntax->quote.len1)
- obstack_grow (obs_safe, context->syntax->quote.str1,
- context->syntax->quote.len1);
- else
- obstack_1grow (obs_safe, ch);
- }
- else
- obstack_1grow (obs_safe, ch);
- }
- }
- else if (MATCH (context, ch, M4_SYNTAX_BCOMM,
- context->syntax->comm.str1,
- context->syntax->comm.len1, true))
- { /* COMMENT */
- if (obs && !m4_get_discard_comments_opt (context))
- obs_safe = obs;
- if (1 < context->syntax->comm.len1)
- obstack_grow (obs_safe, context->syntax->comm.str1,
- context->syntax->comm.len1);
- else
- obstack_1grow (obs_safe, ch);
- while (1)
- {
- /* Start with buffer search for potential end delimiter. */
- size_t len;
- const char *buffer = next_buffer (context, &len, false);
- if (buffer)
- {
- const char *p;
- if (m4_is_syntax_single_comments (M4SYNTAX))
- p = (char *) memchr (buffer, *context->syntax->comm.str2,
- len);
- else
- {
- size_t remaining = len;
- assert (context->syntax->comm.len2 == 1);
- p = buffer;
- while (remaining
- && !m4_has_syntax (M4SYNTAX, *p, M4_SYNTAX_ECOMM))
- {
- p++;
- remaining--;
- }
- if (!remaining)
- p = NULL;
- }
- if (p)
- {
- obstack_grow (obs_safe, buffer, p - buffer);
- ch = to_uchar (*p);
- consume_buffer (context, p - buffer + 1);
- }
- else
- {
- obstack_grow (obs_safe, buffer, len);
- consume_buffer (context, len);
- continue;
- }
- }
- /* Fall back to byte-wise search. */
- else
- ch = next_char (context, false, false, false);
- if (ch == CHAR_EOF)
- {
- if (!caller)
- {
- assert (line);
- m4_set_current_file (context, file);
- m4_set_current_line (context, *line);
- }
- m4_error (context, EXIT_FAILURE, 0, caller,
- _("end of file in comment"));
- }
- if (ch == CHAR_BUILTIN)
- {
- init_builtin_token (context, NULL, NULL);
- continue;
- }
- if (MATCH (context, ch, M4_SYNTAX_ECOMM,
- context->syntax->comm.str2,
- context->syntax->comm.len2, true))
- {
- if (1 < context->syntax->comm.len2)
- obstack_grow (obs_safe, context->syntax->comm.str2,
- context->syntax->comm.len2);
- else
- obstack_1grow (obs_safe, ch);
- break;
- }
- assert (ch < CHAR_EOF);
- obstack_1grow (obs_safe, ch);
- }
- type = (m4_get_discard_comments_opt (context)
- ? M4_TOKEN_NONE : M4_TOKEN_COMMENT);
- }
- else if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_ACTIVE))
- { /* ACTIVE CHARACTER */
- obstack_1grow (&token_stack, ch);
- type = M4_TOKEN_WORD;
- }
- else if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_OPEN))
- { /* OPEN PARENTHESIS */
- obstack_1grow (&token_stack, ch);
- type = M4_TOKEN_OPEN;
- }
- else if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_COMMA))
- { /* COMMA */
- obstack_1grow (&token_stack, ch);
- type = M4_TOKEN_COMMA;
- }
- else if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_CLOSE))
- { /* CLOSE PARENTHESIS */
- obstack_1grow (&token_stack, ch);
- type = M4_TOKEN_CLOSE;
- }
- else
- { /* EVERYTHING ELSE */
- assert (ch < CHAR_EOF);
- obstack_1grow (&token_stack, ch);
- if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_OTHER | M4_SYNTAX_NUM))
- {
- if (obs)
- {
- obs_safe = obs;
- obstack_1grow (obs, ch);
- }
- if (m4__safe_quotes (M4SYNTAX))
- consume_syntax (context, obs_safe,
- M4_SYNTAX_OTHER | M4_SYNTAX_NUM);
- type = M4_TOKEN_STRING;
- }
- else if (m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_SPACE))
- {
- /* Coalescing newlines when interactive or when synclines
- are enabled is wrong. */
- if (!m4_get_interactive_opt (context)
- && !m4_get_syncoutput_opt (context)
- && m4__safe_quotes (M4SYNTAX))
- consume_syntax (context, &token_stack, M4_SYNTAX_SPACE);
- type = M4_TOKEN_SPACE;
- }
- else
- type = M4_TOKEN_SIMPLE;
- }
- } while (type == M4_TOKEN_NONE);
-
- if (token->type == M4_SYMBOL_VOID)
- {
- if (obs_safe != obs)
- {
- len = obstack_object_size (&token_stack);
- obstack_1grow (&token_stack, '\0');
-
- m4_set_symbol_value_text (token, obstack_finish (&token_stack), len,
- m4__quote_age (M4SYNTAX));
- }
- else
- assert (type == M4_TOKEN_STRING || type == M4_TOKEN_COMMENT);
- }
- else
- assert (token->type == M4_SYMBOL_COMP
- && (type == M4_TOKEN_STRING || type == M4_TOKEN_COMMENT));
- VALUE_MAX_ARGS (token) = -1;
-
-#ifdef DEBUG_INPUT
- if (token->type == M4_SYMBOL_VOID)
- {
- len = obstack_object_size (&token_stack);
- obstack_1grow (&token_stack, '\0');
-
- m4_set_symbol_value_text (token, obstack_finish (&token_stack), len,
- m4__quote_age (M4SYNTAX));
- }
-
- m4_print_token (context, "next_token", type, token);
-#endif
-
- return type;
-}
-
-/* Peek at the next token in the input stream to see if it is an open
- parenthesis. It is possible that what is peeked at may change as a
- result of changequote (or friends). This honors multi-character
- comments and quotes, just as next_token does. */
-bool
-m4__next_token_is_open (m4 *context)
-{
- int ch = peek_char (context, false);
-
- if (ch == CHAR_EOF || ch == CHAR_BUILTIN
- || m4_has_syntax (M4SYNTAX, ch, (M4_SYNTAX_BCOMM | M4_SYNTAX_ESCAPE
- | M4_SYNTAX_ALPHA | M4_SYNTAX_LQUOTE
- | M4_SYNTAX_ACTIVE))
- || (MATCH (context, ch, M4_SYNTAX_BCOMM, context->syntax->comm.str1,
- context->syntax->comm.len1, false))
- || (MATCH (context, ch, M4_SYNTAX_LQUOTE, context->syntax->quote.str1,
- context->syntax->quote.len1, false)))
- return false;
- return m4_has_syntax (M4SYNTAX, ch, M4_SYNTAX_OPEN);
-}
-
-
-#ifdef DEBUG_INPUT
-
-int
-m4_print_token (m4 *context, const char *s, m4__token_type type,
- m4_symbol_value *token)
-{
- m4_obstack obs;
- size_t len;
-
- if (!s)
- s = "m4input";
- xfprintf (stderr, "%s: ", s);
- switch (type)
- { /* TOKSW */
- case M4_TOKEN_EOF:
- fputs ("eof", stderr);
- token = NULL;
- break;
- case M4_TOKEN_NONE:
- fputs ("none", stderr);
- token = NULL;
- break;
- case M4_TOKEN_STRING:
- fputs ("string\t", stderr);
- break;
- case M4_TOKEN_COMMENT:
- fputs ("comment\t", stderr);
- break;
- case M4_TOKEN_SPACE:
- fputs ("space\t", stderr);
- break;
- case M4_TOKEN_WORD:
- fputs ("word\t", stderr);
- break;
- case M4_TOKEN_OPEN:
- fputs ("open\t", stderr);
- break;
- case M4_TOKEN_COMMA:
- fputs ("comma\t", stderr);
- break;
- case M4_TOKEN_CLOSE:
- fputs ("close\t", stderr);
- break;
- case M4_TOKEN_SIMPLE:
- fputs ("simple\t", stderr);
- break;
- case M4_TOKEN_MACDEF:
- fputs ("builtin\t", stderr);
- break;
- case M4_TOKEN_ARGV:
- fputs ("argv\t", stderr);
- break;
- default:
- abort ();
- }
- if (token)
- {
- obstack_init (&obs);
- m4__symbol_value_print (context, token, &obs, NULL, false, NULL, NULL,
- true);
- len = obstack_object_size (&obs);
- xfprintf (stderr, "%s\n", quotearg_style_mem (c_maybe_quoting_style,
- obstack_finish (&obs),
- len));
- obstack_free (&obs, NULL);
- }
- else
- fputc ('\n', stderr);
- return 0;
-}
-#endif /* DEBUG_INPUT */
diff --git a/m4/m4.c b/m4/m4.c
deleted file mode 100644
index 0bf185ce..00000000
--- a/m4/m4.c
+++ /dev/null
@@ -1,159 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2001, 2004, 2006-2008, 2010, 2013-2014, 2017
- Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include "bitrotate.h"
-#include "m4private.h"
-
-#define DEFAULT_NESTING_LIMIT 1024
-#define DEFAULT_NAMEMAP_SIZE 61
-
-static size_t
-hashfn (const void *ptr)
-{
- const char *s = (const char *) ptr;
- size_t val = DEFAULT_NAMEMAP_SIZE;
- while (*s)
- val = rotl_sz (val, 7) + to_uchar (*s++);
- return val;
-}
-
-
-m4 *
-m4_create (void)
-{
- m4 *context = (m4 *) xzalloc (sizeof *context);
-
- context->symtab = m4_symtab_create (0);
- context->syntax = m4_syntax_create ();
-
- context->namemap =
- m4_hash_new (DEFAULT_NAMEMAP_SIZE, hashfn, (m4_hash_cmp_func *) strcmp);
-
- context->debug_file = stderr;
- obstack_init (&context->trace_messages);
-
- context->nesting_limit = DEFAULT_NESTING_LIMIT;
- context->debug_level = M4_DEBUG_TRACE_INITIAL;
- context->max_debug_arg_length = SIZE_MAX;
-
- context->search_path =
- (m4__search_path_info *) xzalloc (sizeof *context->search_path);
- m4__include_init (context);
-
- return context;
-}
-
-void
-m4_delete (m4 *context)
-{
- size_t i;
- assert (context);
-
- if (context->symtab)
- m4_symtab_delete (context->symtab);
-
- if (context->syntax)
- m4_syntax_delete (context->syntax);
-
- /* debug_file should have been reset to stdout or stderr, both of
- which are closed later. */
- assert (context->debug_file == stderr || context->debug_file == stdout);
-
- obstack_free (&context->trace_messages, NULL);
-
- if (context->search_path)
- {
- m4__search_path *path = context->search_path->list;
-
- while (path)
- {
- m4__search_path *stale = path;
- path = path->next;
-
- DELETE (stale->dir); /* Cast away const. */
- free (stale);
- }
- free (context->search_path);
- }
-
- for (i = 0; i < context->stacks_count; i++)
- {
- assert (context->arg_stacks[i].refcount == 0
- && context->arg_stacks[i].argcount == 0);
- if (context->arg_stacks[i].args)
- {
- obstack_free (context->arg_stacks[i].args, NULL);
- free (context->arg_stacks[i].args);
- obstack_free (context->arg_stacks[i].argv, NULL);
- free (context->arg_stacks[i].argv);
- }
- }
- free (context->arg_stacks);
-
- free (context);
-}
-
-
-
-/* Use the preprocessor to generate the repetitive bit twiddling functions
- for us. Note the additional paretheses around the expanded function
- name to protect against macro expansion from the fast macros used to
- replace these functions when NDEBUG is defined. */
-#define M4FIELD(type, base, field) \
- type (CONC(m4_get_, base)) (m4 *context) \
- { \
- assert (context); \
- return context->field; \
- }
-m4_context_field_table
-#undef M4FIELD
-
-#define M4FIELD(type, base, field) \
- type (CONC(m4_set_, base)) (m4 *context, type value) \
- { \
- assert (context); \
- return context->field = value; \
- }
-m4_context_field_table
-#undef M4FIELD
-
-#define M4OPT_BIT(bit, base) \
- bool (CONC(m4_get_, base)) (m4 *context) \
- { \
- assert (context); \
- return BIT_TEST (context->opt_flags, (bit)); \
- }
-m4_context_opt_bit_table
-#undef M4OPT_BIT
-
-#define M4OPT_BIT(bit, base) \
- bool (CONC(m4_set_, base)) (m4 *context, bool value) \
- { \
- assert (context); \
- if (value) \
- BIT_SET (context->opt_flags, (bit)); \
- else \
- BIT_RESET (context->opt_flags, (bit)); \
- return value; \
- }
-m4_context_opt_bit_table
-#undef M4OPT_BIT
diff --git a/m4/m4module.h b/m4/m4module.h
deleted file mode 100644
index a96b9853..00000000
--- a/m4/m4module.h
+++ /dev/null
@@ -1,556 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 1999-2000, 2003-2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef M4MODULE_H
-#define M4MODULE_H 1
-
-#include <m4/hash.h>
-#include <m4/system.h>
-
-BEGIN_C_DECLS
-
-
-
-/* --- MODULE AUTHOR DECLARATIONS --- */
-
-typedef struct m4 m4;
-typedef struct m4_builtin m4_builtin;
-typedef struct m4_call_info m4_call_info;
-typedef struct m4_macro m4_macro;
-typedef struct m4_macro_args m4_macro_args;
-typedef struct m4_module m4_module;
-typedef struct obstack m4_obstack;
-typedef struct m4_string m4_string;
-typedef struct m4_string_pair m4_string_pair;
-typedef struct m4_symbol m4_symbol;
-typedef struct m4_symbol_value m4_symbol_value;
-
-typedef void m4_builtin_func (m4 *, m4_obstack *, size_t, m4_macro_args *);
-
-/* The value of m4_builtin flags is built from these: */
-enum {
- /* Set if macro flattens non-text tokens, such as builtin macro
- tokens, to the empty string prior to invoking the builtin; if
- clear, non-text tokens must be transparently handled by the
- builtin. May only be set if max_args is nonzero. */
- M4_BUILTIN_FLATTEN_ARGS = (1 << 0),
- /* Set if macro should only be recognized with arguments; may only
- be set if min_args is nonzero. */
- M4_BUILTIN_BLIND = (1 << 1),
- /* Set if macro has side effects even when there are too few
- arguments; may only be set if min_args is nonzero. */
- M4_BUILTIN_SIDE_EFFECT = (1 << 2),
-
- /* Mask of valid flag bits. Any other bits must be set to 0. */
- M4_BUILTIN_FLAGS_MASK = (1 << 3) - 1
-};
-
-struct m4_builtin
-{
- m4_builtin_func * func; /* implementation of the builtin */
- const char * name; /* name found by builtin, printed by dumpdef */
- int flags; /* bitwise OR of M4_BUILTIN_* bits */
- size_t min_args; /* 0-based minimum number of arguments */
- /* max arguments, SIZE_MAX if unlimited; must be >= min_args */
- size_t max_args;
-};
-
-struct m4_macro
-{
- const char *name;
- const char *value;
- size_t min_args; /* 0-based minimum number of arguments */
- /* max arguments, SIZE_MAX if unlimited; must be >= min_args */
- size_t max_args;
-};
-
-/* Describe a single string, such as a macro name. */
-struct m4_string
-{
- char *str; /* Array of characters, possibly including NUL. */
- size_t len; /* Length of string. */
-};
-
-/* Describe a pair of strings, such as begin and end quotes. */
-struct m4_string_pair
-{
- char *str1; /* First string. */
- size_t len1; /* First length. */
- char *str2; /* Second string. */
- size_t len2; /* Second length. */
-};
-
-/* Declare a prototype for the function "builtin_<NAME>". Note that
- the function name includes any macro expansion of NAME. */
-#define M4BUILTIN(name) \
- static void CONC (builtin_, name) \
- (m4 *, m4_obstack *, size_t, m4_macro_args *);
-
-/* Begin the implementation of the function "builtin_<NAME>",
- declaring parameter names that can be used by other helper macros
- in this file. Note that the function name includes any macro
- expansion of NAME. */
-#define M4BUILTIN_HANDLER(name) \
- static void CONC (builtin_, name) \
- (m4 *context, m4_obstack *obs, size_t argc, m4_macro_args *argv)
-
-/* Declare a variable S of type "<S>_func" to be a pointer to the
- function named S imported from the module M, or NULL if the import
- fails. Note that M and S are intentionally used literally rather
- than subjected to macro expansion, in all but the variable name. */
-#define M4_MODULE_IMPORT(M, S) \
- S ## _func *S = (S ## _func *) m4_module_import (context, #M, #S, obs)
-
-/* Build an entry in a builtin table, for the builtin N implemented by
- the function "builtin_<N>" with name NAME. Build the flags from
- the appropriate combination of M4_BUILTIN_FLAG_* based on M if the
- builtin transparently supports macro tokens, B if it is blind, and
- S if it has side effects. Specify that the builtin takes MIN and
- MAX arguments. Note that N is subject to macro expansion, and that
- NAME is generally used as #N to avoid clashes with builtins named
- after a standard function that is defined as a macro. */
-#define M4BUILTIN_ENTRY(N, NAME, M, B, S, MIN, MAX) \
- { \
- CONC (builtin_, N), NAME, \
- (((!(M) && (MAX)) ? M4_BUILTIN_FLATTEN_ARGS : 0) \
- | (((B) && (MIN)) ? M4_BUILTIN_BLIND : 0) \
- | (((S) && (MIN)) ? M4_BUILTIN_SIDE_EFFECT : 0)), \
- MIN, MAX \
- },
-
-/* Grab the text contents of argument I, or abort if the argument is
- not text. Assumes that `m4 *context' and `m4_macro_args *argv' are
- in scope. */
-#define M4ARG(i) m4_arg_text (context, argv, i, false)
-
-/* Grab the length of the text contents of argument I, or abort if the
- argument is not text. Assumes that `m4 *context' and
- `m4_macro_args *argv' are in scope. */
-#define M4ARGLEN(i) m4_arg_len (context, argv, i, false)
-
-extern bool m4_bad_argc (m4 *, size_t, const m4_call_info *, size_t,
- size_t, bool);
-extern bool m4_numeric_arg (m4 *, const m4_call_info *, const char *,
- size_t, int *);
-extern bool m4_parse_truth_arg (m4 *, const m4_call_info *, const char *,
- size_t, bool);
-extern m4_symbol *m4_symbol_value_lookup (m4 *, m4_macro_args *, size_t, bool);
-extern const char *m4_info_name (const m4_call_info *);
-
-/* Error handling. */
-extern void m4_error (m4 *, int, int, const m4_call_info *, const char *, ...)
- M4_GNUC_PRINTF (5, 6);
-extern void m4_warn (m4 *, int, const m4_call_info *, const char *, ...)
- M4_GNUC_PRINTF (4, 5);
-
-extern const char * m4_get_program_name (void);
-extern void m4_set_program_name (const char *);
-extern void m4_set_exit_failure (int);
-
-
-/* --- CONTEXT MANAGEMENT --- */
-
-typedef struct m4_syntax_table m4_syntax_table;
-typedef struct m4_symbol_table m4_symbol_table;
-
-extern m4 * m4_create (void);
-extern void m4_delete (m4 *);
-
-#define m4_context_field_table \
- M4FIELD(m4_symbol_table *, symbol_table, symtab) \
- M4FIELD(m4_syntax_table *, syntax_table, syntax) \
- M4FIELD(const char *, current_file, current_file) \
- M4FIELD(int, current_line, current_line) \
- M4FIELD(int, output_line, output_line) \
- M4FIELD(FILE *, debug_file, debug_file) \
- M4FIELD(m4_obstack, trace_messages, trace_messages) \
- M4FIELD(int, exit_status, exit_status) \
- M4FIELD(int, current_diversion, current_diversion) \
- M4FIELD(size_t, nesting_limit_opt, nesting_limit) \
- M4FIELD(int, debug_level_opt, debug_level) \
- M4FIELD(size_t, max_debug_arg_length_opt, max_debug_arg_length)\
- M4FIELD(int, regexp_syntax_opt, regexp_syntax) \
-
-
-#define m4_context_opt_bit_table \
- M4OPT_BIT(M4_OPT_PREFIX_BUILTINS_BIT, prefix_builtins_opt) \
- M4OPT_BIT(M4_OPT_SUPPRESS_WARN_BIT, suppress_warnings_opt) \
- M4OPT_BIT(M4_OPT_DISCARD_COMMENTS_BIT, discard_comments_opt) \
- M4OPT_BIT(M4_OPT_INTERACTIVE_BIT, interactive_opt) \
- M4OPT_BIT(M4_OPT_SYNCOUTPUT_BIT, syncoutput_opt) \
- M4OPT_BIT(M4_OPT_POSIXLY_CORRECT_BIT, posixly_correct_opt) \
- M4OPT_BIT(M4_OPT_FATAL_WARN_BIT, fatal_warnings_opt) \
- M4OPT_BIT(M4_OPT_WARN_EXIT_BIT, warnings_exit_opt) \
- M4OPT_BIT(M4_OPT_SAFER_BIT, safer_opt) \
-
-
-#define M4FIELD(type, base, field) \
- extern type CONC (m4_get_, base) (m4 *context); \
- extern type CONC (m4_set_, base) (m4 *context, type value);
-m4_context_field_table
-#undef M4FIELD
-
-#define M4OPT_BIT(bit, base) \
- extern bool CONC (m4_get_, base) (m4 *context); \
- extern bool CONC (m4_set_, base) (m4 *context, bool value);
-m4_context_opt_bit_table
-#undef M4OPT_BIT
-
-#define M4SYMTAB (m4_get_symbol_table (context))
-#define M4SYNTAX (m4_get_syntax_table (context))
-
-
-
-/* --- MODULE MANAGEMENT --- */
-
-typedef void m4_module_init_func (m4 *, m4_module *, m4_obstack *);
-
-extern m4_module * m4_module_load (m4 *, const char *, m4_obstack *);
-extern void * m4_module_import (m4 *, const char *, const char *,
- m4_obstack *);
-
-extern void m4_install_builtins (m4*, m4_module *, const m4_builtin*);
-extern void m4_install_macros (m4*, m4_module *, const m4_macro*);
-
-extern const char * m4_get_module_name (const m4_module *);
-extern m4_module * m4_module_next (m4*, m4_module *);
-
-
-
-/* --- SYMBOL TABLE MANAGEMENT --- */
-
-
-typedef void *m4_symtab_apply_func (m4_symbol_table *, const char *, size_t,
- m4_symbol *, void *);
-
-extern m4_symbol_table *m4_symtab_create (size_t);
-extern void m4_symtab_delete (m4_symbol_table *);
-extern void * m4_symtab_apply (m4_symbol_table *, bool,
- m4_symtab_apply_func *, void *);
-
-extern m4_symbol *m4_symbol_lookup (m4_symbol_table *, const char *, size_t);
-extern m4_symbol *m4_symbol_pushdef (m4_symbol_table *, const char *, size_t,
- m4_symbol_value *);
-extern m4_symbol *m4_symbol_define (m4_symbol_table *, const char *, size_t,
- m4_symbol_value *);
-extern void m4_symbol_popdef (m4_symbol_table *, const char *, size_t);
-extern m4_symbol *m4_symbol_rename (m4_symbol_table *, const char *, size_t,
- const char *, size_t);
-
-extern void m4_symbol_delete (m4_symbol_table *, const char *, size_t);
-
-#define m4_symbol_delete(symtab, name, len) M4_STMT_START \
- { \
- while (m4_symbol_lookup (symtab, name, len)) \
- m4_symbol_popdef (symtab, name, len); \
- } M4_STMT_END
-
-extern m4_symbol_value *m4_get_symbol_value (m4_symbol *);
-extern bool m4_get_symbol_traced (m4_symbol *);
-extern bool m4_set_symbol_name_traced (m4_symbol_table *,
- const char *, size_t, bool);
-extern void m4_symbol_print (m4 *, m4_symbol *, m4_obstack *,
- const m4_string_pair *, bool, size_t,
- bool);
-extern bool m4_symbol_value_flatten_args (m4_symbol_value *);
-
-#define m4_is_symbol_void(symbol) \
- (m4_is_symbol_value_void (m4_get_symbol_value (symbol)))
-#define m4_is_symbol_text(symbol) \
- (m4_is_symbol_value_text (m4_get_symbol_value (symbol)))
-#define m4_is_symbol_func(symbol) \
- (m4_is_symbol_value_func (m4_get_symbol_value (symbol)))
-#define m4_is_symbol_placeholder(symbol) \
- (m4_is_symbol_value_placeholder (m4_get_symbol_value (symbol)))
-#define m4_get_symbol_text(symbol) \
- (m4_get_symbol_value_text (m4_get_symbol_value (symbol)))
-#define m4_get_symbol_len(symbol) \
- (m4_get_symbol_value_len (m4_get_symbol_value (symbol)))
-#define m4_get_symbol_func(symbol) \
- (m4_get_symbol_value_func (m4_get_symbol_value (symbol)))
-#define m4_get_symbol_builtin(symbol) \
- (m4_get_symbol_value_builtin (m4_get_symbol_value (symbol)))
-#define m4_get_symbol_placeholder(symbol) \
- (m4_get_symbol_value_placeholder (m4_get_symbol_value (symbol)))
-#define m4_symbol_flatten_args(symbol) \
- (m4_symbol_value_flatten_args (m4_get_symbol_value (symbol)))
-
-extern m4_symbol_value *m4_symbol_value_create (void);
-extern void m4_symbol_value_delete (m4_symbol_value *);
-extern bool m4_symbol_value_copy (m4 *, m4_symbol_value *,
- m4_symbol_value *);
-extern bool m4_is_symbol_value_text (m4_symbol_value *);
-extern bool m4_is_symbol_value_func (m4_symbol_value *);
-extern bool m4_is_symbol_value_placeholder (m4_symbol_value *);
-extern bool m4_is_symbol_value_void (m4_symbol_value *);
-
-extern const char * m4_get_symbol_value_text (m4_symbol_value *);
-extern size_t m4_get_symbol_value_len (m4_symbol_value *);
-extern unsigned int m4_get_symbol_value_quote_age (m4_symbol_value *);
-
-extern m4_builtin_func *m4_get_symbol_value_func (m4_symbol_value *);
-extern const m4_builtin *m4_get_symbol_value_builtin (m4_symbol_value *);
-extern const char * m4_get_symbol_value_placeholder (m4_symbol_value *);
-
-extern void m4_set_symbol_value_text (m4_symbol_value *,
- const char *, size_t,
- unsigned int);
-extern void m4_set_symbol_value_placeholder (m4_symbol_value *,
- const char *);
-
-
-
-/* --- BUILTIN MANAGEMENT --- */
-
-extern m4_symbol_value *m4_builtin_find_by_name (m4 *, m4_module *, const char *);
-extern m4_symbol_value *m4_builtin_find_by_func (m4 *, m4_module *,
- m4_builtin_func *);
-
-
-
-/* --- MACRO MANAGEMENT --- */
-
-extern void m4_macro_expand_input (m4 *);
-extern void m4_macro_call (m4 *, m4_symbol_value *, m4_obstack *,
- m4_macro_args *);
-extern size_t m4_arg_argc (m4_macro_args *);
-extern const m4_call_info *m4_arg_info (m4_macro_args *);
-extern m4_symbol_value *m4_arg_symbol (m4_macro_args *, size_t);
-extern bool m4_is_arg_text (m4_macro_args *, size_t);
-extern bool m4_is_arg_func (m4_macro_args *, size_t);
-extern bool m4_is_arg_composite (m4_macro_args *, size_t);
-extern const char *m4_arg_text (m4 *, m4_macro_args *, size_t, bool);
-extern bool m4_arg_equal (m4 *, m4_macro_args *, size_t,
- size_t);
-extern bool m4_arg_empty (m4_macro_args *, size_t);
-extern size_t m4_arg_len (m4 *, m4_macro_args *, size_t, bool);
-extern m4_builtin_func *m4_arg_func (m4_macro_args *, size_t);
-extern m4_obstack *m4_arg_scratch (m4 *);
-extern m4_macro_args *m4_make_argv_ref (m4 *, m4_macro_args *, const char *,
- size_t, bool, bool);
-extern void m4_push_arg (m4 *, m4_obstack *, m4_macro_args *,
- size_t);
-extern void m4_push_args (m4 *, m4_obstack *, m4_macro_args *,
- bool, bool);
-extern void m4_wrap_args (m4 *, m4_macro_args *);
-
-
-/* --- RUNTIME DEBUGGING --- */
-
-/* The value of debug_level is a bitmask of the following: */
-enum {
- /* a: show arglist in trace output */
- M4_DEBUG_TRACE_ARGS = (1 << 0),
- /* e: show expansion in trace output */
- M4_DEBUG_TRACE_EXPANSION = (1 << 1),
- /* q: quote args and expansion in trace output */
- M4_DEBUG_TRACE_QUOTE = (1 << 2),
- /* t: trace all macros -- overrides trace{on,off} */
- M4_DEBUG_TRACE_ALL = (1 << 3),
- /* l: add line numbers to trace output */
- M4_DEBUG_TRACE_LINE = (1 << 4),
- /* f: add file name to trace output */
- M4_DEBUG_TRACE_FILE = (1 << 5),
- /* p: trace path search of include files */
- M4_DEBUG_TRACE_PATH = (1 << 6),
- /* c: show macro call before args collection */
- M4_DEBUG_TRACE_CALL = (1 << 7),
- /* i: trace changes of input files */
- M4_DEBUG_TRACE_INPUT = (1 << 8),
- /* x: add call id to trace output */
- M4_DEBUG_TRACE_CALLID = (1 << 9),
- /* m: trace module actions */
- M4_DEBUG_TRACE_MODULE = (1 << 10),
- /* s: trace pushdef stacks */
- M4_DEBUG_TRACE_STACK = (1 << 11),
- /* d: warn if dereferencing undefined macro */
- M4_DEBUG_TRACE_DEREF = (1 << 12),
- /* o: output dumpdef to stderr, not debug file */
- M4_DEBUG_TRACE_OUTPUT_DUMPDEF = (1 << 13),
-
- /* V: very verbose -- print everything */
- M4_DEBUG_TRACE_VERBOSE = ((1 << 14) - 1)
-};
-
-/* initial flags, used if no -d or -E -- equiv: d */
-#define M4_DEBUG_TRACE_INITIAL M4_DEBUG_TRACE_DEREF
-
-/* default flags, used by debugmode() -- equiv: +adeq */
-#define M4_DEBUG_TRACE_DEFAULT \
- (M4_DEBUG_TRACE_ARGS | M4_DEBUG_TRACE_EXPANSION \
- | M4_DEBUG_TRACE_QUOTE | M4_DEBUG_TRACE_DEREF)
-
-#define m4_is_debug_bit(C,B) ((m4_get_debug_level_opt (C) & (B)) != 0)
-
-extern int m4_debug_decode (m4 *, const char *, size_t);
-extern bool m4_debug_set_output (m4 *, const m4_call_info *,
- const char *);
-extern void m4_debug_message_prefix (m4 *);
-extern void m4_debug_message (m4 *, int, const char *, ...)
- M4_GNUC_PRINTF (3, 4);
-
-extern void m4_trace_prepare (m4 *, const m4_call_info *,
- m4_symbol_value *);
-
-
-/* --- REGEXP SYNTAX --- */
-
-extern const char * m4_regexp_syntax_decode (int);
-extern int m4_regexp_syntax_encode (const char *);
-
-
-
-/* --- SYNTAX TABLE DEFINITIONS --- */
-
-extern m4_syntax_table *m4_syntax_create (void);
-extern void m4_syntax_delete (m4_syntax_table *syntax);
-extern int m4_syntax_code (char ch);
-
-extern const char * m4_get_syntax_lquote (m4_syntax_table *syntax);
-extern const char * m4_get_syntax_rquote (m4_syntax_table *syntax);
-extern const char * m4_get_syntax_bcomm (m4_syntax_table *syntax);
-extern const char * m4_get_syntax_ecomm (m4_syntax_table *syntax);
-extern const m4_string_pair *m4_get_syntax_quotes (m4_syntax_table *);
-extern const m4_string_pair *m4_get_syntax_comments (m4_syntax_table *);
-
-extern bool m4_is_syntax_single_quotes (m4_syntax_table *);
-extern bool m4_is_syntax_single_comments (m4_syntax_table *);
-extern bool m4_is_syntax_single_dollar (m4_syntax_table *);
-extern bool m4_is_syntax_macro_escaped (m4_syntax_table *);
-
-/* These are values to be assigned to syntax table entries. Although
- they are bit masks for fast categorization in m4__next_token(),
- only one value per syntax table entry is allowed. The enumeration
- is currently sorted in order of parsing precedence. */
-enum {
- M4_SYNTAX_IGNORE = 0,
- M4_SYNTAX_ESCAPE = 1 << 0,
- M4_SYNTAX_ALPHA = 1 << 1,
- M4_SYNTAX_LQUOTE = 1 << 2,
- M4_SYNTAX_BCOMM = 1 << 3,
- M4_SYNTAX_ACTIVE = 1 << 4,
- M4_SYNTAX_NUM = 1 << 5,
- M4_SYNTAX_SPACE = 1 << 6,
- M4_SYNTAX_OPEN = 1 << 7,
- M4_SYNTAX_CLOSE = 1 << 8,
- M4_SYNTAX_COMMA = 1 << 9,
- M4_SYNTAX_OTHER = 1 << 10,
-
- /* These values are bit masks to OR with categories above, a syntax entry
- may have any number of these in addition to a maximum of one of the
- values above. */
- M4_SYNTAX_DOLLAR = 1 << 11,
- M4_SYNTAX_LBRACE = 1 << 12,
- M4_SYNTAX_RBRACE = 1 << 13,
- M4_SYNTAX_RQUOTE = 1 << 14,
- M4_SYNTAX_ECOMM = 1 << 15
-};
-
-/* Mask of attribute syntax categories. */
-#define M4_SYNTAX_MASKS (M4_SYNTAX_RQUOTE | M4_SYNTAX_ECOMM \
- | M4_SYNTAX_DOLLAR | M4_SYNTAX_LBRACE \
- | M4_SYNTAX_RBRACE)
-/* Mask of basic syntax categories where any change requires a
- recomputation of the overall syntax characteristics. */
-#define M4_SYNTAX_SUSPECT (M4_SYNTAX_LQUOTE | M4_SYNTAX_BCOMM \
- | M4_SYNTAX_ESCAPE)
-
-#define m4_syntab(S, C) ((S)->table[(C)])
-/* Determine if character C matches any of the bitwise-or'd syntax
- categories T for the given syntax table S. C can be either an
- unsigned int (including special values such as CHAR_BUILTIN) or a
- char which will be interpreted as an unsigned char. */
-#define m4_has_syntax(S, C, T) \
- ((m4_syntab ((S), sizeof (C) == 1 ? to_uchar (C) : (C)) & (T)) > 0)
-
-extern void m4_set_quotes (m4_syntax_table *, const char *, size_t,
- const char *, size_t);
-extern void m4_set_comment (m4_syntax_table *, const char *, size_t,
- const char *, size_t);
-extern int m4_set_syntax (m4_syntax_table *, char, char, const char *,
- size_t);
-extern void m4_reset_syntax (m4_syntax_table *);
-
-
-
-/* --- INPUT TOKENIZATION --- */
-
-extern void m4_input_init (m4 *context);
-extern void m4_input_exit (void);
-extern void m4_skip_line (m4 *context, const m4_call_info *);
-
-/* push back input */
-
-extern void m4_push_file (m4 *, FILE *, const char *, bool);
-extern void m4_push_builtin (m4 *, m4_obstack *, m4_symbol_value *);
-extern m4_obstack *m4_push_string_init (m4 *, const char *, int);
-extern void m4_push_string_finish (void);
-extern bool m4_pop_wrapup (m4 *);
-extern void m4_input_print (m4 *, m4_obstack *, int);
-
-
-
-/* --- OUTPUT MANAGEMENT --- */
-
-extern void m4_output_init (m4 *);
-extern void m4_output_exit (void);
-extern void m4_output_text (m4 *, const char *, size_t);
-extern void m4_divert_text (m4 *, m4_obstack *, const char *,
- size_t, int);
-extern void m4_shipout_int (m4_obstack *, int);
-extern void m4_shipout_string (m4 *, m4_obstack *, const char *,
- size_t, bool);
-extern bool m4_shipout_string_trunc (m4_obstack *, const char *, size_t,
- const m4_string_pair *, size_t *);
-
-extern void m4_make_diversion (m4 *, int);
-extern void m4_insert_diversion (m4 *, int);
-extern void m4_insert_file (m4 *, FILE *);
-extern void m4_freeze_diversions (m4 *, FILE *);
-extern void m4_undivert_all (m4 *);
-
-
-
-/* --- PATH MANAGEMENT --- */
-
-extern void m4_add_include_directory (m4 *, const char *, bool);
-extern bool m4_load_filename (m4 *, const m4_call_info *,
- const char *, m4_obstack *, bool);
-extern char * m4_path_search (m4 *, const char *, const char **);
-extern FILE * m4_fopen (m4 *, const char *, const char *);
-
-
-
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
-
-/* Convert a possibly-signed character to an unsigned character. This is
- a bit safer than casting to unsigned char, since it catches some type
- errors that the cast doesn't. */
-#if HAVE_INLINE
-static inline unsigned char to_uchar (char ch) { return ch; }
-#else
-# define to_uchar(C) ((unsigned char) (C))
-#endif
-
-END_C_DECLS
-
-#endif /* !M4MODULE_H */
diff --git a/m4/m4private.h b/m4/m4private.h
deleted file mode 100644
index a09ca9f8..00000000
--- a/m4/m4private.h
+++ /dev/null
@@ -1,626 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 1998-1999, 2004-2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef M4PRIVATE_H
-#define M4PRIVATE_H 1
-
-#include <m4/m4module.h>
-
-#include "cloexec.h"
-#include "quotearg.h"
-#include "xmemdup0.h"
-
-typedef struct m4__search_path_info m4__search_path_info;
-typedef struct m4__macro_arg_stacks m4__macro_arg_stacks;
-typedef struct m4__symbol_chain m4__symbol_chain;
-
-typedef enum {
- M4_SYMBOL_VOID, /* Traced but undefined, u is invalid. */
- M4_SYMBOL_TEXT, /* Plain text, u.u_t is valid. */
- M4_SYMBOL_FUNC, /* Builtin function, u.func is valid. */
- M4_SYMBOL_PLACEHOLDER, /* Placeholder for unknown builtin from -R. */
- M4_SYMBOL_COMP /* Composite symbol, u.u_c.c is valid. */
-} m4__symbol_type;
-
-#define BIT_TEST(flags, bit) (((flags) & (bit)) == (bit))
-#define BIT_SET(flags, bit) ((flags) |= (bit))
-#define BIT_RESET(flags, bit) ((flags) &= ~(bit))
-
-/* Gnulib's stdbool doesn't work with bool bitfields. For nicer
- debugging, use bool when we know it works, but use the more
- portable unsigned int elsewhere. */
-#if __GNUC__ > 2
-typedef bool bool_bitfield;
-#else
-typedef unsigned int bool_bitfield;
-#endif /* !__GNUC__ */
-
-
-/* --- CONTEXT MANAGEMENT --- */
-
-struct m4 {
- m4_symbol_table * symtab;
- m4_syntax_table * syntax;
- m4_module * modules;
- m4_hash * namemap;
-
- const char * current_file; /* Current input file. */
- int current_line; /* Current input line. */
- int output_line; /* Current output line. */
-
- FILE * debug_file; /* File for debugging output. */
- m4_obstack trace_messages;
- int exit_status; /* Cumulative exit status. */
- int current_diversion; /* Current output diversion. */
-
- /* Option flags (set in src/main.c). */
- size_t nesting_limit; /* -L */
- int debug_level; /* -d */
- size_t max_debug_arg_length; /* -l */
- int regexp_syntax; /* -r */
- int opt_flags;
-
- /* __PRIVATE__: */
- m4__search_path_info *search_path; /* The list of path directories. */
- m4__macro_arg_stacks *arg_stacks; /* Array of current argv refs. */
- size_t stacks_count; /* Size of arg_stacks. */
- size_t expansion_level;/* Macro call nesting level. */
-};
-
-#define M4_OPT_PREFIX_BUILTINS_BIT (1 << 0) /* -P */
-#define M4_OPT_SUPPRESS_WARN_BIT (1 << 1) /* -Q */
-#define M4_OPT_DISCARD_COMMENTS_BIT (1 << 2) /* -c */
-#define M4_OPT_INTERACTIVE_BIT (1 << 3) /* -e */
-#define M4_OPT_SYNCOUTPUT_BIT (1 << 4) /* -s */
-#define M4_OPT_POSIXLY_CORRECT_BIT (1 << 5) /* -G/POSIXLY_CORRECT */
-#define M4_OPT_FATAL_WARN_BIT (1 << 6) /* -E once */
-#define M4_OPT_WARN_EXIT_BIT (1 << 7) /* -E twice */
-#define M4_OPT_SAFER_BIT (1 << 8) /* --safer */
-
-/* Fast macro versions of accessor functions for public fields of m4,
- that also have an identically named function exported in m4module.h. */
-#ifdef NDEBUG
-# define m4_get_symbol_table(C) ((C)->symtab)
-# define m4_set_symbol_table(C, V) ((C)->symtab = (V))
-# define m4_get_syntax_table(C) ((C)->syntax)
-# define m4_set_syntax_table(C, V) ((C)->syntax = (V))
-# define m4_get_current_file(C) ((C)->current_file)
-# define m4_set_current_file(C, V) ((C)->current_file = (V))
-# define m4_get_current_line(C) ((C)->current_line)
-# define m4_set_current_line(C, V) ((C)->current_line = (V))
-# define m4_get_output_line(C) ((C)->output_line)
-# define m4_set_output_line(C, V) ((C)->output_line = (V))
-# define m4_get_debug_file(C) ((C)->debug_file)
-# define m4_set_debug_file(C, V) ((C)->debug_file = (V))
-# define m4_get_trace_messages(C) ((C)->trace_messages)
-# define m4_set_trace_messages(C, V) ((C)->trace_messages = (V))
-# define m4_get_exit_status(C) ((C)->exit_status)
-# define m4_set_exit_status(C, V) ((C)->exit_status = (V))
-# define m4_get_current_diversion(C) ((C)->current_diversion)
-# define m4_set_current_diversion(C, V) ((C)->current_diversion = (V))
-# define m4_get_nesting_limit_opt(C) ((C)->nesting_limit)
-# define m4_set_nesting_limit_opt(C, V) ((C)->nesting_limit = (V))
-# define m4_get_debug_level_opt(C) ((C)->debug_level)
-# define m4_set_debug_level_opt(C, V) ((C)->debug_level = (V))
-# define m4_get_max_debug_arg_length_opt(C) ((C)->max_debug_arg_length)
-# define m4_set_max_debug_arg_length_opt(C, V) ((C)->max_debug_arg_length=(V))
-# define m4_get_regexp_syntax_opt(C) ((C)->regexp_syntax)
-# define m4_set_regexp_syntax_opt(C, V) ((C)->regexp_syntax = (V))
-
-# define m4_get_prefix_builtins_opt(C) \
- (BIT_TEST((C)->opt_flags, M4_OPT_PREFIX_BUILTINS_BIT))
-# define m4_get_suppress_warnings_opt(C) \
- (BIT_TEST((C)->opt_flags, M4_OPT_SUPPRESS_WARN_BIT))
-# define m4_get_discard_comments_opt(C) \
- (BIT_TEST((C)->opt_flags, M4_OPT_DISCARD_COMMENTS_BIT))
-# define m4_get_interactive_opt(C) \
- (BIT_TEST((C)->opt_flags, M4_OPT_INTERACTIVE_BIT))
-# define m4_get_syncoutput_opt(C) \
- (BIT_TEST((C)->opt_flags, M4_OPT_SYNCOUTPUT_BIT))
-# define m4_get_posixly_correct_opt(C) \
- (BIT_TEST((C)->opt_flags, M4_OPT_POSIXLY_CORRECT_BIT))
-# define m4_get_fatal_warnings_opt(C) \
- (BIT_TEST((C)->opt_flags, M4_OPT_FATAL_WARN_BIT))
-# define m4_get_warnings_exit_opt(C) \
- (BIT_TEST((C)->opt_flags, M4_OPT_WARN_EXIT_BIT))
-# define m4_get_safer_opt(C) \
- (BIT_TEST((C)->opt_flags, M4_OPT_SAFER_BIT))
-
-/* No fast opt bit set macros, as they would need to evaluate their
- arguments more than once, which would subtly change their semantics. */
-#endif
-
-/* Accessors for private fields of m4, which have no function version
- exported in m4module.h. */
-#define m4__get_search_path(C) ((C)->search_path)
-
-
-/* --- BUILTIN MANAGEMENT --- */
-
-/* Internal representation of loaded builtins. */
-struct m4__builtin
-{
- /* Copied from module's BUILTIN_SYMBOL table, although builtin.flags
- can be used for additional bits beyond what is allowed for
- modules. */
- m4_builtin builtin;
- m4_module *module; /* Module that owns this builtin. */
-};
-typedef struct m4__builtin m4__builtin;
-
-extern void m4__set_symbol_value_builtin (m4_symbol_value *,
- const m4__builtin *);
-extern void m4__builtin_print (m4_obstack *, const m4__builtin *, bool,
- m4__symbol_chain **, const m4_string_pair *,
- bool);
-
-
-/* --- MODULE MANAGEMENT --- */
-
-/* Representation of a loaded m4 module. */
-struct m4_module
-{
- const char *name; /* Name of the module. */
- void *handle; /* System module handle. */
- m4__builtin *builtins; /* Sorted array of builtins. */
- m4_macro *macros; /* Unsorted array of macros. */
- size_t builtins_len; /* Number of builtins. */
- m4_module *next;
-};
-
-extern m4_module * m4__module_open (m4 *context, const char *name,
- m4_obstack *obs);
-extern m4_module * m4__module_find (m4 *context, const char *name);
-
-
-/* --- SYMBOL TABLE MANAGEMENT --- */
-
-struct m4_symbol
-{
- bool traced; /* True if this symbol is traced. */
- m4_symbol_value *value; /* Linked list of pushdef'd values. */
-};
-
-/* Type of a link in a symbol chain. */
-enum m4__symbol_chain_type
-{
- M4__CHAIN_STR, /* Link contains a string, u.u_s is valid. */
- M4__CHAIN_FUNC, /* Link contains builtin token, u.builtin is valid. */
- M4__CHAIN_ARGV, /* Link contains a $@ reference, u.u_a is valid. */
- M4__CHAIN_LOC /* Link contains m4wrap location, u.u_l is valid. */
-};
-
-/* Composite symbols are built of a linked list of chain objects. */
-struct m4__symbol_chain
-{
- m4__symbol_chain *next; /* Pointer to next link of chain. */
- enum m4__symbol_chain_type type; /* Type of this link. */
- unsigned int quote_age; /* Quote_age of this link, or 0. */
- union
- {
- struct
- {
- const char *str; /* Pointer to text. */
- size_t len; /* Remaining length of str. */
- size_t level; /* Expansion level of content, or SIZE_MAX. */
- } u_s; /* M4__CHAIN_STR. */
- const m4__builtin *builtin; /* M4__CHAIN_FUNC. */
- struct
- {
- m4_macro_args *argv; /* Reference to earlier $@. */
- size_t index; /* Argument index within argv. */
- bool_bitfield flatten : 1; /* True to treat builtins as text. */
- bool_bitfield comma : 1; /* True when `,' is next input. */
- bool_bitfield skip_last : 1; /* True if last argument omitted. */
- bool_bitfield has_func : 1; /* True if argv includes func. */
- const m4_string_pair *quotes; /* NULL for $*, quotes for $@. */
- } u_a; /* M4__CHAIN_ARGV. */
- struct
- {
- const char *file; /* File where subsequent links originate. */
- int line; /* Line where subsequent links originate. */
- } u_l; /* M4__CHAIN_LOC. */
- } u;
-};
-
-/* A symbol value is used both for values associated with a macro
- name, and for arguments to a macro invocation. */
-struct m4_symbol_value
-{
- m4_symbol_value * next;
- m4_module * module;
- unsigned int flags;
-
- m4_hash * arg_signature;
- size_t min_args;
- size_t max_args;
- size_t pending_expansions;
-
- m4__symbol_type type;
- union
- {
- struct
- {
- size_t len; /* Length of string. */
- const char * text; /* String contents. */
- /* Quote age when this string was built, or zero to force a
- rescan of the string. Ignored for 0 len. */
- unsigned int quote_age;
- } u_t; /* Valid when type is TEXT, PLACEHOLDER. */
- const m4__builtin * builtin;/* Valid when type is FUNC. */
- struct
- {
- m4__symbol_chain *chain; /* First link of the chain. */
- m4__symbol_chain *end; /* Last link of the chain. */
- bool_bitfield wrapper : 1; /* True if this is a $@ ref. */
- bool_bitfield has_func : 1; /* True if chain includes func. */
- } u_c; /* Valid when type is COMP. */
- } u;
-};
-
-/* Structure describing all arguments to a macro, including the macro
- name at index 0. */
-struct m4_macro_args
-{
- /* One more than the highest actual argument. May be larger than
- arraylen since the array can refer to multiple arguments via a
- single $@ reference. */
- size_t argc;
- /* False unless the macro expansion refers to $@; determines whether
- this object can be freed at end of macro expansion or must wait
- until all references have been rescanned. */
- bool_bitfield inuse : 1;
- /* False if all arguments are just text or func, true if this argv
- refers to another one. */
- bool_bitfield wrapper : 1;
- /* False if all arguments belong to this argv, true if some of them
- include references to another. */
- bool_bitfield has_ref : 1;
- /* True to flatten builtins contained in references. */
- bool_bitfield flatten : 1;
- /* True if any token contains builtins. */
- bool_bitfield has_func : 1;
- /* The value of quote_age for all tokens, or 0 if quote_age changed
- during parsing or any token is potentially unsafe and requires a
- rescan. */
- unsigned int quote_age;
- /* The context of the macro call during expansion, and NULL in a
- back-reference. */
- m4_call_info *info;
- size_t level; /* Which obstack owns this argv. */
- size_t arraylen; /* True length of allocated elements in array. */
- /* Used as a variable-length array, storing information about each
- argument. */
- m4_symbol_value *array[FLEXIBLE_ARRAY_MEMBER];
-};
-
-/* Internal structure for managing multiple argv references. See
- macro.c for a much more detailed comment on usage. */
-struct m4__macro_arg_stacks
-{
- size_t refcount; /* Number of active $@ references at this level. */
- size_t argcount; /* Number of argv at this level. */
- m4_obstack *args; /* Content of arguments. */
- m4_obstack *argv; /* Argv pointers into args. */
- void *args_base; /* Location for clearing the args obstack. */
- void *argv_base; /* Location for clearing the argv obstack. */
-};
-
-/* Opaque structure for managing call context information. Contains
- the context used in tracing and error messages that was valid at
- the start of the macro expansion, even if argument collection
- changes global context in the meantime. */
-struct m4_call_info
-{
- const char *file; /* The file containing the macro invocation. */
- int line; /* The line the macro was called on. */
- size_t call_id; /* The unique sequence call id of the macro. */
- int trace : 1; /* True to trace this macro. */
- int debug_level : 31; /* The debug level for tracing the macro call. */
- const char *name; /* The macro name. */
- size_t name_len; /* The length of name. */
-};
-
-extern size_t m4__adjust_refcount (m4 *, size_t, bool);
-extern bool m4__arg_adjust_refcount (m4 *, m4_macro_args *, bool);
-extern void m4__push_arg_quote (m4 *, m4_obstack *, m4_macro_args *,
- size_t, const m4_string_pair *);
-extern bool m4__arg_print (m4 *, m4_obstack *, m4_macro_args *,
- size_t, const m4_string_pair *, bool,
- m4__symbol_chain **, const char *,
- size_t *, bool, bool);
-
-#define VALUE_NEXT(T) ((T)->next)
-#define VALUE_MODULE(T) ((T)->module)
-#define VALUE_FLAGS(T) ((T)->flags)
-#define VALUE_ARG_SIGNATURE(T) ((T)->arg_signature)
-#define VALUE_MIN_ARGS(T) ((T)->min_args)
-#define VALUE_MAX_ARGS(T) ((T)->max_args)
-#define VALUE_PENDING(T) ((T)->pending_expansions)
-
-#define SYMBOL_NEXT(S) (VALUE_NEXT ((S)->value))
-#define SYMBOL_MODULE(S) (VALUE_MODULE ((S)->value))
-#define SYMBOL_FLAGS(S) (VALUE_FLAGS ((S)->value))
-#define SYMBOL_ARG_SIGNATURE(S) (VALUE_ARG_SIGNATURE ((S)->value))
-#define SYMBOL_MIN_ARGS(S) (VALUE_MIN_ARGS ((S)->value))
-#define SYMBOL_MAX_ARGS(S) (VALUE_MAX_ARGS ((S)->value))
-#define SYMBOL_PENDING(S) (VALUE_PENDING ((S)->value))
-
-/* Fast macro versions of symbol table accessor functions,
- that also have an identically named function exported in m4module.h. */
-#ifdef NDEBUG
-# define m4_get_symbol_traced(S) ((S)->traced)
-# define m4_get_symbol_value(S) ((S)->value)
-# define m4_set_symbol_value(S, V) ((S)->value = (V))
-
-/* m4_symbol_value_{create,delete} are too complex for a simple macro. */
-
-# define m4_is_symbol_value_text(V) ((V)->type == M4_SYMBOL_TEXT)
-# define m4_is_symbol_value_func(V) ((V)->type == M4_SYMBOL_FUNC)
-# define m4_is_symbol_value_void(V) ((V)->type == M4_SYMBOL_VOID)
-# define m4_is_symbol_value_placeholder(V) \
- ((V)->type == M4_SYMBOL_PLACEHOLDER)
-# define m4_get_symbol_value_text(V) ((V)->u.u_t.text)
-# define m4_get_symbol_value_len(V) ((V)->u.u_t.len)
-# define m4_get_symbol_value_quote_age(V) ((V)->u.u_t.quote_age)
-# define m4_get_symbol_value_func(V) ((V)->u.builtin->builtin.func)
-# define m4_get_symbol_value_builtin(V) (&(V)->u.builtin->builtin)
-# define m4_get_symbol_value_placeholder(V) \
- ((V)->u.u_t.text)
-# define m4_symbol_value_flatten_args(V) \
- (BIT_TEST ((V)->flags, VALUE_FLATTEN_ARGS_BIT))
-
-# define m4_set_symbol_value_text(V, T, L, A) \
- ((V)->type = M4_SYMBOL_TEXT, (V)->u.u_t.text = (T), \
- (V)->u.u_t.len = (L), (V)->u.u_t.quote_age = (A))
-# define m4_set_symbol_value_placeholder(V, T) \
- ((V)->type = M4_SYMBOL_PLACEHOLDER, (V)->u.u_t.text = (T))
-# define m4__set_symbol_value_builtin(V, B) \
- ((V)->type = M4_SYMBOL_FUNC, (V)->u.builtin = (B), \
- VALUE_MODULE (V) = (B)->module, \
- VALUE_FLAGS (V) = (B)->builtin.flags, \
- VALUE_MIN_ARGS (V) = (B)->builtin.min_args, \
- VALUE_MAX_ARGS (V) = (B)->builtin.max_args)
-#endif
-
-
-
-/* m4_symbol_value.flags bit masks. Be sure these are a consistent
- superset of the M4_BUILTIN_* bit masks, so we can copy
- m4_builtin.flags to m4_symbol_arg.flags. We can use additional
- bits for private use. */
-
-#define VALUE_FLATTEN_ARGS_BIT (1 << 0)
-#define VALUE_BLIND_ARGS_BIT (1 << 1)
-#define VALUE_SIDE_EFFECT_ARGS_BIT (1 << 2)
-#define VALUE_DELETED_BIT (1 << 3)
-
-
-struct m4_symbol_arg {
- int index;
- int flags;
- char * default_val;
-};
-
-#define SYMBOL_ARG_INDEX(A) ((A)->index)
-#define SYMBOL_ARG_FLAGS(A) ((A)->flags)
-#define SYMBOL_ARG_DEFAULT(A) ((A)->default_val)
-
-/* m4_symbol_arg.flags bit masks: */
-
-#define SYMBOL_ARG_REST_BIT (1 << 0)
-#define SYMBOL_ARG_KEY_BIT (1 << 1)
-
-extern void m4__symtab_remove_module_references (m4_symbol_table *,
- m4_module *);
-extern bool m4__symbol_value_print (m4 *, m4_symbol_value *, m4_obstack *,
- const m4_string_pair *, bool,
- m4__symbol_chain **, size_t *, bool);
-
-
-
-/* --- SYNTAX TABLE MANAGEMENT --- */
-
-/* CHAR_RETRY must be last, because we size the syntax table to hold
- all other characters and sentinels. */
-#define CHAR_EOF (UCHAR_MAX + 1) /* Return on EOF. */
-#define CHAR_BUILTIN (UCHAR_MAX + 2) /* Return for BUILTIN token. */
-#define CHAR_QUOTE (UCHAR_MAX + 3) /* Return for quoted string. */
-#define CHAR_ARGV (UCHAR_MAX + 4) /* Return for $@ reference. */
-#define CHAR_RETRY (UCHAR_MAX + 5) /* Return for end of input block. */
-
-#define DEF_LQUOTE "`" /* Default left quote delimiter. */
-#define DEF_RQUOTE "\'" /* Default right quote delimiter. */
-#define DEF_BCOMM "#" /* Default begin comment delimiter. */
-#define DEF_ECOMM "\n" /* Default end comment delimiter. */
-
-struct m4_syntax_table {
- /* Please read the comment at the top of input.c for details. table
- holds the current syntax, and orig holds the default syntax. */
- unsigned short table[CHAR_RETRY];
- unsigned short orig[CHAR_RETRY];
-
- m4_string_pair quote; /* Quote delimiters. */
- m4_string_pair comm; /* Comment delimiters. */
-
- char dollar; /* Dollar character, if is_single_dollar. */
-
- /* True iff only one start and end quote delimiter exist. */
- bool_bitfield is_single_quotes : 1;
-
- /* True iff only one start and end comment delimiter exist. */
- bool_bitfield is_single_comments : 1;
-
- /* True iff only one byte has M4_SYNTAX_DOLLAR. */
- bool_bitfield is_single_dollar : 1;
-
- /* True iff some character has M4_SYNTAX_ESCAPE. */
- bool_bitfield is_macro_escaped : 1;
-
- /* True iff a changesyntax call has impacted something that requires
- cleanup at the end. */
- bool_bitfield suspect : 1;
-
- /* Track the number of changesyntax calls. This saturates at
- 0xffff, so the idea is that most users won't be changing the
- syntax that frequently; perhaps in the future we will cache
- frequently used syntax schemes by index. */
- unsigned short syntax_age;
-
- /* Track the current quote age, determined by all significant
- changequote, changecom, and changesyntax calls, since any of
- these can alter the rescan of a prior parameter in a quoted
- context. */
- unsigned int quote_age;
-
- /* Track a cached quote pair on the input obstack. */
- m4_string_pair *cached_quote;
-
- /* Storage for a simple cached quote that can be recreated on the fly. */
- char cached_lquote[2];
- char cached_rquote[2];
- m4_string_pair cached_simple;
-};
-
-/* Fast macro versions of syntax table accessor functions,
- that also have an identically named function exported in m4module.h. */
-#ifdef NDEBUG
-# define m4_get_syntax_lquote(S) ((S)->quote.str1)
-# define m4_get_syntax_rquote(S) ((S)->quote.str2)
-# define m4_get_syntax_bcomm(S) ((S)->comm.str1)
-# define m4_get_syntax_ecomm(S) ((S)->comm.str2)
-# define m4_get_syntax_quotes(S) (&(S)->quote)
-# define m4_get_syntax_comments(S) (&(S)->comm)
-
-# define m4_is_syntax_single_quotes(S) ((S)->is_single_quotes)
-# define m4_is_syntax_single_comments(S) ((S)->is_single_comments)
-# define m4_is_syntax_single_dollar(S) ((S)->is_single_dollar)
-# define m4_is_syntax_macro_escaped(S) ((S)->is_macro_escaped)
-#endif
-
-/* Return the current quote age. */
-#define m4__quote_age(S) ((S)->quote_age)
-
-/* Return true if the current quote age guarantees that parsing the
- current token in the context of a quoted string of the same quote
- age will give the same parse. */
-#define m4__safe_quotes(S) (((S)->quote_age & 0xffff) != 0)
-
-/* Set or refresh the cached quote. */
-extern const m4_string_pair *m4__quote_cache (m4_syntax_table *,
- m4_obstack *obs, unsigned int,
- const m4_string_pair *);
-
-/* Clear the cached quote. */
-#define m4__quote_uncache(S) ((S)->cached_quote = NULL)
-
-
-/* --- MACRO MANAGEMENT --- */
-
-/* Various different token types. */
-typedef enum {
- M4_TOKEN_EOF, /* End of file, M4_SYMBOL_VOID. */
- M4_TOKEN_NONE, /* Discardable token, M4_SYMBOL_VOID. */
- M4_TOKEN_STRING, /* Quoted string, M4_SYMBOL_TEXT or M4_SYMBOL_COMP. */
- M4_TOKEN_COMMENT, /* Comment, M4_SYMBOL_TEXT or M4_SYMBOL_COMP. */
- M4_TOKEN_SPACE, /* Whitespace, M4_SYMBOL_TEXT. */
- M4_TOKEN_WORD, /* An identifier, M4_SYMBOL_TEXT. */
- M4_TOKEN_OPEN, /* Argument list start, M4_SYMBOL_TEXT. */
- M4_TOKEN_COMMA, /* Argument separator, M4_SYMBOL_TEXT. */
- M4_TOKEN_CLOSE, /* Argument list end, M4_SYMBOL_TEXT. */
- M4_TOKEN_SIMPLE, /* Single character, M4_SYMBOL_TEXT. */
- M4_TOKEN_MACDEF, /* Builtin token, M4_SYMBOL_FUNC or M4_SYMBOL_COMP. */
- M4_TOKEN_ARGV /* A series of parameters, M4_SYMBOL_COMP. */
-} m4__token_type;
-
-extern void m4__make_text_link (m4_obstack *, m4__symbol_chain **,
- m4__symbol_chain **);
-extern void m4__append_builtin (m4_obstack *, const m4__builtin *,
- m4__symbol_chain **,
- m4__symbol_chain **);
-extern bool m4__push_symbol (m4 *, m4_symbol_value *, size_t,
- bool);
-extern m4_obstack *m4__push_wrapup_init (m4 *, const m4_call_info *,
- m4__symbol_chain ***);
-extern void m4__push_wrapup_finish (void);
-extern m4__token_type m4__next_token (m4 *, m4_symbol_value *, int *,
- m4_obstack *, bool,
- const m4_call_info *);
-extern bool m4__next_token_is_open (m4 *);
-
-/* Fast macro versions of macro argv accessor functions,
- that also have an identically named function exported in m4module.h. */
-#ifdef NDEBUG
-# define m4_arg_argc(A) (A)->argc
-# define m4_arg_info(A) (A)->info
-# define m4_arg_scratch(C) \
- ((C)->arg_stacks[(C)->expansion_level - 1].argv)
-#endif /* NDEBUG */
-
-
-/* --- PATH MANAGEMENT --- */
-
-typedef struct m4__search_path m4__search_path;
-
-struct m4__search_path {
- m4__search_path *next; /* next directory to search */
- const char *dir; /* directory */
- int len;
-};
-
-struct m4__search_path_info {
- m4__search_path *list; /* the list of path directories */
- m4__search_path *list_end; /* the end of same */
- int max_length; /* length of longest directory name */
-};
-
-extern void m4__include_init (m4 *);
-
-
-/* Debugging the memory allocator. */
-
-#if WITH_DMALLOC
-# define DMALLOC_FUNC_CHECK
-# include <dmalloc.h>
-#endif /* WITH_DMALLOC */
-
-
-
-/* Convenience macro to zero a variable after freeing it, as well as
- casting away any const. */
-#define DELETE(Expr) ((Expr) = (free ((void *) (Expr)), (void *) 0))
-
-/* Avoid negative logic when comparing two strings. */
-#define STREQ(a, b) (strcmp (a, b) == 0)
-#define STRNEQ(a, b) (strcmp (a, b) != 0)
-
-
-#if DEBUG
-# define DEBUG_INCL 1
-# define DEBUG_INPUT 1
-# define DEBUG_MACRO 1
-# define DEBUG_MODULES 1
-# define DEBUG_OUTPUT 1
-# define DEBUG_STKOVF 1
-# define DEBUG_SYM 1
-# define DEBUG_SYNTAX 1
-#endif
-
-#endif /* m4private.h */
diff --git a/m4/macro.c b/m4/macro.c
deleted file mode 100644
index ce2675b2..00000000
--- a/m4/macro.c
+++ /dev/null
@@ -1,1784 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2001, 2006-2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* This file contains the functions that perform the basic argument
- parsing and macro expansion. */
-
-#include <config.h>
-
-#include "m4private.h"
-
-/* Define this to 1 see runtime debug info. Implied by DEBUG. */
-/*#define DEBUG_INPUT 1 */
-#ifndef DEBUG_MACRO
-# define DEBUG_MACRO 0
-#endif /* DEBUG_MACRO */
-
-/* A note on argument memory lifetimes: We use an internal struct
- (m4__macro_args_stacks) to maintain list of argument obstacks.
- Within a recursion level, consecutive macros can share a stack, but
- distinct recursion levels need different stacks since the nested
- macro is interrupting the argument collection of the outer level.
- Note that a reference can live as long as the expansion containing
- the reference can participate as an argument in a future macro
- call.
-
- Therefore, we implement a reference counter for each expansion
- level, tracking how many references exist into the obstack, as well
- as associate a level with each reference. Of course, expand_macro
- is actively using argv, so it increments the refcount on entry and
- decrements it on exit. Additionally, any time the input engine is
- handed a reference that it does not inline, it increases the
- refcount in push_token, then decreases it in pop_input once the
- reference has been rescanned. Finally, when the input engine hands
- a reference back to expand_argument, the refcount increases, which
- is then cleaned up at the end of expand_macro.
-
- For a running example, consider this input:
-
- define(a,A)define(b,`a(`$1')')define(c,$*)dnl
- define(x,`a(1)`'c($@')define(y,`$@)')dnl
- x(a(`b')``a'')y(`b')(`a')
- => AAaA
-
- Assuming all arguments are large enough to exceed the inlining
- thresholds of the input engine, the interesting sequence of events
- is as follows:
-
- stacks[0] refs stacks[1] refs
- after second dnl ends: `' 0 `' 0
- expand_macro for x, level 0: `' 1 `' 0
- expand_macro for a, level 1: `' 1 `' 1
- after collect_arguments for a: `' 1 `b' 1
- push `A' to input stack: `' 1 `b' 1
- exit expand_macro for a: `' 1 `' 0
- after collect_arguments for x: `A`a'' 1 `' 0
- push `a(1)`'c(' to input stack: `A`a'' 1 `' 0
- push_token saves $@(x) ref: `A`a'' 2 `' 0
- exit expand_macro for x: `A`a'' 1 `' 0
- expand_macro for a, level 0: `A`a'' 2 `' 0
- after collect_arguments for a: `A`a''`1' 2 `' 0
- push `A' to input stack: `A`a''`1' 2 `' 0
- exit expand_macro for a: `A`a'' 1 `' 0
- output `A': `A`a'' 1 `' 0
- expand_macro for c, level 0: `A`a'' 2 `' 0
- expand_argument gets $@(x) ref: `A`a''`$@(x)' 3 `' 0
- pop_input ends $@(x) ref: `A`a''`$@(x)' 2 `' 0
- expand_macro for y, level 1: `A`a''`$@(x)' 2 `' 1
- after collect_arguments for y: `A`a''`$@(x)' 2 `b' 1
- push_token saves $@(y) ref: `A`a''`$@(x)' 2 `b' 2
- push `)' to input stack: `A`a''`$@(x)' 2 `b' 2
- exit expand_macro for y: `A`a''`$@(x)' 2 `b' 1
- expand_argument gets $@(y) ref: `A`a''`$@(x)$@(y)' 2 `b' 2
- pop_input ends $@(y) ref: `A`a''`$@(x)$@(y)' 2 `b' 1
- after collect_arguments for c: `A`a''`$@(x)$@(y)' 2 `b' 1
- push_token saves $*(c) ref: `A`a''`$@(x)$@(y)' 3 `b' 2
- expand_macro frees $@(x) ref: `A`a''`$@(x)$@(y)' 2 `b' 2
- expand_macro frees $@(y) ref: `A`a''`$@(x)$@(y)' 2 `b' 1
- exit expand_macro for c: `A`a''`$@(x)$@(y)' 1 `b' 1
- output `Aa': `A`a''`$@(x)$@(y)' 0 `b' 1
- pop_input ends $*(c)$@(x) ref: `' 0 `b' 1
- expand_macro for b, level 0: `' 1 `b' 1
- pop_input ends $*(c)$@(y) ref: `' 1 `' 0
- after collect_arguments for b: `a' 1 `' 0
- push `a(`' to input stack: `a' 1 `' 0
- push_token saves $1(b) ref: `a' 2 `' 0
- push `')' to input stack: `a' 2 `' 0
- exit expand_macro for b: `a' 1 `' 0
- expand_macro for a, level 0 : `a' 2 `' 0
- expand_argument gets $1(b) ref: `a'`$1(b)' 3 `' 0
- pop_input ends $1(b) ref: `a'`$1(b)' 2 `' 0
- after collect_arguments for a: `a'`$1(b)' 2 `' 0
- push `A' to input stack: `a'`$1(b)' 2 `' 0
- expand_macro frees $1(b) ref: `a'`$1(b)' 1 `' 0
- exit expand_macro for a: `' 0 `' 0
- output `A': `' 0 `' 0
-
- An obstack is only completely cleared when its refcount reaches
- zero. However, as an optimization, expand_macro also frees
- anything that it added to the obstack if no additional references
- were added at the current expansion level, to reduce the amount of
- memory left on the obstack while waiting for refcounts to drop.
-*/
-
-static m4_macro_args *collect_arguments (m4 *, m4_call_info *, m4_symbol *,
- m4_obstack *, m4_obstack *);
-static void expand_macro (m4 *, const char *, size_t, m4_symbol *);
-static bool expand_token (m4 *, m4_obstack *, m4__token_type,
- m4_symbol_value *, int, bool);
-static bool expand_argument (m4 *, m4_obstack *, m4_symbol_value *,
- const m4_call_info *);
-static void process_macro (m4 *, m4_symbol_value *, m4_obstack *, int,
- m4_macro_args *);
-
-static unsigned int trace_pre (m4 *, m4_macro_args *);
-static void trace_post (m4 *, unsigned int, const m4_call_info *);
-static unsigned int trace_header (m4 *, const m4_call_info *);
-static void trace_flush (m4 *, unsigned int);
-
-
-/* The number of the current call of expand_macro (). */
-static size_t macro_call_id = 0;
-
-/* A placeholder symbol value representing the empty string, used to
- optimize checks for emptiness. */
-static m4_symbol_value empty_symbol;
-
-#if DEBUG_MACRO
-/* True if significant changes to stacks should be printed to the
- trace stream. Primarily useful for debugging $@ ref memory leaks,
- and controlled by M4_DEBUG_MACRO environment variable. */
-static int debug_macro_level;
-#else
-# define debug_macro_level 0
-#endif /* !DEBUG_MACRO */
-#define PRINT_ARGCOUNT_CHANGES 1 /* Any change to argcount > 1. */
-#define PRINT_REFCOUNT_INCREASE 2 /* Any increase to refcount. */
-#define PRINT_REFCOUNT_DECREASE 4 /* Any decrease to refcount. */
-
-
-
-/* This function reads all input, and expands each token, one at a time. */
-void
-m4_macro_expand_input (m4 *context)
-{
- m4__token_type type;
- m4_symbol_value token;
- int line;
-
-#if DEBUG_MACRO
- const char *s = getenv ("M4_DEBUG_MACRO");
- if (s)
- debug_macro_level = strtol (s, NULL, 0);
-#endif /* DEBUG_MACRO */
-
- m4_set_symbol_value_text (&empty_symbol, "", 0, 0);
- VALUE_MAX_ARGS (&empty_symbol) = -1;
-
- while ((type = m4__next_token (context, &token, &line, NULL, false, NULL))
- != M4_TOKEN_EOF)
- expand_token (context, NULL, type, &token, line, true);
-}
-
-
-/* Expand one token onto OBS, according to its type. If OBS is NULL,
- output the expansion to the current diversion. TYPE determines the
- contents of TOKEN. Potential macro names (a TYPE of M4_TOKEN_WORD)
- are looked up in the symbol table, to see if they have a macro
- definition. If they have, they are expanded as macros, otherwise
- the text are just copied to the output. LINE determines where
- TOKEN began. FIRST is true if there is no prior content in the
- current macro argument. Return true if the result is guranteed to
- give the same parse on rescan in a quoted context with the same
- quote age. Returning false is always safe, although it may lead to
- slower performance. */
-static bool
-expand_token (m4 *context, m4_obstack *obs, m4__token_type type,
- m4_symbol_value *token, int line, bool first)
-{
- m4_symbol *symbol;
- bool result = false;
- const char *text = (m4_is_symbol_value_text (token)
- ? m4_get_symbol_value_text (token) : NULL);
-
- switch (type)
- { /* TOKSW */
- case M4_TOKEN_EOF:
- case M4_TOKEN_MACDEF:
- /* Always safe, since there is no text to rescan. */
- return true;
-
- case M4_TOKEN_STRING:
- /* Strings are safe in isolation (since quote_age detects any
- change in delimiters), or when safe_quotes is true. This is
- also returned for sequences of benign characters, such as
- digits. When safe_quotes is false, we could technically
- return true if we can prove that the concatenation of this
- string to prior text does not form a multi-byte quote
- delimiter, but that is a lot of overhead, so we give the
- conservative answer of false. */
- result = first || m4__safe_quotes (M4SYNTAX);
- /* fallthru */
- case M4_TOKEN_COMMENT:
- /* Comments can contain unbalanced quote delimiters. Rather
- than search for one, we return the conservative answer of
- false. If obstack is provided, the string or comment was
- already expanded into it during next_token. */
- if (obs)
- return result;
- break;
-
- case M4_TOKEN_OPEN:
- case M4_TOKEN_COMMA:
- case M4_TOKEN_CLOSE:
- case M4_TOKEN_SPACE:
- /* If safe_quotes is true, then these do not form a quote
- delimiter. If it is false, we give the conservative answer
- of false rather than taking time to prove that no multi-byte
- quote delimiter is formed. */
- result = m4__safe_quotes (M4SYNTAX);
- break;
-
- case M4_TOKEN_SIMPLE:
- /* If safe_quotes is true, then all but the single-byte end
- quote delimiter is safe in a quoted context; a single-byte
- start delimiter will trigger M4_TOKEN_STRING instead. If
- safe_quotes is false, we give the conservative answer of
- false rather than taking time to prove that no multi-byte
- quote delimiter is formed. */
- result = (!m4_has_syntax (M4SYNTAX, *text, M4_SYNTAX_RQUOTE)
- && m4__safe_quotes (M4SYNTAX));
- if (result)
- assert (!m4_has_syntax (M4SYNTAX, *text, M4_SYNTAX_LQUOTE));
- break;
-
- case M4_TOKEN_WORD:
- {
- const char *textp = text;
- size_t len = m4_get_symbol_value_len (token);
- size_t len2 = len;
-
- if (m4_has_syntax (M4SYNTAX, *textp, M4_SYNTAX_ESCAPE))
- {
- textp++;
- len2--;
- }
-
- symbol = m4_symbol_lookup (M4SYMTAB, textp, len2);
- assert (!symbol || !m4_is_symbol_void (symbol));
- if (symbol == NULL
- || (symbol->value->type == M4_SYMBOL_FUNC
- && BIT_TEST (SYMBOL_FLAGS (symbol), VALUE_BLIND_ARGS_BIT)
- && !m4__next_token_is_open (context)))
- {
- m4_divert_text (context, obs, text, len, line);
- /* If safe_quotes is true, then words do not overlap with
- quote delimiters. If it is false, we give the
- conservative answer of false rather than prove that no
- multi-byte delimiters are formed. */
- return m4__safe_quotes (M4SYNTAX);
- }
- expand_macro (context, textp, len2, symbol);
- /* Expanding a macro may create new tokens to scan, and those
- tokens may generate unsafe text, but we did not append any
- text now. */
- return true;
- }
-
- default:
- assert (!"INTERNAL ERROR: bad token type in expand_token ()");
- abort ();
- }
- m4_divert_text (context, obs, text, m4_get_symbol_value_len (token), line);
- return result;
-}
-
-
-/* This function parses one argument to a macro call. It expects the
- first left parenthesis or the separating comma to have been read by
- the caller. It skips leading whitespace, then reads and expands
- tokens, until it finds a comma or a right parenthesis at the same
- level of parentheses. It returns a flag indicating whether the
- argument read is the last for the active macro call. The arguments
- are built on the obstack OBS, indirectly through expand_token ().
- Report errors on behalf of CALLER. */
-static bool
-expand_argument (m4 *context, m4_obstack *obs, m4_symbol_value *argp,
- const m4_call_info *caller)
-{
- m4__token_type type;
- m4_symbol_value token;
- int paren_level = 0;
- int line = m4_get_current_line (context);
- size_t len;
- unsigned int age = m4__quote_age (M4SYNTAX);
- bool first = true;
-
- memset (argp, '\0', sizeof *argp);
- VALUE_MAX_ARGS (argp) = -1;
-
- /* Skip leading white space. */
- do
- {
- type = m4__next_token (context, &token, NULL, obs, true, caller);
- }
- while (type == M4_TOKEN_SPACE);
-
- while (1)
- {
- if (VALUE_MIN_ARGS (argp) < VALUE_MIN_ARGS (&token))
- VALUE_MIN_ARGS (argp) = VALUE_MIN_ARGS (&token);
- if (VALUE_MAX_ARGS (&token) < VALUE_MAX_ARGS (argp))
- VALUE_MAX_ARGS (argp) = VALUE_MAX_ARGS (&token);
- switch (type)
- { /* TOKSW */
- case M4_TOKEN_COMMA:
- case M4_TOKEN_CLOSE:
- if (paren_level == 0)
- {
- assert (argp->type != M4_SYMBOL_FUNC);
- if (argp->type != M4_SYMBOL_COMP)
- {
- len = obstack_object_size (obs);
- VALUE_MODULE (argp) = NULL;
- if (len)
- {
- obstack_1grow (obs, '\0');
- m4_set_symbol_value_text (argp, obstack_finish (obs),
- len, age);
- }
- else
- m4_set_symbol_value_text (argp, "", len, 0);
- }
- else
- {
- m4__make_text_link (obs, NULL, &argp->u.u_c.end);
- if (argp->u.u_c.chain == argp->u.u_c.end
- && argp->u.u_c.chain->type == M4__CHAIN_FUNC)
- {
- const m4__builtin *func = argp->u.u_c.chain->u.builtin;
- argp->type = M4_SYMBOL_FUNC;
- argp->u.builtin = func;
- }
- }
- return type == M4_TOKEN_COMMA;
- }
- /* fallthru */
- case M4_TOKEN_OPEN:
- case M4_TOKEN_SIMPLE:
- if (type == M4_TOKEN_OPEN)
- paren_level++;
- else if (type == M4_TOKEN_CLOSE)
- paren_level--;
- if (!expand_token (context, obs, type, &token, line, first))
- age = 0;
- break;
-
- case M4_TOKEN_EOF:
- m4_error (context, EXIT_FAILURE, 0, caller,
- _("end of file in argument list"));
- break;
-
- case M4_TOKEN_WORD:
- case M4_TOKEN_SPACE:
- case M4_TOKEN_STRING:
- case M4_TOKEN_COMMENT:
- case M4_TOKEN_MACDEF:
- if (!expand_token (context, obs, type, &token, line, first))
- age = 0;
- if (token.type == M4_SYMBOL_COMP)
- {
- if (argp->type != M4_SYMBOL_COMP)
- {
- argp->type = M4_SYMBOL_COMP;
- argp->u.u_c.chain = token.u.u_c.chain;
- argp->u.u_c.wrapper = argp->u.u_c.has_func = false;
- }
- else
- {
- assert (argp->u.u_c.end);
- argp->u.u_c.end->next = token.u.u_c.chain;
- }
- argp->u.u_c.end = token.u.u_c.end;
- if (token.u.u_c.has_func)
- argp->u.u_c.has_func = true;
- }
- break;
-
- case M4_TOKEN_ARGV:
- assert (paren_level == 0 && argp->type == M4_SYMBOL_VOID
- && obstack_object_size (obs) == 0
- && token.u.u_c.chain == token.u.u_c.end
- && token.u.u_c.chain->quote_age == age
- && token.u.u_c.chain->type == M4__CHAIN_ARGV);
- argp->type = M4_SYMBOL_COMP;
- argp->u.u_c.chain = argp->u.u_c.end = token.u.u_c.chain;
- argp->u.u_c.wrapper = true;
- argp->u.u_c.has_func = token.u.u_c.has_func;
- type = m4__next_token (context, &token, NULL, NULL, false, caller);
- if (argp->u.u_c.chain->u.u_a.skip_last)
- assert (type == M4_TOKEN_COMMA);
- else
- assert (type == M4_TOKEN_COMMA || type == M4_TOKEN_CLOSE);
- return type == M4_TOKEN_COMMA;
-
- default:
- assert (!"expand_argument");
- abort ();
- }
-
- if (argp->type != M4_SYMBOL_VOID || obstack_object_size (obs))
- first = false;
- type = m4__next_token (context, &token, NULL, obs, first, caller);
- }
-}
-
-
-/* The macro expansion is handled by expand_macro (). It parses the
- arguments, using collect_arguments (), and builds a table of pointers to
- the arguments. The arguments themselves are stored on a local obstack.
- Expand_macro () uses m4_macro_call () to do the call of the macro.
-
- Expand_macro () is potentially recursive, since it calls expand_argument
- (), which might call expand_token (), which might call expand_macro ().
-
- NAME points to storage on the token stack, so it is only valid
- until a call to collect_arguments parses more tokens. SYMBOL is
- the result of the symbol table lookup on NAME. */
-static void
-expand_macro (m4 *context, const char *name, size_t len, m4_symbol *symbol)
-{
- void *args_base; /* Base of stack->args on entry. */
- void *args_scratch; /* Base of scratch space for m4_macro_call. */
- void *argv_base; /* Base of stack->argv on entry. */
- m4_macro_args *argv; /* Arguments to the called macro. */
- m4_obstack *expansion; /* Collects the macro's expansion. */
- m4_symbol_value *value; /* Original value of this macro. */
- size_t level; /* Expansion level of this macro. */
- m4__macro_arg_stacks *stack; /* Storage for this macro. */
- m4_call_info info; /* Context of this macro call. */
-
- /* Obstack preparation. */
- level = context->expansion_level;
- if (context->stacks_count <= level)
- {
- size_t count = context->stacks_count;
- context->arg_stacks
- = (m4__macro_arg_stacks *) x2nrealloc (context->arg_stacks,
- &context->stacks_count,
- sizeof *context->arg_stacks);
- memset (&context->arg_stacks[count], 0,
- sizeof *context->arg_stacks * (context->stacks_count - count));
- }
- stack = &context->arg_stacks[level];
- if (!stack->args)
- {
- assert (!stack->refcount);
- stack->args = (m4_obstack *) xmalloc (sizeof *stack->args);
- stack->argv = (m4_obstack *) xmalloc (sizeof *stack->argv);
- obstack_init (stack->args);
- obstack_init (stack->argv);
- stack->args_base = obstack_finish (stack->args);
- stack->argv_base = obstack_finish (stack->argv);
- }
- assert (obstack_object_size (stack->args) == 0
- && obstack_object_size (stack->argv) == 0);
- args_base = obstack_finish (stack->args);
- argv_base = obstack_finish (stack->argv);
- m4__adjust_refcount (context, level, true);
- stack->argcount++;
-
- /* Grab the current value of this macro, because it may change while
- collecting arguments. Likewise, grab any state needed during
- tracing. */
- value = m4_get_symbol_value (symbol);
- info.file = m4_get_current_file (context);
- info.line = m4_get_current_line (context);
- info.call_id = ++macro_call_id;
- info.trace = (m4_is_debug_bit (context, M4_DEBUG_TRACE_ALL)
- || m4_get_symbol_traced (symbol));
- info.debug_level = m4_get_debug_level_opt (context);
- info.name = name;
- info.name_len = len;
-
- /* Prepare for macro expansion. */
- VALUE_PENDING (value)++;
- if (m4_get_nesting_limit_opt (context) < ++context->expansion_level)
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-recursion limit of %zu exceeded, use -L<N> to change it"),
- m4_get_nesting_limit_opt (context));
-
- m4_trace_prepare (context, &info, value);
- argv = collect_arguments (context, &info, symbol, stack->args, stack->argv);
- /* Since collect_arguments can invalidate stack by reallocating
- context->arg_stacks during a recursive expand_macro call, we must
- reset it here. */
- stack = &context->arg_stacks[level];
- args_scratch = obstack_finish (stack->args);
-
- /* The actual macro call. */
- expansion = m4_push_string_init (context, info.file, info.line);
- m4_macro_call (context, value, expansion, argv);
- m4_push_string_finish ();
-
- /* Cleanup. */
- argv->info = NULL;
-
- --context->expansion_level;
- --VALUE_PENDING (value);
- if (BIT_TEST (VALUE_FLAGS (value), VALUE_DELETED_BIT))
- m4_symbol_value_delete (value);
-
- /* We no longer need argv, so reduce the refcount. Additionally, if
- no other references to argv were created, we can free our portion
- of the obstack, although we must leave earlier content alone. A
- refcount of 0 implies that adjust_refcount already freed the
- entire stack. */
- m4__arg_adjust_refcount (context, argv, false);
- if (stack->refcount)
- {
- if (argv->inuse)
- {
- obstack_free (stack->args, args_scratch);
- if (debug_macro_level & PRINT_ARGCOUNT_CHANGES)
- xfprintf (stderr, "m4debug: -%zu- `%s' in use, level=%zu, "
- "refcount=%zu, argcount=%zu\n", info.call_id,
- argv->info->name, level, stack->refcount,
- stack->argcount);
- }
- else
- {
- obstack_free (stack->args, args_base);
- obstack_free (stack->argv, argv_base);
- stack->argcount--;
- }
- }
-}
-
-/* Collect all the arguments to a call of the macro SYMBOL, with call
- context INFO. The arguments are stored on the obstack ARGUMENTS
- and a table of pointers to the arguments on ARGV_STACK. Return the
- object describing all of the macro arguments. */
-static m4_macro_args *
-collect_arguments (m4 *context, m4_call_info *info, m4_symbol *symbol,
- m4_obstack *arguments, m4_obstack *argv_stack)
-{
- m4_symbol_value token;
- m4_symbol_value *tokenp;
- bool more_args;
- m4_macro_args args;
- m4_macro_args *argv;
-
- args.argc = 1;
- args.inuse = false;
- args.wrapper = false;
- args.has_ref = false;
- args.flatten = m4_symbol_flatten_args (symbol);
- args.has_func = false;
- /* Must copy here, since we are consuming tokens, and since symbol
- table can be changed during argument collection. */
- info->name = (char *) obstack_copy0 (arguments, info->name, info->name_len);
- args.quote_age = m4__quote_age (M4SYNTAX);
- args.info = info;
- args.level = context->expansion_level - 1;
- args.arraylen = 0;
- obstack_grow (argv_stack, &args, offsetof (m4_macro_args, array));
-
- if (m4__next_token_is_open (context))
- {
- /* Gobble parenthesis, then collect arguments. */
- m4__next_token (context, &token, NULL, NULL, false, info);
- do
- {
- tokenp = (m4_symbol_value *) obstack_alloc (arguments,
- sizeof *tokenp);
- more_args = expand_argument (context, arguments, tokenp, info);
-
- if ((m4_is_symbol_value_text (tokenp)
- && !m4_get_symbol_value_len (tokenp))
- || (args.flatten && m4_is_symbol_value_func (tokenp)))
- {
- obstack_free (arguments, tokenp);
- tokenp = &empty_symbol;
- }
- obstack_ptr_grow (argv_stack, tokenp);
- args.arraylen++;
- args.argc++;
- switch (tokenp->type)
- {
- case M4_SYMBOL_TEXT:
- /* Be conservative - any change in quoting while
- collecting arguments, or any unsafe argument, will
- require a rescan if $@ is reused. */
- if (m4_get_symbol_value_len (tokenp)
- && m4_get_symbol_value_quote_age (tokenp) != args.quote_age)
- args.quote_age = 0;
- break;
- case M4_SYMBOL_FUNC:
- args.has_func = true;
- break;
- case M4_SYMBOL_COMP:
- args.has_ref = true;
- if (tokenp->u.u_c.wrapper)
- {
- assert (tokenp->u.u_c.chain->type == M4__CHAIN_ARGV
- && !tokenp->u.u_c.chain->next);
- args.argc += (tokenp->u.u_c.chain->u.u_a.argv->argc
- - tokenp->u.u_c.chain->u.u_a.index
- - tokenp->u.u_c.chain->u.u_a.skip_last - 1);
- args.wrapper = true;
- }
- if (tokenp->u.u_c.has_func)
- args.has_func = true;
- break;
- default:
- assert (!"expand_argument");
- abort ();
- }
- }
- while (more_args);
- }
- argv = (m4_macro_args *) obstack_finish (argv_stack);
- argv->argc = args.argc;
- argv->wrapper = args.wrapper;
- argv->has_ref = args.has_ref;
- argv->has_func = args.has_func;
- if (args.quote_age != m4__quote_age (M4SYNTAX))
- argv->quote_age = 0;
- argv->arraylen = args.arraylen;
- return argv;
-}
-
-
-/* The actual call of a macro is handled by m4_macro_call ().
- m4_macro_call () is passed a symbol VALUE, whose type is used to
- call either a builtin function, or the user macro expansion
- function process_macro (). The arguments are provided by the ARGV
- table. The expansion is left on the obstack EXPANSION. Macro
- tracing is also handled here. */
-void
-m4_macro_call (m4 *context, m4_symbol_value *value, m4_obstack *expansion,
- m4_macro_args *argv)
-{
- unsigned int trace_start = 0;
-
- if (argv->info->trace)
- trace_start = trace_pre (context, argv);
- if (!m4_bad_argc (context, argv->argc, argv->info,
- VALUE_MIN_ARGS (value), VALUE_MAX_ARGS (value),
- BIT_TEST (VALUE_FLAGS (value),
- VALUE_SIDE_EFFECT_ARGS_BIT)))
- {
- if (m4_is_symbol_value_text (value))
- process_macro (context, value, expansion, argv->argc, argv);
- else if (m4_is_symbol_value_func (value))
- m4_get_symbol_value_func (value) (context, expansion, argv->argc,
- argv);
- else if (m4_is_symbol_value_placeholder (value))
- m4_warn (context, 0, argv->info,
- _("builtin %s requested by frozen file not found"),
- quotearg_style (locale_quoting_style,
- m4_get_symbol_value_placeholder (value)));
- else
- {
- assert (!"m4_macro_call");
- abort ();
- }
- }
- if (argv->info->trace)
- trace_post (context, trace_start, argv->info);
-}
-
-/* This function handles all expansion of user defined and predefined
- macros. It is called with an obstack OBS, where the macros expansion
- will be placed, as an unfinished object. SYMBOL points to the macro
- definition, giving the expansion text. ARGC and ARGV are the arguments,
- as usual. */
-static void
-process_macro (m4 *context, m4_symbol_value *value, m4_obstack *obs,
- int argc, m4_macro_args *argv)
-{
- const char *text = m4_get_symbol_value_text (value);
- size_t len = m4_get_symbol_value_len (value);
- const char *end = text + len;
- int i;
- while (1)
- {
- const char *dollar;
- if (m4_is_syntax_single_dollar (M4SYNTAX))
- dollar = (char *) memchr (text, M4SYNTAX->dollar, len);
- else
- {
- dollar = text;
- while (dollar != end)
- {
- if (m4_has_syntax (M4SYNTAX, *dollar, M4_SYNTAX_DOLLAR))
- break;
- dollar++;
- }
- if (dollar == end)
- dollar = NULL;
- }
- if (!dollar)
- {
- obstack_grow (obs, text, len);
- return;
- }
- obstack_grow (obs, text, dollar - text);
- len -= dollar - text;
- text = dollar;
- if (len == 1)
- {
- obstack_1grow (obs, *dollar);
- return;
- }
- len--;
- switch (*++text)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- /* FIXME - multidigit arguments should convert over to ${10}
- syntax instead of $10; see
- http://lists.gnu.org/archive/html/m4-discuss/2006-08/msg00028.html
- for more discussion. */
- if (m4_get_posixly_correct_opt (context)
- || !isdigit (to_uchar (text[1])))
- {
- i = *text++ - '0';
- len--;
- }
- else
- {
- char *endp;
- i = (int) strtol (text, &endp, 10);
- len -= endp - text;
- text = endp;
- }
- if (i < argc)
- m4_push_arg (context, obs, argv, i);
- break;
-
- case '#': /* number of arguments */
- m4_shipout_int (obs, argc - 1);
- text++;
- len--;
- break;
-
- case '*': /* all arguments */
- case '@': /* ... same, but quoted */
- m4_push_args (context, obs, argv, false, *text == '@');
- text++;
- len--;
- break;
-
- default:
- if (m4_get_posixly_correct_opt (context)
- || !VALUE_ARG_SIGNATURE (value))
- {
- obstack_1grow (obs, *dollar);
- }
- else
- {
- size_t len1 = 0;
- const char *endp;
- char *key;
-
- for (endp = ++text;
- len1 < len && m4_has_syntax (M4SYNTAX, *endp,
- (M4_SYNTAX_OTHER
- | M4_SYNTAX_ALPHA
- | M4_SYNTAX_NUM));
- ++endp)
- {
- ++len1;
- }
- key = xstrndup (text, len1);
-
- if (*endp)
- {
- struct m4_symbol_arg **arg
- = (struct m4_symbol_arg **)
- m4_hash_lookup (VALUE_ARG_SIGNATURE (value), key);
-
- if (arg)
- {
- i = SYMBOL_ARG_INDEX (*arg);
- assert (i < argc);
- m4_shipout_string (context, obs, M4ARG (i), M4ARGLEN (i),
- false);
- }
- }
- else
- {
- m4_error (context, 0, 0, argv->info,
- _("unterminated parameter reference: %s"), key);
- }
-
- len -= endp - text;
- text = endp;
-
- free (key);
- }
- break;
- }
- }
-}
-
-
-
-/* The next portion of this file contains the functions for macro
- tracing output. All tracing output for a macro call is collected
- on an obstack TRACE, and printed whenever the line is complete.
- This prevents tracing output from interfering with other debug
- messages generated by the various builtins. */
-
-/* Format the standard header attached to all tracing output lines,
- using the context in INFO as appropriate. Return the offset into
- the trace obstack where this particular trace begins. */
-static unsigned int
-trace_header (m4 *context, const m4_call_info *info)
-{
- m4_obstack *trace = &context->trace_messages;
- unsigned int result = obstack_object_size (trace);
- obstack_grow (trace, "m4trace:", 8);
- if (info->debug_level & M4_DEBUG_TRACE_FILE)
- obstack_printf (trace, "%s:", info->file);
- if (info->debug_level & M4_DEBUG_TRACE_LINE)
- obstack_printf (trace, "%d:", info->line);
- obstack_printf (trace, " -%zu- ", context->expansion_level);
- if (info->debug_level & M4_DEBUG_TRACE_CALLID)
- obstack_printf (trace, "id %zu: ", info->call_id);
- return result;
-}
-
-/* Print current tracing line starting at offset START, as returned
- from an earlier trace_header(), then clear the obstack. */
-static void
-trace_flush (m4 *context, unsigned int start)
-{
- char *str;
- size_t len = obstack_object_size (&context->trace_messages);
- FILE *file = m4_get_debug_file (context);
-
- if (file)
- {
- /* TODO - quote nonprintable characters if debug is tty? */
- str = (char *) obstack_base (&context->trace_messages);
- fwrite (&str[start], 1, len - start, file);
- fputc ('\n', file);
- }
- obstack_blank_fast (&context->trace_messages, start - len);
-}
-
-/* Do pre-argument-collection tracing for the macro described in INFO.
- Should be called prior to m4_macro_call(). */
-void
-m4_trace_prepare (m4 *context, const m4_call_info *info,
- m4_symbol_value *value)
-{
- const m4_string_pair *quotes = NULL;
- size_t arg_length = m4_get_max_debug_arg_length_opt (context);
- bool module = (info->debug_level & M4_DEBUG_TRACE_MODULE) != 0;
-
- if (info->debug_level & M4_DEBUG_TRACE_QUOTE)
- quotes = m4_get_syntax_quotes (M4SYNTAX);
- if (info->trace && (info->debug_level & M4_DEBUG_TRACE_CALL))
- {
- unsigned int start = trace_header (context, info);
- obstack_grow (&context->trace_messages, info->name, info->name_len);
- obstack_grow (&context->trace_messages, " ... = ", 7);
- m4__symbol_value_print (context, value, &context->trace_messages, quotes,
- false, NULL, &arg_length, module);
- trace_flush (context, start);
- }
-}
-
-/* Format the parts of a trace line that are known via ARGV before the
- macro is actually expanded. Used from m4_macro_call(). Return the
- start of the current trace, in case other traces are printed before
- this trace completes trace_post. */
-static unsigned int
-trace_pre (m4 *context, m4_macro_args *argv)
-{
- int trace_level = argv->info->debug_level;
- unsigned int start = trace_header (context, argv->info);
- m4_obstack *trace = &context->trace_messages;
-
- assert (argv->info->trace);
- obstack_grow (trace, argv->info->name, argv->info->name_len);
-
- if (1 < m4_arg_argc (argv) && (trace_level & M4_DEBUG_TRACE_ARGS))
- {
- const m4_string_pair *quotes = NULL;
- size_t arg_length = m4_get_max_debug_arg_length_opt (context);
- bool module = (trace_level & M4_DEBUG_TRACE_MODULE) != 0;
-
- if (trace_level & M4_DEBUG_TRACE_QUOTE)
- quotes = m4_get_syntax_quotes (M4SYNTAX);
- obstack_1grow (trace, '(');
- m4__arg_print (context, trace, argv, 1, quotes, false, NULL, ", ",
- &arg_length, true, module);
- obstack_1grow (trace, ')');
- }
- return start;
-}
-
-/* If requested by the trace state in INFO, format the final part of a
- trace line. Then print all collected information from START,
- returned from a prior trace_pre(). Used from m4_macro_call (). */
-static void
-trace_post (m4 *context, unsigned int start, const m4_call_info *info)
-{
- assert (info->trace);
- if (info->debug_level & M4_DEBUG_TRACE_EXPANSION)
- {
- obstack_grow (&context->trace_messages, " -> ", 4);
- m4_input_print (context, &context->trace_messages, info->debug_level);
- }
- trace_flush (context, start);
-}
-
-
-/* Accessors into m4_macro_args. */
-
-/* Adjust the refcount of argument stack LEVEL. If INCREASE, then
- increase the count, otherwise decrease the count and clear the
- entire stack if the new count is zero. Return the new
- refcount. */
-size_t
-m4__adjust_refcount (m4 *context, size_t level, bool increase)
-{
- m4__macro_arg_stacks *stack = &context->arg_stacks[level];
- assert (level < context->stacks_count && stack->args
- && (increase || stack->refcount));
- if (increase)
- stack->refcount++;
- else if (--stack->refcount == 0)
- {
- obstack_free (stack->args, stack->args_base);
- obstack_free (stack->argv, stack->argv_base);
- if ((debug_macro_level & PRINT_ARGCOUNT_CHANGES) && 1 < stack->argcount)
- xfprintf (stderr, "m4debug: -%zu- freeing %zu args, level=%zu\n",
- macro_call_id, stack->argcount, level);
- stack->argcount = 0;
- }
- if (debug_macro_level
- & (increase ? PRINT_REFCOUNT_INCREASE : PRINT_REFCOUNT_DECREASE))
- xfprintf (stderr, "m4debug: level %zu refcount=%zu\n", level,
- stack->refcount);
- return stack->refcount;
-}
-
-/* Given ARGV, adjust the refcount of every reference it contains in
- the direction decided by INCREASE. Return true if increasing
- references to ARGV implies the first use of ARGV. */
-bool
-m4__arg_adjust_refcount (m4 *context, m4_macro_args *argv, bool increase)
-{
- size_t i;
- m4__symbol_chain *chain;
- bool result = !argv->inuse;
-
- if (argv->has_ref)
- for (i = 0; i < argv->arraylen; i++)
- if (argv->array[i]->type == M4_SYMBOL_COMP)
- {
- chain = argv->array[i]->u.u_c.chain;
- while (chain)
- {
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- if (chain->u.u_s.level < SIZE_MAX)
- m4__adjust_refcount (context, chain->u.u_s.level,
- increase);
- break;
- case M4__CHAIN_FUNC:
- break;
- case M4__CHAIN_ARGV:
- assert (chain->u.u_a.argv->inuse);
- m4__arg_adjust_refcount (context, chain->u.u_a.argv,
- increase);
- break;
- default:
- assert (!"m4__arg_adjust_refcount");
- abort ();
- }
- chain = chain->next;
- }
- }
- m4__adjust_refcount (context, argv->level, increase);
- return result;
-}
-
-/* Mark ARGV as being in use, along with any $@ references that it
- wraps. */
-static void
-arg_mark (m4_macro_args *argv)
-{
- size_t i;
- m4__symbol_chain *chain;
-
- if (argv->inuse)
- return;
- argv->inuse = true;
- if (argv->wrapper)
- {
- for (i = 0; i < argv->arraylen; i++)
- if (argv->array[i]->type == M4_SYMBOL_COMP
- && argv->array[i]->u.u_c.wrapper)
- {
- chain = argv->array[i]->u.u_c.chain;
- assert (!chain->next && chain->type == M4__CHAIN_ARGV);
- if (!chain->u.u_a.argv->inuse)
- arg_mark (chain->u.u_a.argv);
- }
- }
-}
-
-/* Populate the newly-allocated VALUE as a wrapper around ARGV,
- starting with argument ARG. Allocate any data on OBS, owned by a
- given expansion LEVEL. FLATTEN determines whether to allow
- builtins, and QUOTES determines whether all arguments are quoted.
- Return TOKEN when successful, NULL when wrapping ARGV is trivially
- empty. */
-static m4_symbol_value *
-make_argv_ref (m4 *context, m4_symbol_value *value, m4_obstack *obs,
- size_t level, m4_macro_args *argv, size_t arg, bool flatten,
- const m4_string_pair *quotes)
-{
- m4__symbol_chain *chain;
-
- if (argv->argc <= arg)
- return NULL;
- value->type = M4_SYMBOL_COMP;
- value->u.u_c.chain = value->u.u_c.end = NULL;
-
- /* Cater to the common idiom of $0(`$1',shift(shift($@))), by
- inlining the first few arguments and reusing the original $@ ref,
- rather than creating another layer of wrappers. */
- while (argv->wrapper)
- {
- size_t i;
- for (i = 0; i < argv->arraylen; i++)
- {
- if ((argv->array[i]->type == M4_SYMBOL_COMP
- && argv->array[i]->u.u_c.wrapper)
- || level < SIZE_MAX)
- break;
- if (arg == 1)
- {
- m4__push_arg_quote (context, obs, argv, i + 1, quotes);
- /* TODO support M4_SYNTAX_COMMA. */
- obstack_1grow (obs, ',');
- }
- else
- arg--;
- }
- assert (i < argv->arraylen);
- if (i + 1 == argv->arraylen)
- {
- assert (argv->array[i]->type == M4_SYMBOL_COMP
- && argv->array[i]->u.u_c.wrapper);
- chain = argv->array[i]->u.u_c.chain;
- assert (!chain->next && chain->type == M4__CHAIN_ARGV
- && !chain->u.u_a.skip_last);
- argv = chain->u.u_a.argv;
- arg += chain->u.u_a.index - 1;
- }
- else
- {
- arg += i;
- break;
- }
- }
-
- m4__make_text_link (obs, &value->u.u_c.chain, &value->u.u_c.end);
- chain = (m4__symbol_chain *) obstack_alloc (obs, sizeof *chain);
- if (value->u.u_c.end)
- value->u.u_c.end->next = chain;
- else
- value->u.u_c.chain = chain;
- value->u.u_c.end = chain;
- value->u.u_c.wrapper = true;
- value->u.u_c.has_func = argv->has_func;
- chain->next = NULL;
- chain->type = M4__CHAIN_ARGV;
- chain->quote_age = argv->quote_age;
- chain->u.u_a.argv = argv;
- chain->u.u_a.index = arg;
- chain->u.u_a.flatten = flatten;
- chain->u.u_a.has_func = argv->has_func;
- chain->u.u_a.comma = false;
- chain->u.u_a.skip_last = false;
- chain->u.u_a.quotes = m4__quote_cache (M4SYNTAX, obs, chain->quote_age,
- quotes);
- return value;
-}
-
-/* Given ARGV, return the symbol value at the specified ARG, which
- must be non-zero. *LEVEL is set to the obstack level that contains
- the symbol (which is not necessarily the level of ARGV). If
- FLATTEN, avoid returning a builtin token. */
-static m4_symbol_value *
-arg_symbol (m4_macro_args *argv, size_t arg, size_t *level, bool flatten)
-{
- size_t i;
- m4_symbol_value *value;
-
- assert (arg);
- if (level)
- *level = argv->level;
- flatten |= argv->flatten;
- if (argv->argc <= arg)
- return &empty_symbol;
- if (!argv->wrapper)
- {
- value = argv->array[arg - 1];
- if (flatten && m4_is_symbol_value_func (value))
- value = &empty_symbol;
- return value;
- }
-
- /* Must cycle through all array slots until we find arg, since
- wrappers can contain multiple arguments. */
- for (i = 0; i < argv->arraylen; i++)
- {
- value = argv->array[i];
- if (value->type == M4_SYMBOL_COMP && value->u.u_c.wrapper)
- {
- m4__symbol_chain *chain = value->u.u_c.chain;
- assert (!chain->next && chain->type == M4__CHAIN_ARGV);
- if (arg <= (chain->u.u_a.argv->argc - chain->u.u_a.index
- - chain->u.u_a.skip_last))
- {
- value = arg_symbol (chain->u.u_a.argv,
- chain->u.u_a.index - 1 + arg, level,
- flatten || chain->u.u_a.flatten);
- break;
- }
- arg -= (chain->u.u_a.argv->argc - chain->u.u_a.index
- - chain->u.u_a.skip_last);
- }
- else if (--arg == 0)
- break;
- }
- return value;
-}
-
-/* Given ARGV, return the symbol value at the specified ARG, which
- must be non-zero. */
-m4_symbol_value *
-m4_arg_symbol (m4_macro_args *argv, size_t arg)
-{
- return arg_symbol (argv, arg, NULL, false);
-}
-
-/* Given ARGV, return true if argument ARG is text. Arg 0 is always
- text, as are indices beyond argc. */
-bool
-m4_is_arg_text (m4_macro_args *argv, size_t arg)
-{
- m4_symbol_value *value;
- if (arg == 0 || argv->argc <= arg || argv->flatten || !argv->has_func)
- return true;
- value = m4_arg_symbol (argv, arg);
- if (m4_is_symbol_value_text (value)
- || (value->type == M4_SYMBOL_COMP && !value->u.u_c.has_func))
- return true;
- return false;
-}
-
-/* Given ARGV, return true if argument ARG is a single builtin
- function. Only non-zero indices less than argc can return
- true. */
-bool
-m4_is_arg_func (m4_macro_args *argv, size_t arg)
-{
- if (arg == 0 || argv->argc <= arg || argv->flatten || !argv->has_func)
- return false;
- return m4_is_symbol_value_func (m4_arg_symbol (argv, arg));
-}
-
-/* Given ARGV, return true if argument ARG contains a builtin token
- concatenated with anything else. Only non-zero indices less than
- argc can return true. */
-bool
-m4_is_arg_composite (m4_macro_args *argv, size_t arg)
-{
- m4_symbol_value *value;
- if (arg == 0 || argv->argc <= arg || argv->flatten || !argv->has_func)
- return false;
- value = m4_arg_symbol (argv, arg);
- if (value->type == M4_SYMBOL_COMP && value->u.u_c.has_func)
- return true;
- return false;
-}
-
-/* Given ARGV, return the text at argument ARG. Abort if the argument
- is not text. Arg 0 is always text, and indices beyond argc return
- the empty string. If FLATTEN, builtins are ignored. The result is
- always NUL-terminated, even if it includes embedded NUL
- characters. */
-const char *
-m4_arg_text (m4 *context, m4_macro_args *argv, size_t arg, bool flatten)
-{
- m4_symbol_value *value;
- m4__symbol_chain *chain;
- m4_obstack *obs;
-
- if (arg == 0)
- {
- assert (argv->info);
- return argv->info->name;
- }
- if (argv->argc <= arg)
- return "";
- value = arg_symbol (argv, arg, NULL, flatten);
- if (m4_is_symbol_value_text (value))
- return m4_get_symbol_value_text (value);
- assert (value->type == M4_SYMBOL_COMP);
- chain = value->u.u_c.chain;
- obs = m4_arg_scratch (context);
- while (chain)
- {
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
- break;
- case M4__CHAIN_FUNC:
- if (flatten)
- break;
- assert (!"m4_arg_text");
- abort ();
- case M4__CHAIN_ARGV:
- assert (!chain->u.u_a.has_func || flatten || argv->flatten);
- m4__arg_print (context, obs, chain->u.u_a.argv, chain->u.u_a.index,
- m4__quote_cache (M4SYNTAX, NULL, chain->quote_age,
- chain->u.u_a.quotes),
- flatten || argv->flatten || chain->u.u_a.flatten,
- NULL, NULL, NULL, false, false);
- break;
- default:
- assert (!"m4_arg_text");
- abort ();
- }
- chain = chain->next;
- }
- obstack_1grow (obs, '\0');
- return (char *) obstack_finish (obs);
-}
-
-/* Given ARGV, compare text arguments INDEXA and INDEXB for equality.
- Both indices must be non-zero. Return true if the arguments
- contain the same contents; often more efficient than
- STREQ (m4_arg_text (context, argv, indexa),
- m4_arg_text (context, argv, indexb)). */
-bool
-m4_arg_equal (m4 *context, m4_macro_args *argv, size_t indexa, size_t indexb)
-{
- m4_symbol_value *sa = m4_arg_symbol (argv, indexa);
- m4_symbol_value *sb = m4_arg_symbol (argv, indexb);
- m4__symbol_chain tmpa;
- m4__symbol_chain tmpb;
- m4__symbol_chain *ca = &tmpa;
- m4__symbol_chain *cb = &tmpb;
- m4__symbol_chain *chain;
- m4_obstack *obs = m4_arg_scratch (context);
-
- /* Quick tests. */
- if (sa == &empty_symbol || sb == &empty_symbol)
- return sa == sb;
- if (m4_is_symbol_value_text (sa) && m4_is_symbol_value_text (sb))
- return (m4_get_symbol_value_len (sa) == m4_get_symbol_value_len (sb)
- && memcmp (m4_get_symbol_value_text (sa),
- m4_get_symbol_value_text (sb),
- m4_get_symbol_value_len (sa)) == 0);
-
- /* Convert both arguments to chains, if not one already. */
- switch (sa->type)
- {
- case M4_SYMBOL_TEXT:
- tmpa.next = NULL;
- tmpa.type = M4__CHAIN_STR;
- tmpa.u.u_s.str = m4_get_symbol_value_text (sa);
- tmpa.u.u_s.len = m4_get_symbol_value_len (sa);
- break;
- case M4_SYMBOL_FUNC:
- tmpa.next = NULL;
- tmpa.type = M4__CHAIN_FUNC;
- tmpa.u.builtin = sa->u.builtin;
- break;
- case M4_SYMBOL_COMP:
- ca = sa->u.u_c.chain;
- break;
- default:
- assert (!"m4_arg_equal");
- abort ();
- }
- switch (sb->type)
- {
- case M4_SYMBOL_TEXT:
- tmpb.next = NULL;
- tmpb.type = M4__CHAIN_STR;
- tmpb.u.u_s.str = m4_get_symbol_value_text (sb);
- tmpb.u.u_s.len = m4_get_symbol_value_len (sb);
- break;
- case M4_SYMBOL_FUNC:
- tmpb.next = NULL;
- tmpb.type = M4__CHAIN_FUNC;
- tmpb.u.builtin = sb->u.builtin;
- break;
- case M4_SYMBOL_COMP:
- cb = sb->u.u_c.chain;
- break;
- default:
- assert (!"m4_arg_equal");
- abort ();
- }
-
- /* Compare each link of the chain. */
- while (ca && cb)
- {
- if (ca->type == M4__CHAIN_ARGV)
- {
- tmpa.next = NULL;
- tmpa.type = M4__CHAIN_STR;
- tmpa.u.u_s.str = NULL;
- tmpa.u.u_s.len = 0;
- chain = &tmpa;
- m4__arg_print (context, obs, ca->u.u_a.argv, ca->u.u_a.index,
- m4__quote_cache (M4SYNTAX, NULL, ca->quote_age,
- ca->u.u_a.quotes),
- argv->flatten || ca->u.u_a.flatten, &chain, NULL,
- NULL, false, false);
- assert (obstack_object_size (obs) == 0 && chain != &tmpa);
- chain->next = ca->next;
- ca = tmpa.next;
- continue;
- }
- if (cb->type == M4__CHAIN_ARGV)
- {
- tmpb.next = NULL;
- tmpb.type = M4__CHAIN_STR;
- tmpb.u.u_s.str = NULL;
- tmpb.u.u_s.len = 0;
- chain = &tmpb;
- m4__arg_print (context, obs, cb->u.u_a.argv, cb->u.u_a.index,
- m4__quote_cache (M4SYNTAX, NULL, cb->quote_age,
- cb->u.u_a.quotes),
- argv->flatten || cb->u.u_a.flatten, &chain, NULL,
- NULL, false, false);
- assert (obstack_object_size (obs) == 0 && chain != &tmpb);
- chain->next = cb->next;
- cb = tmpb.next;
- continue;
- }
- if (ca->type == M4__CHAIN_FUNC)
- {
- if (cb->type != M4__CHAIN_FUNC || ca->u.builtin != cb->u.builtin)
- return false;
- ca = ca->next;
- cb = cb->next;
- continue;
- }
- assert (ca->type == M4__CHAIN_STR && cb->type == M4__CHAIN_STR);
- if (ca->u.u_s.len == cb->u.u_s.len)
- {
- if (memcmp (ca->u.u_s.str, cb->u.u_s.str, ca->u.u_s.len) != 0)
- return false;
- ca = ca->next;
- cb = cb->next;
- }
- else if (ca->u.u_s.len < cb->u.u_s.len)
- {
- if (memcmp (ca->u.u_s.str, cb->u.u_s.str, ca->u.u_s.len) != 0)
- return false;
- tmpb.next = cb->next;
- tmpb.u.u_s.str = cb->u.u_s.str + ca->u.u_s.len;
- tmpb.u.u_s.len = cb->u.u_s.len - ca->u.u_s.len;
- ca = ca->next;
- cb = &tmpb;
- }
- else
- {
- assert (cb->u.u_s.len < ca->u.u_s.len);
- if (memcmp (ca->u.u_s.str, cb->u.u_s.str, cb->u.u_s.len) != 0)
- return false;
- tmpa.next = ca->next;
- tmpa.u.u_s.str = ca->u.u_s.str + cb->u.u_s.len;
- tmpa.u.u_s.len = ca->u.u_s.len - cb->u.u_s.len;
- ca = &tmpa;
- cb = cb->next;
- }
- }
-
- /* If we get this far, the two arguments are equal only if both
- chains are exhausted. */
- assert (ca != cb || !ca);
- return ca == cb;
-}
-
-/* Given ARGV, return true if argument ARG is the empty string. This
- gives the same result as comparing m4_arg_len against 0, but is
- often faster. */
-bool
-m4_arg_empty (m4_macro_args *argv, size_t arg)
-{
- if (!arg)
- {
- assert (argv->info);
- return !argv->info->name_len;
- }
- return m4_arg_symbol (argv, arg) == &empty_symbol;
-}
-
-/* Given ARGV, return the length of argument ARG. Abort if the
- argument is not text and FLATTEN is not true. Indices beyond argc
- return 0. */
-size_t
-m4_arg_len (m4 *context, m4_macro_args *argv, size_t arg, bool flatten)
-{
- m4_symbol_value *value;
- m4__symbol_chain *chain;
- size_t len;
-
- if (arg == 0)
- {
- assert (argv->info);
- return argv->info->name_len;
- }
- if (argv->argc <= arg)
- return 0;
- value = arg_symbol (argv, arg, NULL, flatten);
- if (m4_is_symbol_value_text (value))
- return m4_get_symbol_value_len (value);
- assert (value->type == M4_SYMBOL_COMP);
- chain = value->u.u_c.chain;
- len = 0;
- while (chain)
- {
- size_t i;
- size_t limit;
- const m4_string_pair *quotes;
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- len += chain->u.u_s.len;
- break;
- case M4__CHAIN_FUNC:
- assert (flatten);
- break;
- case M4__CHAIN_ARGV:
- i = chain->u.u_a.index;
- limit = chain->u.u_a.argv->argc - i - chain->u.u_a.skip_last;
- quotes = m4__quote_cache (M4SYNTAX, NULL, chain->quote_age,
- chain->u.u_a.quotes);
- assert (limit);
- if (quotes)
- len += (quotes->len1 + quotes->len2) * limit;
- len += limit - 1;
- while (limit--)
- len += m4_arg_len (context, chain->u.u_a.argv, i++,
- flatten || chain->u.u_a.flatten);
- break;
- default:
- assert (!"m4_arg_len");
- abort ();
- }
- chain = chain->next;
- }
- assert (len || flatten);
- return len;
-}
-
-/* Given ARGV, return the builtin function referenced by argument ARG.
- Abort if it is not a single builtin. */
-m4_builtin_func *
-m4_arg_func (m4_macro_args *argv, size_t arg)
-{
- return m4_get_symbol_value_func (m4_arg_symbol (argv, arg));
-}
-
-/* Dump a representation of ARGV to the obstack OBS, starting with
- argument ARG. If QUOTES is non-NULL, each argument is displayed
- with those quotes. If FLATTEN, builtins are converted to empty
- quotes; if CHAINP, *CHAINP is updated with macro tokens; otherwise,
- builtins are represented by their name. Separate arguments with
- SEP, which defaults to a comma. If MAX_LEN is non-NULL, truncate
- the output after *MAX_LEN bytes are output and return true;
- otherwise, return false, and reduce *MAX_LEN by the number of bytes
- output. If QUOTE_EACH, the truncation length is reset for each
- argument, quotes do not count against length, and all arguments are
- printed; otherwise, quotes count against the length and trailing
- arguments may be discarded. If MODULE, print any details about
- originating modules; modules do not count against truncation
- length. MAX_LEN and CHAINP may not both be specified. */
-bool
-m4__arg_print (m4 *context, m4_obstack *obs, m4_macro_args *argv, size_t arg,
- const m4_string_pair *quotes, bool flatten,
- m4__symbol_chain **chainp, const char *sep, size_t *max_len,
- bool quote_each, bool module)
-{
- size_t len = max_len ? *max_len : SIZE_MAX;
- size_t i;
- bool use_sep = false;
- size_t sep_len;
- size_t *plen = quote_each ? NULL : &len;
-
- flatten |= argv->flatten;
- if (chainp)
- assert (!max_len && *chainp);
- if (!sep)
- sep = ",";
- sep_len = strlen (sep);
- for (i = arg; i < argv->argc; i++)
- {
- if (quote_each && max_len)
- len = *max_len;
- if (use_sep && m4_shipout_string_trunc (obs, sep, sep_len, NULL, plen))
- return true;
- use_sep = true;
- if (quotes && !quote_each
- && m4_shipout_string_trunc (obs, quotes->str1, quotes->len1, NULL,
- plen))
- return true;
- if (m4__symbol_value_print (context, arg_symbol (argv, i, NULL, flatten),
- obs, quote_each ? quotes : NULL, flatten,
- chainp, &len, module))
- return true;
- if (quotes && !quote_each
- && m4_shipout_string_trunc (obs, quotes->str2, quotes->len2, NULL,
- plen))
- return true;
- }
- if (max_len)
- *max_len = len;
- else if (chainp)
- m4__make_text_link (obs, NULL, chainp);
- return false;
-}
-
-/* Create a new argument object using the same obstack as ARGV; thus,
- the new object will automatically be freed when the original is
- freed. Explicitly set the macro name (argv[0]) from ARGV0 with
- length ARGV0_LEN, and discard argv[1] of the wrapped ARGV. If
- FLATTEN, any builtins in ARGV are flattened to an empty string when
- referenced through the new object. If TRACE, then trace the macro
- regardless of global trace state. */
-m4_macro_args *
-m4_make_argv_ref (m4 *context, m4_macro_args *argv, const char *argv0,
- size_t argv0_len, bool flatten, bool trace)
-{
- m4_macro_args *new_argv;
- m4_symbol_value *value;
- m4_symbol_value *new_value;
- m4_obstack *obs = m4_arg_scratch (context);
- m4_call_info *info;
-
- info = (m4_call_info *) obstack_copy (obs, argv->info, sizeof *info);
- new_value = (m4_symbol_value *) obstack_alloc (obs, sizeof *value);
- value = make_argv_ref (context, new_value, obs, context->expansion_level - 1,
- argv, 2, flatten, NULL);
- if (!value)
- {
- obstack_free (obs, new_value);
- new_argv = (m4_macro_args *) obstack_alloc (obs, offsetof (m4_macro_args,
- array));
- new_argv->arraylen = 0;
- new_argv->wrapper = false;
- new_argv->has_ref = false;
- new_argv->flatten = false;
- new_argv->has_func = false;
- }
- else
- {
- new_argv = (m4_macro_args *) obstack_alloc (obs, (offsetof (m4_macro_args,
- array)
- + sizeof value));
- new_argv->arraylen = 1;
- new_argv->array[0] = value;
- new_argv->wrapper = true;
- new_argv->has_ref = argv->has_ref;
- new_argv->flatten = flatten;
- new_argv->has_func = argv->has_func;
- }
- new_argv->argc = argv->argc - 1;
- new_argv->inuse = false;
- new_argv->quote_age = argv->quote_age;
- new_argv->info = info;
- info->trace = (argv->info->debug_level & M4_DEBUG_TRACE_ALL) || trace;
- info->name = argv0;
- info->name_len = argv0_len;
- new_argv->level = argv->level;
- return new_argv;
-}
-
-/* Push argument ARG from ARGV, which must be a text token, onto the
- expansion stack OBS for rescanning. */
-void
-m4_push_arg (m4 *context, m4_obstack *obs, m4_macro_args *argv, size_t arg)
-{
- m4_symbol_value value;
-
- if (arg == 0)
- {
- assert (argv->info);
- m4_set_symbol_value_text (&value, argv->info->name, argv->info->name_len,
- 0);
- if (m4__push_symbol (context, &value, context->expansion_level - 1,
- argv->inuse))
- arg_mark (argv);
- }
- else
- m4__push_arg_quote (context, obs, argv, arg, NULL);
-}
-
-/* Push argument ARG from ARGV onto the expansion stack OBS for
- rescanning. ARG must be non-zero. QUOTES determines any quote
- delimiters that were in effect when the reference was created. */
-void
-m4__push_arg_quote (m4 *context, m4_obstack *obs, m4_macro_args *argv,
- size_t arg, const m4_string_pair *quotes)
-{
- size_t level;
- m4_symbol_value *value = arg_symbol (argv, arg, &level, false);
-
- if (quotes)
- obstack_grow (obs, quotes->str1, quotes->len1);
- if (value != &empty_symbol
- && m4__push_symbol (context, value, level, argv->inuse))
- arg_mark (argv);
- if (quotes)
- obstack_grow (obs, quotes->str2, quotes->len2);
-}
-
-/* Push series of comma-separated arguments from ARGV onto the
- expansion stack OBS for rescanning. If SKIP, then don't push the
- first argument. If QUOTE, also push quoting around each arg. */
-void
-m4_push_args (m4 *context, m4_obstack *obs, m4_macro_args *argv, bool skip,
- bool quote)
-{
- m4_symbol_value tmp;
- m4_symbol_value *value;
- size_t i = skip ? 2 : 1;
- const m4_string_pair *quotes = m4_get_syntax_quotes (M4SYNTAX);
-
- if (argv->argc <= i)
- return;
-
- if (argv->argc == i + 1)
- {
- m4__push_arg_quote (context, obs, argv, i, quote ? quotes : NULL);
- return;
- }
-
- value = make_argv_ref (context, &tmp, obs, -1, argv, i, argv->flatten,
- quote ? quotes : NULL);
- assert (value == &tmp);
- if (m4__push_symbol (context, value, -1, argv->inuse))
- arg_mark (argv);
-}
-
-/* Push arguments from ARGV onto the wrap stack for later rescanning.
- If GNU extensions are disabled, only the first argument is pushed;
- otherwise, all arguments are pushed and separated with a space. */
-void
-m4_wrap_args (m4 *context, m4_macro_args *argv)
-{
- size_t i;
- m4_obstack *obs;
- m4_symbol_value *value;
- m4__symbol_chain *chain;
- m4__symbol_chain **end;
- size_t limit = m4_get_posixly_correct_opt (context) ? 2 : argv->argc;
-
- if (limit == 2 && m4_arg_empty (argv, 1))
- return;
-
- obs = m4__push_wrapup_init (context, argv->info, &end);
- for (i = 1; i < limit; i++)
- {
- if (i != 1)
- obstack_1grow (obs, ' ');
- value = m4_arg_symbol (argv, i);
- switch (value->type)
- {
- case M4_SYMBOL_TEXT:
- obstack_grow (obs, m4_get_symbol_value_text (value),
- m4_get_symbol_value_len (value));
- break;
- case M4_SYMBOL_FUNC:
- m4__append_builtin (obs, value->u.builtin, NULL, end);
- break;
- case M4_SYMBOL_COMP:
- chain = value->u.u_c.chain;
- while (chain)
- {
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
- break;
- case M4__CHAIN_FUNC:
- m4__append_builtin (obs, chain->u.builtin, NULL, end);
- break;
- case M4__CHAIN_ARGV:
- m4__arg_print (context, obs, chain->u.u_a.argv,
- chain->u.u_a.index,
- m4__quote_cache (M4SYNTAX, NULL,
- chain->quote_age,
- chain->u.u_a.quotes),
- chain->u.u_a.flatten, end, NULL, NULL, false,
- false);
- break;
- default:
- assert (!"m4_wrap_args");
- abort ();
- }
- chain = chain->next;
- }
- break;
- default:
- assert (!"m4_wrap_args");
- abort ();
- }
- }
- m4__push_wrapup_finish ();
-}
-
-
-/* Define these last, so that earlier uses can benefit from the macros
- in m4private.h. */
-
-/* Given ARGV, return one greater than the number of arguments it
- describes. */
-#undef m4_arg_argc
-size_t
-m4_arg_argc (m4_macro_args *argv)
-{
- return argv->argc;
-}
-
-/* Given ARGV, return the call context in effect when argument
- collection began. Only safe to call while the macro is being
- expanded. */
-#undef m4_arg_info
-const m4_call_info *
-m4_arg_info (m4_macro_args *argv)
-{
- assert (argv->info);
- return argv->info;
-}
-
-/* Return an obstack useful for scratch calculations, and which will
- not interfere with macro expansion. The obstack will be reset when
- expand_macro completes. */
-#undef m4_arg_scratch
-m4_obstack *
-m4_arg_scratch (m4 *context)
-{
- m4__macro_arg_stacks *stack
- = &context->arg_stacks[context->expansion_level - 1];
- assert (obstack_object_size (stack->args) == 0);
- return stack->args;
-}
diff --git a/m4/module.c b/m4/module.c
deleted file mode 100644
index c00b8aa1..00000000
--- a/m4/module.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 1998-1999, 2002-2008, 2010, 2013-2014, 2017
- Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include <dlfcn.h>
-
-#include "m4private.h"
-#include "xvasprintf.h"
-
-/* Define this to see runtime debug info. Implied by DEBUG. */
-/*#define DEBUG_MODULES */
-
-/*
- * This file implements dynamic modules in GNU M4. A module is a
- * compiled shared object, that can be loaded into GNU M4 at run
- * time. Information about creating modules is in ../modules/README.
- *
- * This implementation uses libltdl, which is in turn can open modules
- * using either dlopen(3) (exists on GNU/Linux, OSF, Solaris, SunOS and
- * others), shl_load(3) (exists on HPUX), LoadLibrary(3) (exists on
- * Windows, cygwin, OS/2), load_add_on(3) (exists on BeOS), NSAddImage
- * (exists on MacOS) and can also fall back to dld_link(3) from GNU
- * libdld or lt_dlpreload from libtool if shared libraries are not
- * available on the host machine.
- *
- * An M4 module will usually define an external symbol named after the
- * basename of the loadable module:
- *
- * void
- * mymod_LTX_m4_init_module (m4 *context, m4_module *module,
- * m4_obstack *obs)
- *
- * The function is only called the first time the module is included
- * and generally uses either `m4_install_builtins' or
- * `m4_install_macros' (or both!) to register whatever builtins and
- * macros are provided by the module.
- *
- * To load a module, call m4_module_load(), which searches for the
- * module in directories from M4PATH. The search path is initialized
- * from the environment variable M4PATH, followed by the configuration
- * time default where the modules shipped with M4 itself are installed.
- * `m4_module_load' returns NULL on failure, or else an opaque module
- * handle for the newly mapped vm segment containing the module code.
- * If the module is not already loaded, m4_module_load() the builtins
- * and macros registered by `mymod_LTX_m4_init_module' are installed
- * into the symbol table using `install_builtin_table' and `install_
- * macro_table' respectively.
- **/
-
-#define MODULE_SELF_NAME "!myself!"
-
-#if DLSYM_USCORE
-static void *
-uscore_sym (void *handle, const char *symbol)
-{
- char *symname = xasprintf ("_%s", symbol);
- void *address = dlsym (handle, symname);
- free (symname);
- return address;
-}
-
-#define dlsym uscore_sym
-#endif
-
-static const char * module_dlerror (void);
-
-static void install_builtin_table (m4*, m4_module *);
-static void install_macro_table (m4*, m4_module *);
-
-static int compare_builtin_CB (const void *a, const void *b);
-
-const char *
-m4_get_module_name (const m4_module *module)
-{
- assert (module);
- return module->name;
-}
-
-void *
-m4_module_import (m4 *context, const char *module_name,
- const char *symbol_name, m4_obstack *obs)
-{
- m4_module * module = m4__module_find (context, module_name);
- void * symbol_address = NULL;
-
- /* Try to load the module if it is not yet available (errors are
- diagnosed by m4_module_load). */
- /* FIXME - should this use m4__module_open instead, to avoid
- polluting the symbol table when importing a function? */
- if (!module)
- module = m4_module_load (context, module_name, obs);
-
- if (module)
- {
- symbol_address = dlsym (module->handle, symbol_name);
-
- if (!symbol_address)
- m4_error (context, 0, 0, NULL,
- _("cannot load symbol `%s' from module `%s'"),
- symbol_name, module_name);
- }
-
- return symbol_address;
-}
-
-void
-m4_install_builtins (m4 *context, m4_module *module, const m4_builtin *bp)
-{
- assert (context);
- assert (module);
- assert (bp);
-
- const m4_builtin *tmp;
- m4__builtin *builtin;
- for (tmp = bp; tmp->name; tmp++)
- module->builtins_len++;
- module->builtins = (m4__builtin *) xnmalloc (module->builtins_len,
- sizeof *module->builtins);
- for (builtin = module->builtins; bp->name != NULL; bp++, builtin++)
- {
- /* Sanity check that builtins meet the required interface. */
- assert (bp->min_args <= bp->max_args);
- assert (bp->min_args > 0 ||
- (bp->flags & (M4_BUILTIN_BLIND|M4_BUILTIN_SIDE_EFFECT)) == 0);
- assert (bp->max_args ||
- (bp->flags & M4_BUILTIN_FLATTEN_ARGS) == 0);
- assert ((bp->flags & ~M4_BUILTIN_FLAGS_MASK) == 0);
- memcpy (&builtin->builtin, bp, sizeof *bp);
- builtin->builtin.name = xstrdup (bp->name);
- builtin->module = module;
- }
- qsort (module->builtins, module->builtins_len,
- sizeof *module->builtins, compare_builtin_CB);
-}
-
-static void
-install_builtin_table (m4 *context, m4_module *module)
-{
- size_t i;
-
- assert (context);
- assert (module);
- for (i = 0; i < module->builtins_len; i++)
- {
- m4_symbol_value *value = m4_symbol_value_create ();
- const char *name = module->builtins[i].builtin.name;
-
- m4__set_symbol_value_builtin (value, &module->builtins[i]);
- if (m4_get_prefix_builtins_opt (context))
- name = xasprintf ("m4_%s", name);
-
- m4_symbol_pushdef (M4SYMTAB, name, strlen (name), value);
-
- if (m4_get_prefix_builtins_opt (context))
- DELETE (name);
- }
- if (i)
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: builtins loaded"),
- m4_get_module_name (module));
-}
-
-void
-m4_install_macros (m4 *context, m4_module *module, const m4_macro *mp)
-{
- assert (context);
- assert (module);
- assert (mp);
-
- module->macros = (m4_macro *) mp;
-}
-
-static void
-install_macro_table (m4 *context, m4_module *module)
-{
- const m4_macro *mp;
-
- assert (context);
- assert (module);
-
- mp = module->macros;
-
- if (mp)
- {
- for (; mp->name != NULL; mp++)
- {
- m4_symbol_value *value = m4_symbol_value_create ();
- size_t len = strlen (mp->value);
-
- /* Sanity check that builtins meet the required interface. */
- assert (mp->min_args <= mp->max_args);
-
- m4_set_symbol_value_text (value, xmemdup0 (mp->value, len), len, 0);
- VALUE_MODULE (value) = module;
- VALUE_MIN_ARGS (value) = mp->min_args;
- VALUE_MAX_ARGS (value) = mp->max_args;
-
- m4_symbol_pushdef (M4SYMTAB, mp->name, strlen (mp->name), value);
- }
-
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: macros loaded"),
- m4_get_module_name (module));
- }
-}
-
-m4_module *
-m4_module_load (m4 *context, const char *name, m4_obstack *obs)
-{
- m4_module *module = m4__module_find (context, name);
-
- if (!module)
- {
- module = m4__module_open (context, name, obs);
-
- if (module)
- {
- install_builtin_table (context, module);
- install_macro_table (context, module);
- }
- }
-
- return module;
-}
-
-
-/* Return successive loaded modules. */
-m4_module *
-m4_module_next (m4 *context, m4_module *module)
-{
- return module ? module->next : context->modules;
-}
-
-/* Return the first loaded module that passes the registered interface test
- and is called NAME. */
-m4_module *
-m4__module_find (m4 *context, const char *name)
-{
- m4_module **pmodule = (m4_module **) m4_hash_lookup (context->namemap, name);
- return pmodule ? *pmodule : NULL;
-}
-
-
-/* Compare two builtins A and B for sorting, as in qsort. */
-static int
-compare_builtin_CB (const void *a, const void *b)
-{
- const m4__builtin *builtin_a = (const m4__builtin *) a;
- const m4__builtin *builtin_b = (const m4__builtin *) b;
- int result = strcmp (builtin_a->builtin.name, builtin_b->builtin.name);
- /* A builtin module should never provide two builtins with the same
- name. */
- assert (result || a == b);
- return result;
-}
-
-/* Load a module. NAME can be a absolute file name or, if relative,
- it is searched for in the module path. The module is unloaded in
- case of error. */
-m4_module *
-m4__module_open (m4 *context, const char *name, m4_obstack *obs)
-{
- static const char * suffixes[] = { "", LT_MODULE_EXT, NULL };
- m4_module * module = NULL;
-
- assert (context);
-
- char *filepath = m4_path_search (context, name, suffixes);
- void *handle = NULL;
-
- if (filepath)
- {
- handle = dlopen (filepath, RTLD_NOW|RTLD_GLOBAL);
- free (filepath);
- }
-
- if (handle)
- {
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: opening file %s"),
- name ? name : MODULE_SELF_NAME,
- quotearg_style (locale_quoting_style, name));
-
- module = (m4_module *) xzalloc (sizeof *module);
- module->name = xstrdup (name);
- module->handle = handle;
- module->next = context->modules;
-
- context->modules = module;
- m4_hash_insert (context->namemap, xstrdup (name), module);
-
- /* Find and run any initializing function in the opened module,
- the first time the module is opened. */
- char *entry_point = xasprintf ("include_%s", name);
- m4_module_init_func *init_func =
- (m4_module_init_func *) dlsym (handle, entry_point);
- free (entry_point);
-
- if (init_func)
- {
- init_func (context, module, obs);
-
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: init hook called"), name);
- }
- else
- {
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("module `%s' has no entry point"), name);
- }
-
- m4_debug_message (context, M4_DEBUG_TRACE_MODULE,
- _("module %s: opened"), name);
- }
- else
- {
- const char *err = dlerror ();
- if (!err) err = _("unknown error");
-
- /* Couldn't open the module; diagnose and exit. */
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("cannot open module `%s': %s"), name, err);
- }
-
- return module;
-}
diff --git a/m4/output.c b/m4/output.c
deleted file mode 100644
index b9371956..00000000
--- a/m4/output.c
+++ /dev/null
@@ -1,1119 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 1998, 2002, 2004, 2006-2010, 2013-2014, 2017
- Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include <sys/stat.h>
-
-#include "m4private.h"
-
-#include "binary-io.h"
-#include "clean-temp.h"
-#include "exitfail.h"
-#include "gl_avltree_oset.h"
-#include "gl_xoset.h"
-#include "intprops.h"
-#include "quotearg.h"
-#include "xvasprintf.h"
-
-/* Define this to see runtime debug output. Implied by DEBUG. */
-/*#define DEBUG_OUTPUT */
-
-/* Size of initial in-memory buffer size for diversions. Small diversions
- would usually fit in. */
-#define INITIAL_BUFFER_SIZE 512
-
-/* Maximum value for the total of all in-memory buffer sizes for
- diversions. */
-#define MAXIMUM_TOTAL_SIZE (512 * 1024)
-
-/* Size of buffer size to use while copying files. */
-#define COPY_BUFFER_SIZE (32 * 512)
-
-/* Output functions. Most of the complexity is for handling cpp like
- sync lines.
-
- This code is fairly entangled with the code in input.c, and maybe it
- belongs there? */
-
-typedef struct temp_dir m4_temp_dir;
-
-/* When part of diversion_table, each struct m4_diversion either
- represents an open file (zero size, non-NULL u.file), an in-memory
- buffer (non-zero size, non-NULL u.buffer), or an unused placeholder
- diversion (zero size, u is NULL, non-zero used indicates that a
- temporary file exists). When not part of diversion_table, u.next
- is a pointer to the free_list chain. */
-
-typedef struct m4_diversion m4_diversion;
-
-struct m4_diversion
- {
- union
- {
- FILE *file; /* Diversion file on disk. */
- char *buffer; /* Malloc'd diversion buffer. */
- m4_diversion *next; /* Free-list pointer */
- } u;
- int divnum; /* Which diversion this represents. */
- size_t size; /* Usable size before reallocation. */
- size_t used; /* Used buffer length, or tmp file exists. */
- };
-
-/* Sorted set of diversions 1 through INT_MAX. */
-static gl_oset_t diversion_table;
-
-/* Diversion 0 (not part of diversion_table). */
-static m4_diversion div0;
-
-/* Linked list of reclaimed diversion storage. */
-static m4_diversion *free_list;
-
-/* Obstack from which diversion storage is allocated. */
-static m4_obstack diversion_storage;
-
-/* Total size of all in-memory buffer sizes. */
-static size_t total_buffer_size;
-
-/* Current output diversion, NULL if output is being currently
- discarded. output_diversion->u is guaranteed non-NULL except when
- the diversion has never been used; use size to determine if it is a
- malloc'd buffer or a FILE. output_diversion->used is 0 if u.file
- is stdout, and non-zero if this is a malloc'd buffer or a temporary
- diversion file. */
-static m4_diversion *output_diversion;
-
-/* Cache of output_diversion->u.file, only valid when
- output_diversion->size is 0. */
-static FILE *output_file;
-
-/* Cache of output_diversion->u.buffer + output_diversion->used, only
- valid when output_diversion->size is non-zero. */
-static char *output_cursor;
-
-/* Cache of output_diversion->size - output_diversion->used, only
- valid when output_diversion->size is non-zero. */
-static size_t output_unused;
-
-/* Temporary directory holding all spilled diversion files. */
-static m4_temp_dir *output_temp_dir;
-
-/* Cache of most recently used spilled diversion files. */
-static FILE *tmp_file1;
-static FILE *tmp_file2;
-
-/* Diversions that own tmp_file, or 0. */
-static int tmp_file1_owner;
-static int tmp_file2_owner;
-
-/* True if tmp_file2 is more recently used. */
-static bool tmp_file2_recent;
-
-
-/* Internal routines. */
-
-/* Callback for comparing list elements ELT1 and ELT2 for order in
- diversion_table. */
-static int
-cmp_diversion_CB (const void *elt1, const void *elt2)
-{
- const m4_diversion *d1 = (const m4_diversion *) elt1;
- const m4_diversion *d2 = (const m4_diversion *) elt2;
- /* No need to worry about overflow, since we don't create diversions
- with negative divnum. */
- return d1->divnum - d2->divnum;
-}
-
-/* Callback for comparing list element ELT against THRESHOLD. */
-static bool
-threshold_diversion_CB (const void *elt, const void *threshold)
-{
- const m4_diversion *diversion = (const m4_diversion *) elt;
- /* No need to worry about overflow, since we don't create diversions
- with negative divnum. */
- return diversion->divnum >= *(const int *) threshold;
-}
-
-/* Clean up any temporary directory. Designed for use as an atexit
- handler, where it is not safe to call exit() recursively; so this
- calls _exit if a problem is encountered. */
-static void
-cleanup_tmpfile (void)
-{
- /* Close any open diversions. */
- bool fail = false;
-
- if (diversion_table)
- {
- const void *elt;
- gl_oset_iterator_t iter = gl_oset_iterator (diversion_table);
- while (gl_oset_iterator_next (&iter, &elt))
- {
- m4_diversion *diversion = (m4_diversion *) elt;
- if (!diversion->size && diversion->u.file
- && close_stream_temp (diversion->u.file) != 0)
- {
- error (0, errno,
- _("cannot clean temporary file for diversion"));
- fail = true;
- }
- }
- gl_oset_iterator_free (&iter);
- }
-
- /* Clean up the temporary directory. */
- if (cleanup_temp_dir (output_temp_dir) != 0)
- fail = true;
- if (fail)
- _exit (exit_failure);
-}
-
-/* Convert DIVNUM into a temporary file name for use in m4_tmp*. */
-static const char *
-m4_tmpname (int divnum)
-{
- static char *buffer;
- static size_t offset;
- if (buffer == NULL)
- {
- obstack_printf (&diversion_storage, "%s/m4-", output_temp_dir->dir_name);
- offset = obstack_object_size (&diversion_storage);
- buffer = (char *) obstack_alloc (&diversion_storage,
- INT_BUFSIZE_BOUND (divnum));
- }
- assert (0 < divnum);
- if (snprintf (&buffer[offset], INT_BUFSIZE_BOUND (divnum), "%d", divnum) < 0)
- abort ();
- return buffer;
-}
-
-/* Create a temporary file for diversion DIVNUM open for reading and
- writing in a secure temp directory. The file will be automatically
- closed and deleted on a fatal signal. The file can be closed and
- reopened with m4_tmpclose and m4_tmpopen, or moved with
- m4_tmprename; when finally done with the file, close it with
- m4_tmpremove. Exits on failure, so the return value is always an
- open file. */
-static FILE *
-m4_tmpfile (m4 *context, int divnum)
-{
- const char *name;
- FILE *file;
-
- if (output_temp_dir == NULL)
- {
- output_temp_dir = create_temp_dir ("m4-", NULL, true);
- if (output_temp_dir == NULL)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot create temporary file for diversion"));
- atexit (cleanup_tmpfile);
- }
- name = m4_tmpname (divnum);
- register_temp_file (output_temp_dir, name);
- file = fopen_temp (name, O_BINARY ? "wb+" : "w+");
- if (file == NULL)
- {
- unregister_temp_file (output_temp_dir, name);
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot create temporary file for diversion"));
- }
- else if (set_cloexec_flag (fileno (file), true) != 0)
- m4_warn (context, errno, NULL, _("cannot protect diversion across forks"));
- return file;
-}
-
-/* Reopen a temporary file for diversion DIVNUM for reading and
- writing in a secure temp directory. If REREAD, the file is
- positioned at offset 0, otherwise the file is positioned at the
- end. Exits on failure, so the return value is always an open
- file. */
-static FILE *
-m4_tmpopen (m4 *context, int divnum, bool reread)
-{
- const char *name;
- FILE *file;
-
- if (tmp_file1_owner == divnum)
- {
- if (reread && fseeko (tmp_file1, 0, SEEK_SET) != 0)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot seek within diversion"));
- tmp_file2_recent = false;
- return tmp_file1;
- }
- else if (tmp_file2_owner == divnum)
- {
- if (reread && fseeko (tmp_file2, 0, SEEK_SET) != 0)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot seek to beginning of diversion"));
- tmp_file2_recent = true;
- return tmp_file2;
- }
- name = m4_tmpname (divnum);
- /* We need update mode, to avoid truncation. */
- file = fopen_temp (name, O_BINARY ? "rb+" : "r+");
- if (file == NULL)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot create temporary file for diversion"));
- else if (set_cloexec_flag (fileno (file), true) != 0)
- m4_warn (context, errno, NULL, _("cannot protect diversion across forks"));
- /* Update mode starts at the beginning of the stream, but sometimes
- we want the end. */
- else if (!reread && fseeko (file, 0, SEEK_END) != 0)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot seek within diversion"));
- return file;
-}
-
-/* Close, but don't delete, a temporary FILE for diversion DIVNUM. To
- reduce the I/O overhead of repeatedly opening and closing the same
- file, this implementation caches the most recent spilled diversion.
- On the other hand, keeping every spilled diversion open would run
- into EMFILE limits. */
-static int
-m4_tmpclose (FILE *file, int divnum)
-{
- int result = 0;
- if (divnum != tmp_file1_owner && divnum != tmp_file2_owner)
- {
- if (tmp_file2_recent)
- {
- if (tmp_file1_owner)
- result = close_stream_temp (tmp_file1);
- tmp_file1 = file;
- tmp_file1_owner = divnum;
- }
- else
- {
- if (tmp_file2_owner)
- result = close_stream_temp (tmp_file2);
- tmp_file2 = file;
- tmp_file2_owner = divnum;
- }
- }
- return result;
-}
-
-/* Delete a closed temporary FILE for diversion DIVNUM. */
-static int
-m4_tmpremove (int divnum)
-{
- if (divnum == tmp_file1_owner)
- {
- int result = close_stream_temp (tmp_file1);
- if (result)
- return result;
- tmp_file1_owner = 0;
- }
- else if (divnum == tmp_file2_owner)
- {
- int result = close_stream_temp (tmp_file2);
- if (result)
- return result;
- tmp_file2_owner = 0;
- }
- return cleanup_temp_file (output_temp_dir, m4_tmpname (divnum));
-}
-
-/* Transfer the temporary file for diversion OLDNUM to the previously
- unused diversion NEWNUM. Return an open stream visiting the new
- temporary file, positioned at the end, or exit on failure. */
-static FILE*
-m4_tmprename (m4 *context, int oldnum, int newnum)
-{
- /* m4_tmpname reuses its return buffer. */
- char *oldname = xstrdup (m4_tmpname (oldnum));
- const char *newname = m4_tmpname (newnum);
- register_temp_file (output_temp_dir, newname);
- if (oldnum == tmp_file1_owner)
- {
- /* Be careful of mingw, which can't rename an open file. */
- if (RENAME_OPEN_FILE_WORKS)
- tmp_file1_owner = newnum;
- else
- {
- if (close_stream_temp (tmp_file1))
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot close temporary file for diversion"));
- tmp_file1_owner = 0;
- }
- }
- else if (oldnum == tmp_file2_owner)
- {
- /* Be careful of mingw, which can't rename an open file. */
- if (RENAME_OPEN_FILE_WORKS)
- tmp_file2_owner = newnum;
- else
- {
- if (close_stream_temp (tmp_file2))
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot close temporary file for diversion"));
- tmp_file2_owner = 0;
- }
- }
- /* Either it is safe to rename an open file, or no one should have
- oldname open at this point. */
- if (rename (oldname, newname))
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot create temporary file for diversion"));
- unregister_temp_file (output_temp_dir, oldname);
- free (oldname);
- return m4_tmpopen (context, newnum, false);
-}
-
-
-/* --- OUTPUT INITIALIZATION --- */
-
-/* Initialize the output engine. */
-void
-m4_output_init (m4 *context)
-{
- diversion_table = gl_oset_create_empty (GL_AVLTREE_OSET, cmp_diversion_CB,
- NULL);
- div0.u.file = stdout;
- m4_set_current_diversion (context, 0);
- output_diversion = &div0;
- output_file = stdout;
- obstack_init (&diversion_storage);
-}
-
-/* Clean up memory allocated during use. */
-void
-m4_output_exit (void)
-{
- /* Order is important, since we may have registered cleanup_tmpfile
- as an atexit handler, and it must not traverse stale memory. */
- gl_oset_t table = diversion_table;
- assert (gl_oset_size (diversion_table) == 0);
- if (tmp_file1_owner)
- m4_tmpremove (tmp_file1_owner);
- if (tmp_file2_owner)
- m4_tmpremove (tmp_file2_owner);
- diversion_table = NULL;
- gl_oset_free (table);
- obstack_free (&diversion_storage, NULL);
-}
-
-/* Reorganize in-memory diversion buffers so the current diversion can
- accomodate LENGTH more characters without further reorganization. The
- current diversion buffer is made bigger if possible. But to make room
- for a bigger buffer, one of the in-memory diversion buffers might have
- to be flushed to a newly created temporary file. This flushed buffer
- might well be the current one. */
-static void
-make_room_for (m4 *context, size_t length)
-{
- size_t wanted_size;
- m4_diversion *selected_diversion = NULL;
-
- assert (!output_file);
- assert (output_diversion);
- assert (output_diversion->size || !output_diversion->u.file);
-
- /* Compute needed size for in-memory buffer. Diversions in-memory
- buffers start at 0 bytes, then 512, then keep doubling until it is
- decided to flush them to disk. */
-
- output_diversion->used = output_diversion->size - output_unused;
-
- for (wanted_size = output_diversion->size;
- wanted_size <= MAXIMUM_TOTAL_SIZE
- && wanted_size - output_diversion->used < length;
- wanted_size = wanted_size == 0 ? INITIAL_BUFFER_SIZE : wanted_size * 2)
- ;
-
- /* Check if we are exceeding the maximum amount of buffer memory. */
-
- if (total_buffer_size - output_diversion->size + wanted_size
- > MAXIMUM_TOTAL_SIZE)
- {
- size_t selected_used;
- char *selected_buffer;
- m4_diversion *diversion;
- size_t count;
- gl_oset_iterator_t iter;
- const void *elt;
-
- /* Find out the buffer having most data, in view of flushing it to
- disk. Fake the current buffer as having already received the
- projected data, while making the selection. So, if it is
- selected indeed, we will flush it smaller, before it grows. */
-
- selected_diversion = output_diversion;
- selected_used = output_diversion->used + length;
-
- iter = gl_oset_iterator (diversion_table);
- while (gl_oset_iterator_next (&iter, &elt))
- {
- diversion = (m4_diversion *) elt;
- if (diversion->used > selected_used)
- {
- selected_diversion = diversion;
- selected_used = diversion->used;
- }
- }
- gl_oset_iterator_free (&iter);
-
- /* Create a temporary file, write the in-memory buffer of the
- diversion to this file, then release the buffer. Zero the
- diversion before doing anything that can exit () (including
- m4_tmpfile), so that the atexit handler doesn't try to close
- a garbage pointer as a file. */
-
- selected_buffer = selected_diversion->u.buffer;
- total_buffer_size -= selected_diversion->size;
- selected_diversion->size = 0;
- selected_diversion->u.file = NULL;
- selected_diversion->u.file = m4_tmpfile (context,
- selected_diversion->divnum);
-
- if (selected_diversion->used > 0)
- {
- count = fwrite (selected_buffer, selected_diversion->used, 1,
- selected_diversion->u.file);
- if (count != 1)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot flush diversion to temporary file"));
- }
-
- /* Reclaim the buffer space for other diversions. */
-
- free (selected_buffer);
- selected_diversion->used = 1;
- }
-
- /* Reload output_file, just in case the flushed diversion was current. */
-
- if (output_diversion == selected_diversion)
- {
- /* The flushed diversion was current indeed. */
-
- output_file = output_diversion->u.file;
- output_cursor = NULL;
- output_unused = 0;
- }
- else
- {
- /* Close any selected file since it is not the current diversion. */
- if (selected_diversion)
- {
- FILE *file = selected_diversion->u.file;
- selected_diversion->u.file = NULL;
- if (m4_tmpclose (file, selected_diversion->divnum) != 0)
- m4_error (context, 0, errno, NULL,
- _("cannot close temporary file for diversion"));
- }
-
- /* The current buffer may be safely reallocated. */
- assert (wanted_size >= length);
- {
- char *buffer = output_diversion->u.buffer;
- output_diversion->u.buffer = xcharalloc ((size_t) wanted_size);
- memcpy (output_diversion->u.buffer, buffer, output_diversion->used);
- free (buffer);
- }
-
- total_buffer_size += wanted_size - output_diversion->size;
- output_diversion->size = wanted_size;
-
- output_cursor = output_diversion->u.buffer + output_diversion->used;
- output_unused = wanted_size - output_diversion->used;
- }
-}
-
-/* Output one character CHAR, when it is known that it goes to a
- diversion file or an in-memory diversion buffer. A variable m4
- *context must be in scope. */
-#define OUTPUT_CHARACTER(Char) \
- if (output_file) \
- putc ((Char), output_file); \
- else if (output_unused == 0) \
- output_character_helper (context, (Char)); \
- else \
- (output_unused--, *output_cursor++ = (Char))
-
-static void
-output_character_helper (m4 *context, int character)
-{
- make_room_for (context, 1);
-
- if (output_file)
- putc (character, output_file);
- else
- {
- *output_cursor++ = character;
- output_unused--;
- }
-}
-
-/* Output one TEXT having LENGTH characters, when it is known that it goes
- to a diversion file or an in-memory diversion buffer. */
-void
-m4_output_text (m4 *context, const char *text, size_t length)
-{
- size_t count;
-
- if (!output_diversion || !length)
- return;
-
- if (!output_file && length > output_unused)
- make_room_for (context, length);
-
- if (output_file)
- {
- count = fwrite (text, length, 1, output_file);
- if (count != 1)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("copying inserted file"));
- }
- else
- {
- memcpy (output_cursor, text, length);
- output_cursor += length;
- output_unused -= length;
- }
-}
-
-/* Add some text into an obstack OBS, taken from TEXT, having LENGTH
- characters. If OBS is NULL, output the text to an external file or
- an in-memory diversion buffer instead. If OBS is NULL, and there
- is no output file, the text is discarded. LINE is the line where
- the token starts (not necessarily m4_get_output_line, in the case
- of multiline tokens).
-
- If we are generating sync lines, the output has to be examined,
- because we need to know how much output each input line generates.
- In general, sync lines are output whenever a single input line
- generates several output lines, or when several input lines do not
- generate any output. */
-void
-m4_divert_text (m4 *context, m4_obstack *obs, const char *text, size_t length,
- int line)
-{
- static bool start_of_output_line = true;
-
- /* If output goes to an obstack, merely add TEXT to it. */
-
- if (obs != NULL)
- {
- obstack_grow (obs, text, length);
- return;
- }
-
- /* Do nothing if TEXT should be discarded. */
-
- if (!output_diversion || !length)
- return;
-
- /* Output TEXT to a file, or in-memory diversion buffer. */
-
- if (!m4_get_syncoutput_opt (context))
- switch (length)
- {
-
- /* In-line short texts. */
-
- case 8: OUTPUT_CHARACTER (*text); text++;
- case 7: OUTPUT_CHARACTER (*text); text++;
- case 6: OUTPUT_CHARACTER (*text); text++;
- case 5: OUTPUT_CHARACTER (*text); text++;
- case 4: OUTPUT_CHARACTER (*text); text++;
- case 3: OUTPUT_CHARACTER (*text); text++;
- case 2: OUTPUT_CHARACTER (*text); text++;
- case 1: OUTPUT_CHARACTER (*text);
- case 0:
- return;
-
- /* Optimize longer texts. */
-
- default:
- m4_output_text (context, text, length);
- }
- else
- {
- /* Check for syncline only at the start of a token. Multiline
- tokens, and tokens that are out of sync but in the middle of
- the line, must wait until the next raw newline triggers a
- syncline. */
- if (start_of_output_line)
- {
- start_of_output_line = false;
- m4_set_output_line (context, m4_get_output_line (context) + 1);
-
-#ifdef DEBUG_OUTPUT
- xfprintf (stderr, "DEBUG: line %d, cur %lu, cur out %lu\n", line,
- (unsigned long int) m4_get_current_line (context),
- (unsigned long int) m4_get_output_line (context));
-#endif
-
- /* Output a `#line NUM' synchronization directive if needed.
- If output_line was previously given a negative
- value (invalidated), then output `#line NUM "FILE"'. */
-
- if (m4_get_output_line (context) != line)
- {
- char linebuf[sizeof "#line " + INT_BUFSIZE_BOUND (line)];
- sprintf (linebuf, "#line %lu",
- (unsigned long int) m4_get_current_line (context));
- m4_output_text (context, linebuf, strlen (linebuf));
- if (m4_get_output_line (context) < 1
- && m4_get_current_file (context)[0] != '\0')
- {
- const char *file = m4_get_current_file (context);
- OUTPUT_CHARACTER (' ');
- OUTPUT_CHARACTER ('"');
- m4_output_text (context, file, strlen (file));
- OUTPUT_CHARACTER ('"');
- }
- OUTPUT_CHARACTER ('\n');
- m4_set_output_line (context, line);
- }
- }
-
- /* Output the token, and track embedded newlines. */
- for (; length-- > 0; text++)
- {
- if (start_of_output_line)
- {
- start_of_output_line = false;
- m4_set_output_line (context, m4_get_output_line (context) + 1);
-
-#ifdef DEBUG_OUTPUT
- xfprintf (stderr, "DEBUG: line %d, cur %lu, cur out %lu\n", line,
- (unsigned long int) m4_get_current_line (context),
- (unsigned long int) m4_get_output_line (context));
-#endif
- }
- OUTPUT_CHARACTER (*text);
- if (*text == '\n')
- start_of_output_line = true;
- }
- }
-}
-
-/* Format an int VAL, and stuff it into an obstack OBS. Used for
- macros expanding to numbers. FIXME - support wider types, and
- unsigned types. */
-void
-m4_shipout_int (m4_obstack *obs, int val)
-{
- /* Using obstack_printf (obs, "%d", val) has too much overhead. */
- unsigned int uval;
- char buf[INT_BUFSIZE_BOUND (unsigned int)];
- char *p = buf + INT_STRLEN_BOUND (unsigned int);
-
- if (val < 0)
- {
- obstack_1grow (obs, '-');
- uval = -(unsigned int) val;
- }
- else
- uval = val;
- *p = '\0';
- do
- *--p = '0' + uval % 10;
- while (uval /= 10);
- obstack_grow (obs, p, strlen (p));
-}
-
-/* Output the text S, of length LEN, to OBS. If QUOTED, also output
- current quote characters around S. If LEN is SIZE_MAX, use the
- string length of S instead. */
-void
-m4_shipout_string (m4 *context, m4_obstack *obs, const char *s, size_t len,
- bool quoted)
-{
- m4_shipout_string_trunc (obs, s, len,
- quoted ? m4_get_syntax_quotes (M4SYNTAX) : NULL,
- NULL);
-}
-
-/* Output the text S, of length LEN, to OBS. If QUOTES, also output
- quote characters around S. If LEN is SIZE_MAX, use the string
- length of S instead. If MAX_LEN, reduce *MAX_LEN by LEN. If LEN
- is larger than *MAX_LEN, then truncate output and return true;
- otherwise return false. Quotes do not count against MAX_LEN. */
-bool
-m4_shipout_string_trunc (m4_obstack *obs, const char *s, size_t len,
- const m4_string_pair *quotes, size_t *max_len)
-{
- size_t max = max_len ? *max_len : SIZE_MAX;
-
- assert (obs && s);
- if (len == SIZE_MAX)
- len = strlen (s);
- if (quotes)
- obstack_grow (obs, quotes->str1, quotes->len1);
- if (len < max)
- {
- obstack_grow (obs, s, len);
- max -= len;
- }
- else
- {
- obstack_grow (obs, s, max);
- obstack_grow (obs, "...", 3);
- max = 0;
- }
- if (quotes)
- obstack_grow (obs, quotes->str2, quotes->len2);
- if (max_len)
- *max_len = max;
- return max == 0;
-}
-
-
-
-/* --- FUNCTIONS FOR USE BY DIVERSIONS --- */
-
-/* Make a file for diversion DIVNUM, and install it in the diversion table.
- Grow the size of the diversion table as needed. */
-
-/* The number of possible diversions is limited only by memory and
- available file descriptors (each overflowing diversion uses one). */
-
-void
-m4_make_diversion (m4 *context, int divnum)
-{
- m4_diversion *diversion = NULL;
-
- if (m4_get_current_diversion (context) == divnum)
- return;
-
- if (output_diversion)
- {
- assert (!output_file || output_diversion->u.file == output_file);
- assert (output_diversion->divnum != divnum);
- if (!output_diversion->size && !output_diversion->u.file)
- {
- assert (!output_diversion->used);
- if (!gl_oset_remove (diversion_table, output_diversion))
- assert (false);
- output_diversion->u.next = free_list;
- free_list = output_diversion;
- }
- else if (output_diversion->size)
- output_diversion->used = output_diversion->size - output_unused;
- else if (output_diversion->used)
- {
- assert (output_diversion->divnum != 0);
- FILE *file = output_diversion->u.file;
- output_diversion->u.file = NULL;
- if (m4_tmpclose (file, output_diversion->divnum) != 0)
- m4_error (context, 0, errno, NULL,
- _("cannot close temporary file for diversion"));
- }
- output_diversion = NULL;
- output_file = NULL;
- output_cursor = NULL;
- output_unused = 0;
- }
-
- m4_set_current_diversion (context, divnum);
-
- if (divnum < 0)
- return;
-
- if (divnum == 0)
- diversion = &div0;
- else
- {
- const void *elt;
- if (gl_oset_search_atleast (diversion_table, threshold_diversion_CB,
- &divnum, &elt))
- {
- m4_diversion *temp = (m4_diversion *) elt;
- if (temp->divnum == divnum)
- diversion = temp;
- }
- }
- if (diversion == NULL)
- {
- /* First time visiting this diversion. */
- if (free_list)
- {
- diversion = free_list;
- free_list = diversion->u.next;
- assert (!diversion->size && !diversion->used);
- }
- else
- {
- diversion = (m4_diversion *) obstack_alloc (&diversion_storage,
- sizeof *diversion);
- diversion->size = 0;
- diversion->used = 0;
- }
- diversion->u.file = NULL;
- diversion->divnum = divnum;
- if (!gl_oset_add (diversion_table, diversion))
- assert (false);
- }
-
- output_diversion = diversion;
- if (output_diversion->size)
- {
- output_cursor = output_diversion->u.buffer + output_diversion->used;
- output_unused = output_diversion->size - output_diversion->used;
- }
- else
- {
- if (!output_diversion->u.file && output_diversion->used)
- output_diversion->u.file = m4_tmpopen (context,
- output_diversion->divnum,
- false);
- output_file = output_diversion->u.file;
- }
-
- m4_set_output_line (context, -1);
-}
-
-/* Insert a FILE into the current output file, in the same manner
- diversions are handled. If ESCAPED, ensure the output is all
- ASCII. */
-static void
-insert_file (m4 *context, FILE *file, bool escaped)
-{
- static char buffer[COPY_BUFFER_SIZE];
- size_t length;
- char *str = buffer;
- bool first = true;
-
- assert (output_diversion);
- /* Insert output by big chunks. */
- while (1)
- {
- length = fread (buffer, 1, sizeof buffer, file);
- if (ferror (file))
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("reading inserted file"));
- if (length == 0)
- break;
- if (escaped)
- {
- if (first)
- first = false;
- else
- m4_output_text (context, "\\\n", 2);
- str = quotearg_style_mem (escape_quoting_style, buffer, length);
- }
- m4_output_text (context, str, escaped ? strlen (str) : length);
- }
-}
-
-/* Insert a FILE into the current output file, in the same manner
- diversions are handled. This allows files to be included, without
- having them rescanned by m4. */
-void
-m4_insert_file (m4 *context, FILE *file)
-{
- /* Optimize out inserting into a sink. */
- if (output_diversion)
- insert_file (context, file, false);
-}
-
-/* Insert DIVERSION living at NODE into the current output file. The
- diversion is NOT placed on the expansion obstack, because it must
- not be rescanned. If ESCAPED, ensure the output is ASCII. When
- the file is closed, it is deleted by the system. */
-static void
-insert_diversion_helper (m4 *context, m4_diversion *diversion, bool escaped)
-{
- assert (diversion->divnum > 0
- && diversion->divnum != m4_get_current_diversion (context));
- /* Effectively undivert only if an output stream is active. */
- if (output_diversion)
- {
- if (diversion->size)
- {
- if (!output_diversion->u.file)
- {
- /* Transferring diversion metadata is faster than
- copying contents. */
- assert (!output_diversion->used && output_diversion != &div0
- && !output_file);
- output_diversion->u.buffer = diversion->u.buffer;
- output_diversion->size = diversion->size;
- output_cursor = diversion->u.buffer + diversion->used;
- output_unused = diversion->size - diversion->used;
- diversion->u.buffer = NULL;
- }
- else
- {
- char *str = diversion->u.buffer;
- size_t len = diversion->used;
- /* Avoid double-charging the total in-memory size when
- transferring from one in-memory diversion to
- another. */
- total_buffer_size -= diversion->size;
- if (escaped)
- str = quotearg_style_mem (escape_quoting_style, str, len);
- m4_output_text (context, str, escaped ? strlen (str) : len);
- }
- }
- else if (!output_diversion->u.file)
- {
- /* Transferring diversion metadata is faster than copying
- contents. */
- assert (!output_diversion->used && output_diversion != &div0
- && !output_file);
- output_diversion->u.file = m4_tmprename (context, diversion->divnum,
- output_diversion->divnum);
- output_diversion->used = 1;
- output_file = output_diversion->u.file;
- diversion->u.file = NULL;
- diversion->size = 1;
- }
- else
- {
- assert (diversion->used);
- if (!diversion->u.file)
- diversion->u.file = m4_tmpopen (context, diversion->divnum, true);
- insert_file (context, diversion->u.file, escaped);
- }
-
- m4_set_output_line (context, -1);
- }
-
- /* Return all space used by the diversion. */
- if (diversion->size)
- {
- if (!output_diversion)
- total_buffer_size -= diversion->size;
- free (diversion->u.buffer);
- diversion->size = 0;
- }
- else
- {
- if (diversion->u.file)
- {
- FILE *file = diversion->u.file;
- diversion->u.file = NULL;
- if (m4_tmpclose (file, diversion->divnum) != 0)
- m4_error (context, 0, errno, NULL,
- _("cannot clean temporary file for diversion"));
- }
- if (m4_tmpremove (diversion->divnum) != 0)
- m4_error (context, 0, errno, NULL,
- _("cannot clean temporary file for diversion"));
- }
- diversion->used = 0;
- if (!gl_oset_remove (diversion_table, diversion))
- assert (false);
- diversion->u.next = free_list;
- free_list = diversion;
-}
-
-/* Insert diversion number DIVNUM into the current output file. The
- diversion is NOT placed on the expansion obstack, because it must not
- be rescanned. When the file is closed, it is deleted by the system. */
-void
-m4_insert_diversion (m4 *context, int divnum)
-{
- const void *elt;
-
- /* Do not care about nonexistent diversions, and undiverting stdout
- or self is a no-op. */
- if (divnum <= 0 || m4_get_current_diversion (context) == divnum)
- return;
- if (gl_oset_search_atleast (diversion_table, threshold_diversion_CB,
- &divnum, &elt))
- {
- m4_diversion *diversion = (m4_diversion *) elt;
- if (diversion->divnum == divnum)
- insert_diversion_helper (context, diversion, false);
- }
-}
-
-/* Get back all diversions. This is done just before exiting from main,
- and from m4_undivert (), if called without arguments. */
-void
-m4_undivert_all (m4 *context)
-{
- int divnum = m4_get_current_diversion (context);
- const void *elt;
- gl_oset_iterator_t iter = gl_oset_iterator (diversion_table);
- while (gl_oset_iterator_next (&iter, &elt))
- {
- m4_diversion *diversion = (m4_diversion *) elt;
- if (diversion->divnum != divnum)
- insert_diversion_helper (context, diversion, false);
- }
- gl_oset_iterator_free (&iter);
-}
-
-/* Produce all diversion information in frozen format on FILE. */
-void
-m4_freeze_diversions (m4 *context, FILE *file)
-{
- int saved_number;
- int last_inserted;
- gl_oset_iterator_t iter;
- const void *elt;
-
- saved_number = m4_get_current_diversion (context);
- last_inserted = 0;
- m4_make_diversion (context, 0);
- output_file = file; /* kludge in the frozen file */
-
- iter = gl_oset_iterator (diversion_table);
- while (gl_oset_iterator_next (&iter, &elt))
- {
- m4_diversion *diversion = (m4_diversion *) elt;
- if (diversion->size || diversion->used)
- {
- if (diversion->size)
- {
- assert (diversion->used == (int) diversion->used);
- xfprintf (file, "D%d,%d\n", diversion->divnum,
- (int) diversion->used);
- }
- else
- {
- struct stat file_stat;
- assert (!diversion->u.file);
- diversion->u.file = m4_tmpopen (context, diversion->divnum,
- true);
- if (fstat (fileno (diversion->u.file), &file_stat) < 0)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("cannot stat diversion"));
- /* FIXME - support 64-bit off_t with 32-bit long, and
- fix frozen file format to support 64-bit integers.
- This implies fixing m4_divert_text to take off_t. */
- if (file_stat.st_size < 0
- || file_stat.st_size != (unsigned long int) file_stat.st_size)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("diversion too large"));
- xfprintf (file, "%c%d,%lu\n", 'D', diversion->divnum,
- (unsigned long int) file_stat.st_size);
- }
-
- insert_diversion_helper (context, diversion, true);
- putc ('\n', file);
-
- last_inserted = diversion->divnum;
- }
- }
- gl_oset_iterator_free (&iter);
-
- /* Save the active diversion number, if not already. */
-
- if (saved_number != last_inserted)
- xfprintf (file, "D%d,0\n\n", saved_number);
-}
diff --git a/m4/path.c b/m4/path.c
deleted file mode 100644
index 0c6a962d..00000000
--- a/m4/path.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1993, 1998, 2004, 2006-2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* Handling of path search of included files via the builtins "include"
- and "sinclude". */
-
-#include <config.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "m4private.h"
-
-#include "configmake.h"
-#include "dirname.h"
-#include "filenamecat.h"
-
-#if OS2 /* Any others? */
-# define TRUNCATE_FILENAME 1
-#endif
-
-/* Define this to see runtime debug info. Implied by DEBUG. */
-/*#define DEBUG_INCL */
-
-static const char *FILE_SUFFIXES[] = {
- "",
- ".m4f",
- ".m4",
- LT_MODULE_EXT,
- NULL
-};
-
-static const char *NO_SUFFIXES[] = { "", NULL };
-
-static void search_path_add (m4__search_path_info *, const char *, bool);
-static void search_path_env_init (m4__search_path_info *, char *, bool);
-static void include_env_init (m4 *context);
-
-#ifdef DEBUG_INCL
-static void include_dump (m4 *context);
-#endif
-
-
-/*
- * General functions for search paths
- */
-
-static void
-search_path_add (m4__search_path_info *info, const char *dir, bool prepend)
-{
- m4__search_path *path = (m4__search_path *) xmalloc (sizeof *path);
-
- path->len = strlen (dir);
- path->dir = xstrdup (dir);
-
- if (path->len > info->max_length) /* remember len of longest directory */
- info->max_length = path->len;
-
- if (prepend)
- {
- path->next = info->list;
- info->list = path;
- if (info->list_end == NULL)
- info->list_end = path;
- }
- else
- {
- path->next = NULL;
-
- if (info->list_end == NULL)
- info->list = path;
- else
- info->list_end->next = path;
- info->list_end = path;
- }
-}
-
-static void
-search_path_env_init (m4__search_path_info *info, char *path, bool isabs)
-{
- char *path_end;
-
- if (info == NULL || path == NULL)
- return;
-
- do
- {
- path_end = strchr (path, PATH_SEPARATOR);
- if (path_end)
- *path_end = '\0';
- if (!isabs || *path == '/')
- search_path_add (info, path, false);
- path = path_end + 1;
- }
- while (path_end);
-}
-
-static void
-include_env_init (m4 *context)
-{
- char *m4path;
-
- if (m4_get_posixly_correct_opt (context))
- return;
-
- m4path = getenv ("M4PATH");
- if (m4path)
- m4path = xstrdup (m4path);
- search_path_env_init (m4__get_search_path (context), m4path, false);
- free (m4path);
-}
-
-
-#if TRUNCATE_FILENAME
-/* Destructively modify PATH to contain no more than 8 non-`.'
- characters, optionally followed by a `.' and a filenname extension
- of 3 characters or fewer. */
-static char *
-path_truncate (char *path)
-{
- char *p, *beg = path; /* following final '/' */
- for (p = path; *p != '\0'; ++p)
- {
- if (ISSLASH (*p))
- beg = 1+ p;
- }
-
- char *end = strchr (beg, '.'); /* first period */
- char *ext = strrchr (beg, '.'); /* last period */
-
- size_t len = (size_t) (end - beg); /* length of filename element */
- if (len > 8)
- end = beg + 8;
-
- if (ext == NULL)
- {
- *end = '\0';
- }
- else if (ext != end)
- {
- stpncpy (end, ext, 4);
- }
-
- return path;
-}
-#endif
-
-
-
-/* Functions for normal input path search */
-
-void
-m4_add_include_directory (m4 *context, const char *dir, bool prepend)
-{
- if (m4_get_posixly_correct_opt (context))
- return;
-
- search_path_add (m4__get_search_path (context), dir, prepend);
-
-#ifdef DEBUG_INCL
- xfprintf (stderr, "add_include_directory (%s) %s;\n", dir,
- prepend ? "prepend" : "append");
-#endif
-}
-
-
-/* Search for FILENAME according to -B options, `.', -I options, then
- M4PATH environment. If successful, return the open file, and if
- RESULT is not NULL, set *RESULT to a malloc'd string that
- represents the file found with respect to the current working
- directory. Otherwise, return NULL, and errno reflects the failure
- from searching `.' (regardless of what else was searched). */
-char *
-m4_path_search (m4 *context, const char *filename, const char **suffixes)
-{
- m4__search_path *incl;
- char *filepath; /* buffer for constructed name */
- size_t max_suffix_len = 0;
- int i, e = 0;
-
- /* Reject empty file. */
- if (*filename == '\0')
- {
- errno = ENOENT;
- return NULL;
- }
-
- /* Use no suffixes by default. */
- if (suffixes == NULL)
- suffixes = NO_SUFFIXES;
-
- /* Find the longest suffix, so that we will always allocate enough
- memory for a filename with suffix. */
- for (i = 0; suffixes && suffixes[i]; ++i)
- {
- size_t len = strlen (suffixes[i]);
- if (len > max_suffix_len)
- max_suffix_len = len;
- }
-
- /* If file is absolute, or if we are not searching a path, a single
- lookup will do the trick. */
- if (IS_ABSOLUTE_FILE_NAME (filename))
- {
- size_t mem = strlen (filename);
-
- /* Try appending each of the suffixes we were given. */
- filepath = strncpy (xmalloc (mem + max_suffix_len +1), filename, mem +1);
-#if TRUNCATE_FILENAME
- filepath = path_truncate (filepath);
- mem = strlen (filepath); /* recalculate length after truncation */
-#endif
- for (i = 0; suffixes && suffixes[i]; ++i)
- {
- strcpy (filepath + mem, suffixes[i]);
- if (access (filepath, R_OK) == 0)
- return filepath;
-
- /* If search fails, we'll use the error we got from the first
- access (usually with no suffix). */
- if (i == 0)
- e = errno;
- }
- free (filepath);
-
- /* No such file. */
- errno = e;
- return NULL;
- }
-
- for (incl = m4__get_search_path (context)->list;
- incl != NULL; incl = incl->next)
- {
- char *pathname = file_name_concat (incl->dir, filename, NULL);
- size_t mem = strlen (pathname);
-
-#ifdef DEBUG_INCL
- xfprintf (stderr, "path_search (%s) -- trying %s\n", filename, pathname);
-#endif
-
- if (access (pathname, R_OK) == 0)
- {
- m4_debug_message (context, M4_DEBUG_TRACE_PATH,
- _("path search for %s found %s"),
- quotearg_style (locale_quoting_style, filename),
- quotearg_n_style (1, locale_quoting_style, pathname));
- return pathname;
- }
- else if (!incl->len)
- /* Capture errno only when searching `.'. */
- e = errno;
-
- filepath = strncpy (xmalloc (mem + max_suffix_len +1), pathname, mem +1);
- free (pathname);
-#if TRUNCATE_FILENAME
- filepath = path_truncate (filepath);
- mem = strlen (filepath); /* recalculate length after truncation */
-#endif
-
- for (i = 0; suffixes && suffixes[i]; ++i)
- {
- strcpy (filepath + mem, suffixes[i]);
- if (access (filepath, R_OK) == 0)
- return filepath;
- }
- free (filepath);
- }
-
- errno = e;
- return NULL;
-}
-
-
-/* Attempt to open FILE; if it opens, verify that it is not a
- directory, and ensure it does not leak across execs. */
-FILE *
-m4_fopen (m4 *context, const char *file, const char *mode)
-{
- FILE *fp = NULL;
-
- if (file)
- {
- struct stat st;
- int fd;
-
- fp = fopen (file, mode);
- fd = fileno (fp);
-
- if (fstat (fd, &st) == 0 && S_ISDIR (st.st_mode))
- {
- fclose (fp);
- errno = EISDIR;
- return NULL;
- }
- if (set_cloexec_flag (fileno (fp), true) != 0)
- m4_error (context, 0, errno, NULL,
- _("cannot protect input file across forks"));
- }
- return fp;
-}
-
-
-/* Generic load function. Push the input file or load the module named
- FILENAME, if it can be found in the search path. Complain
- about inaccesible files iff SILENT is false. */
-bool
-m4_load_filename (m4 *context, const m4_call_info *caller,
- const char *filename, m4_obstack *obs, bool silent)
-{
- char *filepath = NULL;
- char *suffix = NULL;
- bool new_input = false;
-
- if (m4_get_posixly_correct_opt (context))
- {
- if (access (filename, R_OK) == 0)
- filepath = xstrdup (filename);
- }
- else
- filepath = m4_path_search (context, filename, FILE_SUFFIXES);
-
- if (filepath)
- suffix = strrchr (filepath, '.');
-
- if (!m4_get_posixly_correct_opt (context)
- && suffix
- && STREQ (suffix, LT_MODULE_EXT))
- {
- m4_module_load (context, filename, obs);
- }
- else
- {
- FILE *fp = NULL;
-
- if (filepath)
- fp = m4_fopen (context, filepath, "r");
-
- if (fp == NULL)
- {
- if (!silent)
- m4_error (context, 0, errno, caller, _("cannot open file '%s'"),
- filename);
- free (filepath);
- return false;
- }
-
- m4_push_file (context, fp, filepath, true);
- new_input = true;
- }
- free (filepath);
-
- return new_input;
-}
-
-
-void
-m4__include_init (m4 *context)
-{
- include_env_init (context);
-
- {
- m4__search_path_info *info = m4__get_search_path (context);
-
- /* If M4PATH was not set, then search just the current directory by
- default. */
- assert (info);
- if (info->list_end == NULL)
- search_path_add (info, "", false);
-
- /* Non-core modules installation directory. */
- search_path_add (info, PKGLIBDIR, false);
- }
-
-#ifdef DEBUG_INCL
- fputs ("initial include search path...\n", stderr);
- include_dump (context);
-#endif
-}
-
-
-
-#ifdef DEBUG_INCL
-
-static void
-include_dump (m4 *context)
-{
- m4__search_path *incl;
-
- fputs ("include_dump:\n", stderr);
- for (incl = m4__get_search_path (context)->list;
- incl != NULL; incl = incl->next)
- xfprintf (stderr, "\t'%s'\n", incl->dir);
-}
-
-#endif /* DEBUG_INCL */
diff --git a/m4/resyntax.c b/m4/resyntax.c
deleted file mode 100644
index 704e357c..00000000
--- a/m4/resyntax.c
+++ /dev/null
@@ -1,127 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2006-2008, 2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include <regex.h>
-#include <string.h>
-
-#include "m4private.h"
-
-typedef struct {
- const char *spec;
- const int code;
-} m4_resyntax;
-
-/* The syntaxes named in this table are saved into frozen files. Changing
- the mappings will break programs that load a frozen file made before
- such a change... */
-
-static m4_resyntax const m4_resyntax_map[] =
-{
- /* First, the canonical definitions for reverse lookups: */
-
- { "AWK", RE_SYNTAX_AWK },
- { "ED", RE_SYNTAX_ED },
- { "EGREP", RE_SYNTAX_EGREP },
- { "EMACS", RE_SYNTAX_EMACS },
- { "GNU_AWK", RE_SYNTAX_GNU_AWK },
- { "GREP", RE_SYNTAX_GREP },
- { "POSIX_AWK", RE_SYNTAX_POSIX_AWK },
- { "POSIX_BASIC", RE_SYNTAX_POSIX_BASIC },
- { "POSIX_EGREP", RE_SYNTAX_POSIX_EGREP },
- { "POSIX_EXTENDED", RE_SYNTAX_POSIX_EXTENDED },
- { "POSIX_MINIMAL_BASIC", RE_SYNTAX_POSIX_MINIMAL_BASIC },
- { "SED", RE_SYNTAX_SED },
-
- /* The rest are aliases, for forward lookups only: */
-
- { "", RE_SYNTAX_EMACS },
- { "BASIC", RE_SYNTAX_POSIX_BASIC },
- { "BSD_M4", RE_SYNTAX_POSIX_EXTENDED },
- { "EXTENDED", RE_SYNTAX_POSIX_EXTENDED },
- { "GAWK", RE_SYNTAX_GNU_AWK },
- { "GNU_EGREP", RE_SYNTAX_EGREP },
- { "GNU_EMACS", RE_SYNTAX_EMACS },
- { "GNU_M4", RE_SYNTAX_EMACS },
- { "MINIMAL", RE_SYNTAX_POSIX_MINIMAL_BASIC },
- { "MINIMAL_BASIC", RE_SYNTAX_POSIX_MINIMAL_BASIC },
- { "POSIX_MINIMAL", RE_SYNTAX_POSIX_MINIMAL_BASIC },
-
- /* End marker: */
-
- { NULL, -1 }
-};
-
-
-/* Return the internal code representing the syntax SPEC, or -1 if
- SPEC is invalid. The `m4_syntax_map' table is searched case
- insensitively, after replacing any spaces or dashes in SPEC with
- underscore characters. Possible matches for the "GNU_M4" element
- then, are "gnu m4", "GNU-m4" or "Gnu_M4". */
-int
-m4_regexp_syntax_encode (const char *spec)
-{
- const m4_resyntax *resyntax;
- char *canonical;
- char *p;
-
- /* Unless specified otherwise, return the historical GNU M4 default. */
- if (!spec)
- return RE_SYNTAX_EMACS;
-
- canonical = xstrdup (spec);
-
- /* Canonicalise SPEC. */
- for (p = canonical; *p != '\0'; ++p)
- {
- if ((*p == ' ') || (*p == '-'))
- *p = '_';
- else if (islower (to_uchar (*p)))
- *p = toupper (to_uchar (*p));
- }
-
- for (resyntax = m4_resyntax_map; resyntax->spec != NULL; ++resyntax)
- {
- if (STREQ (resyntax->spec, canonical))
- break;
- }
-
- free (canonical);
-
- return resyntax->code;
-}
-
-
-/* Return the syntax specifier that matches CODE, or NULL if there is
- no match. */
-const char *
-m4_regexp_syntax_decode (int code)
-{
- const m4_resyntax *resyntax;
-
- for (resyntax = m4_resyntax_map; resyntax->spec != NULL; ++resyntax)
- {
- if (resyntax->code == code)
- break;
- }
-
- return resyntax->spec;
-}
diff --git a/m4/symtab.c b/m4/symtab.c
deleted file mode 100644
index b04b55e7..00000000
--- a/m4/symtab.c
+++ /dev/null
@@ -1,968 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2001, 2005-2008, 2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include "m4private.h"
-
-/* Define this to see runtime debug info. Implied by DEBUG. */
-/*#define DEBUG_SYM */
-
-/* This file handles all the low level work around the symbol table. The
- symbol table is an abstract hash table type implemented in hash.c. Each
- symbol is represented by `struct m4_symbol', which is stored in the hash
- table keyed by the symbol name. As a special case, to facilitate the
- "pushdef" and "popdef" builtins, the value stored against each key is a
- stack of `m4_symbol_value'. All the value entries for a symbol name are
- simply ordered on the stack by age. The most recently pushed definition
- will then always be the first found.
-
- Also worthy of mention is the way traced symbols are managed: the
- trace bit is associated with a particular symbol name. If a symbol
- is undefined and then redefined, it does not lose its trace bit.
- This is achieved by not removing traced symbol names from the
- symbol table, even if their value stack is empty. That way, when
- the name is given a new value, it is pushed onto the empty stack,
- and the trace bit attached to the name was never lost. There is a
- small amount of fluff in these functions to make sure that such
- symbols (with empty value stacks) are invisible to the users of
- this module. */
-
-#define M4_SYMTAB_DEFAULT_SIZE 2047
-
-struct m4_symbol_table {
- m4_hash *table;
-};
-
-static m4_symbol *symtab_fetch (m4_symbol_table*, const char *,
- size_t);
-static void symbol_popval (m4_symbol *);
-static void * symbol_destroy_CB (m4_symbol_table *, const char *,
- size_t, m4_symbol *, void *);
-static void * arg_destroy_CB (m4_hash *, const void *, void *,
- void *);
-static void * arg_copy_CB (m4_hash *, const void *, void *,
- m4_hash *);
-
-
-/* -- SYMBOL TABLE MANAGEMENT --
-
- These functions are used to manage a symbol table as a whole. */
-
-m4_symbol_table *
-m4_symtab_create (size_t size)
-{
- m4_symbol_table *symtab = (m4_symbol_table *) xmalloc (sizeof *symtab);
-
- symtab->table = m4_hash_new (size ? size : M4_SYMTAB_DEFAULT_SIZE,
- m4_hash_string_hash, m4_hash_string_cmp);
- return symtab;
-}
-
-void
-m4_symtab_delete (m4_symbol_table *symtab)
-{
- assert (symtab);
- assert (symtab->table);
-
- m4_symtab_apply (symtab, true, symbol_destroy_CB, NULL);
- m4_hash_delete (symtab->table);
- free (symtab);
-}
-
-/* For every symbol in SYMTAB, execute the callback FUNC with the name
- and value of the symbol being visited, and the opaque parameter
- USERDATA. Skip undefined symbols that are placeholders for
- traceon, unless INCLUDE_TRACE is true. If FUNC returns non-NULL,
- abort the iteration and return the same result; otherwise return
- NULL when iteration completes. */
-void *
-m4_symtab_apply (m4_symbol_table *symtab, bool include_trace,
- m4_symtab_apply_func *func, void *userdata)
-{
- m4_hash_iterator *place = NULL;
- void * result = NULL;
-
- assert (symtab);
- assert (symtab->table);
- assert (func);
-
- while ((place = m4_get_hash_iterator_next (symtab->table, place)))
- {
- m4_symbol *symbol = m4_get_hash_iterator_value (place);
- if (symbol->value || include_trace)
- {
- const m4_string *key
- = (const m4_string *) m4_get_hash_iterator_key (place);
- result = func (symtab, key->str, key->len, symbol, userdata);
- }
- if (result != NULL)
- {
- m4_free_hash_iterator (symtab->table, place);
- break;
- }
- }
-
- return result;
-}
-
-/* Ensure that NAME of length LEN exists in the table, creating an
- entry if needed. */
-static m4_symbol *
-symtab_fetch (m4_symbol_table *symtab, const char *name, size_t len)
-{
- m4_symbol **psymbol;
- m4_symbol *symbol;
- m4_string key;
-
- assert (symtab);
- assert (name);
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len;
- psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
- if (psymbol)
- {
- symbol = *psymbol;
- }
- else
- {
- /* Use xmemdup0 rather than memdup so that debugging the symbol
- table is easier. */
- m4_string *new_key = (m4_string *) xmalloc (sizeof *new_key);
- new_key->str = xmemdup0 (name, len);
- new_key->len = len;
- symbol = (m4_symbol *) xzalloc (sizeof *symbol);
- m4_hash_insert (symtab->table, new_key, symbol);
- }
-
- return symbol;
-}
-
-/* Remove every symbol that references the given module from
- the symbol table. */
-void
-m4__symtab_remove_module_references (m4_symbol_table *symtab,
- m4_module *module)
-{
- m4_hash_iterator *place = 0;
-
- assert (module);
-
- /* Traverse each symbol name in the hash table. */
- while ((place = m4_get_hash_iterator_next (symtab->table, place)))
- {
- m4_symbol *symbol = (m4_symbol *) m4_get_hash_iterator_value (place);
- m4_symbol_value *data = m4_get_symbol_value (symbol);
-
- /* For symbols that have token data... */
- if (data)
- {
- /* Purge any shadowed references. */
- while (VALUE_NEXT (data))
- {
- m4_symbol_value *next = VALUE_NEXT (data);
-
- if (VALUE_MODULE (next) == module)
- {
- VALUE_NEXT (data) = VALUE_NEXT (next);
-
- assert (next->type != M4_SYMBOL_PLACEHOLDER);
- m4_symbol_value_delete (next);
- }
- else
- data = next;
- }
-
- /* Purge the live reference if necessary. */
- if (SYMBOL_MODULE (symbol) == module)
- {
- const m4_string *key
- = (const m4_string *) m4_get_hash_iterator_key (place);
- m4_symbol_popdef (symtab, key->str, key->len);
- }
- }
- }
-}
-
-
-/* This callback is used exclusively by m4_symtab_delete(), to cleanup
- the memory used by the symbol table. As such, the trace bit is reset
- on every symbol so that m4_symbol_popdef() doesn't try to preserve
- the table entry. */
-static void *
-symbol_destroy_CB (m4_symbol_table *symtab, const char *name, size_t len,
- m4_symbol *symbol, void *ignored M4_GNUC_UNUSED)
-{
- m4_string key;
- key.str = xmemdup0 (name, len);
- key.len = len;
-
- symbol->traced = false;
-
- while (m4_hash_lookup (symtab->table, &key))
- m4_symbol_popdef (symtab, key.str, key.len);
-
- free (key.str);
-
- return NULL;
-}
-
-
-
-/* -- SYMBOL MANAGEMENT --
-
- The following functions manipulate individual symbols within
- an existing table. */
-
-/* Return the symbol associated to NAME of length LEN, or else
- NULL. */
-m4_symbol *
-m4_symbol_lookup (m4_symbol_table *symtab, const char *name, size_t len)
-{
- m4_string key;
- m4_symbol **psymbol;
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len;
- psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
-
- /* If just searching, return status of search -- if only an empty
- struct is returned, that is treated as a failed lookup. */
- return (psymbol && m4_get_symbol_value (*psymbol)) ? *psymbol : NULL;
-}
-
-
-/* Insert NAME of length LEN into the symbol table. If there is
- already a symbol associated with NAME, push the new VALUE on top of
- the value stack for this symbol. Otherwise create a new
- association. */
-m4_symbol *
-m4_symbol_pushdef (m4_symbol_table *symtab, const char *name, size_t len,
- m4_symbol_value *value)
-{
- m4_symbol *symbol;
-
- assert (symtab);
- assert (name);
- assert (value);
-
- symbol = symtab_fetch (symtab, name, len);
- VALUE_NEXT (value) = m4_get_symbol_value (symbol);
- symbol->value = value;
-
- assert (m4_get_symbol_value (symbol));
-
- return symbol;
-}
-
-/* Return the symbol associated with NAME of length LEN in the symbol
- table, creating a new symbol if necessary. In either case set the
- symbol's VALUE. */
-m4_symbol *
-m4_symbol_define (m4_symbol_table *symtab, const char *name, size_t len,
- m4_symbol_value *value)
-{
- m4_symbol *symbol;
-
- assert (symtab);
- assert (name);
- assert (value);
-
- symbol = symtab_fetch (symtab, name, len);
- if (m4_get_symbol_value (symbol))
- symbol_popval (symbol);
-
- VALUE_NEXT (value) = m4_get_symbol_value (symbol);
- symbol->value = value;
-
- assert (m4_get_symbol_value (symbol));
-
- return symbol;
-}
-
-/* Pop the topmost value stack entry from the symbol associated with
- NAME of length LEN, deleting it from the table entirely if that was
- the last remaining value in the stack. */
-void
-m4_symbol_popdef (m4_symbol_table *symtab, const char *name, size_t len)
-{
- m4_string key;
- m4_symbol **psymbol;
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len;
- psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
-
- assert (psymbol);
- assert (*psymbol);
-
- symbol_popval (*psymbol);
-
- /* Only remove the hash table entry if the last value in the
- symbol value stack was successfully removed. */
- if (!m4_get_symbol_value (*psymbol) && !m4_get_symbol_traced (*psymbol))
- {
- m4_string *old_key;
- DELETE (*psymbol);
- old_key = (m4_string *) m4_hash_remove (symtab->table, &key);
- free (old_key->str);
- free (old_key);
- }
-}
-
-/* Remove the top-most value from SYMBOL's stack. */
-static void
-symbol_popval (m4_symbol *symbol)
-{
- m4_symbol_value *stale;
-
- assert (symbol);
-
- stale = m4_get_symbol_value (symbol);
-
- if (stale)
- {
- symbol->value = VALUE_NEXT (stale);
- m4_symbol_value_delete (stale);
- }
-}
-
-/* Create a new symbol value, with fields populated for default
- behavior. */
-m4_symbol_value *
-m4_symbol_value_create (void)
-{
- m4_symbol_value *value = (m4_symbol_value *) xzalloc (sizeof *value);
- VALUE_MAX_ARGS (value) = SIZE_MAX;
- return value;
-}
-
-/* Remove VALUE from the symbol table, and mark it as deleted. If no
- expansions are pending, reclaim its resources. */
-void
-m4_symbol_value_delete (m4_symbol_value *value)
-{
- if (VALUE_PENDING (value) > 0)
- BIT_SET (VALUE_FLAGS (value), VALUE_DELETED_BIT);
- else
- {
- if (VALUE_ARG_SIGNATURE (value))
- {
- m4_hash_apply (VALUE_ARG_SIGNATURE (value), arg_destroy_CB, NULL);
- m4_hash_delete (VALUE_ARG_SIGNATURE (value));
- }
- switch (value->type)
- {
- case M4_SYMBOL_TEXT:
- DELETE (value->u.u_t.text);
- break;
- case M4_SYMBOL_PLACEHOLDER:
- DELETE (value->u.u_t.text);
- break;
- case M4_SYMBOL_VOID:
- case M4_SYMBOL_FUNC:
- break;
- default:
- assert (!"m4_symbol_value_delete");
- abort ();
- }
- free (value);
- }
-}
-
-/* Rename the entire stack of values associated with NAME and LEN1 to
- NEWNAME and LEN2. */
-m4_symbol *
-m4_symbol_rename (m4_symbol_table *symtab, const char *name, size_t len1,
- const char *newname, size_t len2)
-{
- m4_symbol *symbol = NULL;
- m4_symbol **psymbol;
- m4_string key;
- m4_string *pkey;
-
- assert (symtab);
- assert (name);
- assert (newname);
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len1;
- /* Use a low level hash fetch, so we can save the symbol value when
- removing the symbol name from the symbol table. */
- psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
-
- if (psymbol)
- {
- symbol = *psymbol;
-
- /* Remove the old name from the symbol table. */
- pkey = (m4_string *) m4_hash_remove (symtab->table, &key);
- assert (pkey && !m4_hash_lookup (symtab->table, &key));
- free (pkey->str);
-
- pkey->str = xmemdup0 (newname, len2);
- pkey->len = len2;
- m4_hash_insert (symtab->table, pkey, *psymbol);
- }
- /* else
- NAME does not name a symbol in symtab->table! */
-
- return symbol;
-}
-
-
-/* Callback used by m4_symbol_popdef () to release the memory used
- by values in the arg_signature hash. */
-static void *
-arg_destroy_CB (m4_hash *hash, const void *name, void *arg, void *ignored)
-{
- struct m4_symbol_arg *token_arg = (struct m4_symbol_arg *) arg;
-
- assert (name);
- assert (hash);
-
- if (SYMBOL_ARG_DEFAULT (token_arg))
- DELETE (SYMBOL_ARG_DEFAULT (token_arg));
- free (token_arg);
- free (m4_hash_remove (hash, (const char *) name));
-
- return NULL;
-}
-
-/* Copy the symbol SRC into DEST. Return true if builtin tokens were
- flattened. */
-bool
-m4_symbol_value_copy (m4 *context, m4_symbol_value *dest, m4_symbol_value *src)
-{
- m4_symbol_value *next;
- bool result = false;
-
- assert (dest);
- assert (src);
-
- switch (dest->type)
- {
- case M4_SYMBOL_TEXT:
- DELETE (dest->u.u_t.text);
- break;
- case M4_SYMBOL_PLACEHOLDER:
- DELETE (dest->u.u_t.text);
- break;
- case M4_SYMBOL_VOID:
- case M4_SYMBOL_FUNC:
- break;
- default:
- assert (!"m4_symbol_value_delete");
- abort ();
- }
-
- if (VALUE_ARG_SIGNATURE (dest))
- {
- m4_hash_apply (VALUE_ARG_SIGNATURE (dest), arg_destroy_CB, NULL);
- m4_hash_delete (VALUE_ARG_SIGNATURE (dest));
- }
-
- /* Copy the value contents over, being careful to preserve
- the next pointer. */
- next = VALUE_NEXT (dest);
- memcpy (dest, src, sizeof (m4_symbol_value));
- VALUE_NEXT (dest) = next;
-
- /* Caller is supposed to free text token strings, so we have to
- copy the string not just its address in that case. */
- switch (src->type)
- {
- case M4_SYMBOL_TEXT:
- {
- size_t len = m4_get_symbol_value_len (src);
- unsigned int age = m4_get_symbol_value_quote_age (src);
- m4_set_symbol_value_text (dest,
- xmemdup0 (m4_get_symbol_value_text (src),
- len), len, age);
- }
- break;
- case M4_SYMBOL_FUNC:
- m4__set_symbol_value_builtin (dest, src->u.builtin);
- break;
- case M4_SYMBOL_PLACEHOLDER:
- m4_set_symbol_value_placeholder (dest,
- xstrdup (m4_get_symbol_value_placeholder
- (src)));
- break;
- case M4_SYMBOL_COMP:
- {
- m4__symbol_chain *chain = src->u.u_c.chain;
- size_t len;
- char *str;
- const m4_string_pair *quotes;
- m4_obstack *obs = m4_arg_scratch (context);
- while (chain)
- {
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- obstack_grow (obs, chain->u.u_s.str, chain->u.u_s.len);
- break;
- case M4__CHAIN_FUNC:
- result = true;
- break;
- case M4__CHAIN_ARGV:
- quotes = m4__quote_cache (M4SYNTAX, NULL, chain->quote_age,
- chain->u.u_a.quotes);
- if (chain->u.u_a.has_func && !chain->u.u_a.flatten)
- result = true;
- m4__arg_print (context, obs, chain->u.u_a.argv,
- chain->u.u_a.index, quotes, true, NULL, NULL,
- NULL, false, false);
- break;
- default:
- assert (!"m4_symbol_value_copy");
- abort ();
- }
- chain = chain->next;
- }
- obstack_1grow (obs, '\0');
- len = obstack_object_size (obs);
- str = xcharalloc (len);
- memcpy (str, obstack_finish (obs), len);
- m4_set_symbol_value_text (dest, str, len - 1, 0);
- }
- break;
- default:
- assert (!"m4_symbol_value_copy");
- abort ();
- }
- if (VALUE_ARG_SIGNATURE (src))
- VALUE_ARG_SIGNATURE (dest) = m4_hash_dup (VALUE_ARG_SIGNATURE (src),
- arg_copy_CB);
- return result;
-}
-
-static void *
-arg_copy_CB (m4_hash *src, const void *name, void *arg, m4_hash *dest)
-{
- m4_hash_insert ((m4_hash *) dest, name, arg);
- return NULL;
-}
-
-/* Set the tracing status of the symbol NAME of length LEN to TRACED.
- This takes a name, rather than a symbol, since we hide macros that
- are traced but otherwise undefined from normal lookups, but still
- can affect their tracing status. Return true iff the macro was
- previously traced. */
-bool
-m4_set_symbol_name_traced (m4_symbol_table *symtab, const char *name,
- size_t len, bool traced)
-{
- m4_symbol *symbol;
- bool result;
-
- assert (symtab);
- assert (name);
-
- if (traced)
- symbol = symtab_fetch (symtab, name, len);
- else
- {
- m4_string key;
- m4_symbol **psymbol;
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len;
- psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, &key);
- if (!psymbol)
- return false;
- symbol = *psymbol;
- }
-
- result = symbol->traced;
- symbol->traced = traced;
- if (!traced && !m4_get_symbol_value (symbol))
- {
- /* Free an undefined entry once it is no longer traced. */
- m4_string key;
- m4_string *old_key;
- assert (result);
- free (symbol);
-
- /* Safe to cast away const, since m4_hash_lookup doesn't modify
- key. */
- key.str = (char *) name;
- key.len = len;
- old_key = (m4_string *) m4_hash_remove (symtab->table, &key);
- free (old_key->str);
- free (old_key);
- }
-
- return result;
-}
-
-/* Grow OBS with a text representation of VALUE. If QUOTES, then use
- it to surround a text definition. If FLATTEN, builtins are
- converted to empty quotes; if CHAINP, *CHAINP is updated with macro
- tokens; otherwise, builtins are represented by their name. If
- MAXLEN, then truncate text definitions to *MAXLEN, and adjust by
- how many characters are printed. If MODULE, then include which
- module defined a builtin. Return true if the output was truncated.
- QUOTES and MODULE do not count against the truncation length. */
-bool
-m4__symbol_value_print (m4 *context, m4_symbol_value *value, m4_obstack *obs,
- const m4_string_pair *quotes, bool flatten,
- m4__symbol_chain **chainp, size_t *maxlen, bool module)
-{
- const char *text;
- m4__symbol_chain *chain;
- size_t len = maxlen ? *maxlen : SIZE_MAX;
- bool result = false;
-
- switch (value->type)
- {
- case M4_SYMBOL_TEXT:
- if (m4_shipout_string_trunc (obs, m4_get_symbol_value_text (value),
- m4_get_symbol_value_len (value), quotes,
- &len))
- result = true;
- break;
- case M4_SYMBOL_FUNC:
- m4__builtin_print (obs, value->u.builtin, flatten, chainp, quotes,
- module);
- module = false;
- break;
- case M4_SYMBOL_PLACEHOLDER:
- if (flatten)
- {
- if (quotes)
- {
- obstack_grow (obs, quotes->str1, quotes->len1);
- obstack_grow (obs, quotes->str2, quotes->len2);
- }
- module = false;
- }
- else
- {
- text = m4_get_symbol_value_placeholder (value);
- obstack_1grow (obs, '<');
- obstack_1grow (obs, '<');
- obstack_grow (obs, text, strlen (text));
- obstack_1grow (obs, '>');
- obstack_1grow (obs, '>');
- }
- break;
- case M4_SYMBOL_COMP:
- chain = value->u.u_c.chain;
- assert (!module);
- if (quotes)
- obstack_grow (obs, quotes->str1, quotes->len1);
- while (chain && !result)
- {
- switch (chain->type)
- {
- case M4__CHAIN_STR:
- if (m4_shipout_string_trunc (obs, chain->u.u_s.str,
- chain->u.u_s.len, NULL, &len))
- result = true;
- break;
- case M4__CHAIN_FUNC:
- m4__builtin_print (obs, chain->u.builtin, flatten, chainp,
- quotes, module);
- break;
- case M4__CHAIN_ARGV:
- if (m4__arg_print (context, obs, chain->u.u_a.argv,
- chain->u.u_a.index,
- m4__quote_cache (M4SYNTAX, NULL,
- chain->quote_age,
- chain->u.u_a.quotes),
- chain->u.u_a.flatten, chainp, NULL, &len,
- false, module))
- result = true;
- break;
- default:
- assert (!"m4__symbol_value_print");
- abort ();
- }
- chain = chain->next;
- }
- if (quotes)
- obstack_grow (obs, quotes->str2, quotes->len2);
- break;
- default:
- assert (!"m4__symbol_value_print");
- abort ();
- }
-
- if (module && VALUE_MODULE (value))
- {
- obstack_1grow (obs, '{');
- text = m4_get_module_name (VALUE_MODULE (value));
- obstack_grow (obs, text, strlen (text));
- obstack_1grow (obs, '}');
- }
- if (maxlen)
- *maxlen = len;
- return result;
-}
-
-/* Grow OBS with a text representation of SYMBOL. If QUOTES, then use
- it to surround each text definition. If STACK, then append all
- pushdef'd values, rather than just the top. If ARG_LENGTH is less
- than SIZE_MAX, then truncate text definitions to that length. If
- MODULE, then include which module defined a builtin. QUOTES and
- MODULE do not count toward truncation. */
-void
-m4_symbol_print (m4 *context, m4_symbol *symbol, m4_obstack *obs,
- const m4_string_pair *quotes, bool stack, size_t arg_length,
- bool module)
-{
- m4_symbol_value *value;
- size_t len = arg_length;
-
- assert (symbol);
- assert (obs);
-
- value = m4_get_symbol_value (symbol);
- m4__symbol_value_print (context, value, obs, quotes, false, NULL, &len,
- module);
- if (stack)
- {
- value = VALUE_NEXT (value);
- while (value)
- {
- obstack_1grow (obs, ',');
- obstack_1grow (obs, ' ');
- len = arg_length;
- m4__symbol_value_print (context, value, obs, quotes, false, NULL,
- &len, module);
- value = VALUE_NEXT (value);
- }
- }
-}
-
-
-/* Define these functions at the end, so that calls in the file use the
- faster macro version from m4module.h. */
-
-/* Pop all values from the symbol associated with NAME. */
-#undef m4_symbol_delete
-void
-m4_symbol_delete (m4_symbol_table *symtab, const char *name, size_t len)
-{
- while (m4_symbol_lookup (symtab, name, len))
- m4_symbol_popdef (symtab, name, len);
-}
-
-#undef m4_get_symbol_traced
-bool
-m4_get_symbol_traced (m4_symbol *symbol)
-{
- assert (symbol);
- return symbol->traced;
-}
-
-#undef m4_symbol_value_flatten_args
-bool
-m4_symbol_value_flatten_args (m4_symbol_value *value)
-{
- assert (value);
- return BIT_TEST (value->flags, VALUE_FLATTEN_ARGS_BIT);
-}
-
-#undef m4_get_symbol_value
-m4_symbol_value *
-m4_get_symbol_value (m4_symbol *symbol)
-{
- assert (symbol);
- return symbol->value;
-}
-
-#undef m4_is_symbol_value_text
-bool
-m4_is_symbol_value_text (m4_symbol_value *value)
-{
- assert (value);
- return (value->type == M4_SYMBOL_TEXT);
-}
-
-#undef m4_is_symbol_value_func
-bool
-m4_is_symbol_value_func (m4_symbol_value *value)
-{
- assert (value);
- return (value->type == M4_SYMBOL_FUNC);
-}
-
-#undef m4_is_symbol_value_placeholder
-bool
-m4_is_symbol_value_placeholder (m4_symbol_value *value)
-{
- assert (value);
- return (value->type == M4_SYMBOL_PLACEHOLDER);
-}
-
-#undef m4_is_symbol_value_void
-bool
-m4_is_symbol_value_void (m4_symbol_value *value)
-{
- assert (value);
- return (value->type == M4_SYMBOL_VOID);
-}
-
-#undef m4_get_symbol_value_text
-const char *
-m4_get_symbol_value_text (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_TEXT);
- return value->u.u_t.text;
-}
-
-#undef m4_get_symbol_value_len
-size_t
-m4_get_symbol_value_len (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_TEXT);
- return value->u.u_t.len;
-}
-
-#undef m4_get_symbol_value_quote_age
-unsigned int
-m4_get_symbol_value_quote_age (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_TEXT);
- return value->u.u_t.quote_age;
-}
-
-#undef m4_get_symbol_value_func
-m4_builtin_func *
-m4_get_symbol_value_func (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_FUNC);
- return value->u.builtin->builtin.func;
-}
-
-#undef m4_get_symbol_value_builtin
-const m4_builtin *
-m4_get_symbol_value_builtin (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_FUNC);
- return &value->u.builtin->builtin;
-}
-
-#undef m4_get_symbol_value_placeholder
-const char *
-m4_get_symbol_value_placeholder (m4_symbol_value *value)
-{
- assert (value && value->type == M4_SYMBOL_PLACEHOLDER);
- return value->u.u_t.text;
-}
-
-#undef m4_set_symbol_value_text
-void
-m4_set_symbol_value_text (m4_symbol_value *value, const char *text, size_t len,
- unsigned int quote_age)
-{
- assert (value && text);
- /* In practice, it is easier to debug when we guarantee a
- terminating NUL, even when there are embedded NULs. */
- assert (!text[len]);
-
- value->type = M4_SYMBOL_TEXT;
- value->u.u_t.text = text;
- value->u.u_t.len = len;
- value->u.u_t.quote_age = quote_age;
-}
-
-#undef m4__set_symbol_value_builtin
-void
-m4__set_symbol_value_builtin (m4_symbol_value *value,
- const m4__builtin *builtin)
-{
- assert (value && builtin);
-
- value->type = M4_SYMBOL_FUNC;
- value->u.builtin = builtin;
- VALUE_MODULE (value) = builtin->module;
- VALUE_FLAGS (value) = builtin->builtin.flags;
- VALUE_MIN_ARGS (value) = builtin->builtin.min_args;
- VALUE_MAX_ARGS (value) = builtin->builtin.max_args;
-}
-
-#undef m4_set_symbol_value_placeholder
-void
-m4_set_symbol_value_placeholder (m4_symbol_value *value, const char *text)
-{
- assert (value);
- assert (text);
-
- value->type = M4_SYMBOL_PLACEHOLDER;
- value->u.u_t.text = text;
- value->u.u_t.len = SIZE_MAX; /* len is not tracked for placeholders. */
-}
-
-
-#ifdef DEBUG_SYM
-
-static void *dump_symbol_CB (m4_symbol_table *symtab, const char *name,
- m4_symbol *symbol, void *userdata);
-static M4_GNUC_UNUSED void *
-symtab_dump (m4 *context, m4_symbol_table *symtab)
-{
- return m4_symtab_apply (symtab, true, dump_symbol_CB, context);
-}
-
-static void *
-dump_symbol_CB (m4_symbol_table *symtab, const char *name,
- m4_symbol *symbol, void *ptr)
-{
- m4 * context = (m4 *) ptr;
- m4_symbol_value *value = m4_get_symbol_value (symbol);
- int flags = value ? SYMBOL_FLAGS (symbol) : 0;
- m4_module * module = value ? SYMBOL_MODULE (symbol) : NULL;
- const char * module_name = module ? m4_get_module_name (module) : "NONE";
-
- xfprintf (stderr, "%10s: (%d%s) %s=", module_name, flags,
- m4_get_symbol_traced (symbol) ? "!" : "", name);
-
- if (!value)
- fputs ("<!UNDEFINED!>", stderr);
- else if (m4_is_symbol_value_void (value))
- fputs ("<!VOID!>", stderr);
- else
- {
- m4_obstack obs;
- obstack_init (&obs);
- m4__symbol_value_print (context, value, &obs, NULL, false, NULL, NULL,
- true);
- xfprintf (stderr, "%s", (char *) obstack_finish (&obs));
- obstack_free (&obs, NULL);
- }
- fputc ('\n', stderr);
- return NULL;
-}
-#endif /* DEBUG_SYM */
diff --git a/m4/syntax.c b/m4/syntax.c
deleted file mode 100644
index 4bde1234..00000000
--- a/m4/syntax.c
+++ /dev/null
@@ -1,954 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2002, 2004, 2006-2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include "m4private.h"
-
-/* Define this to see runtime debug info. Implied by DEBUG. */
-/*#define DEBUG_SYNTAX */
-
-/* THE SYNTAX TABLE
-
- The input is read character by character and grouped together
- according to a syntax table. The character groups are (definitions
- are all in m4module.h, those marked with a * are not yet in use):
-
- Basic (all characters fall in one of these mutually exclusive bins)
- M4_SYNTAX_IGNORE *Character to be deleted from input as if not present
- M4_SYNTAX_OTHER Any character with no special meaning to m4
- M4_SYNTAX_SPACE Whitespace (ignored when leading macro arguments)
- M4_SYNTAX_OPEN Open list of macro arguments
- M4_SYNTAX_CLOSE Close list of macro arguments
- M4_SYNTAX_COMMA Separates macro arguments
- M4_SYNTAX_ACTIVE This character is a macro name by itself
- M4_SYNTAX_ESCAPE Use this character to prefix all macro names
-
- M4_SYNTAX_ALPHA Alphabetic characters (can start macro names)
- M4_SYNTAX_NUM Numeric characters (can form macro names)
-
- M4_SYNTAX_LQUOTE A single character left quote
- M4_SYNTAX_BCOMM A single character begin comment delimiter
-
- Attribute (these are context sensitive, and exist in addition to basic)
- M4_SYNTAX_RQUOTE A single character right quote
- M4_SYNTAX_ECOMM A single character end comment delimiter
- M4_SYNTAX_DOLLAR Indicates macro argument in user macros
- M4_SYNTAX_LBRACE *Indicates start of extended macro argument
- M4_SYNTAX_RBRACE *Indicates end of extended macro argument
-
- Besides adding new facilities, the use of a syntax table will reduce
- the number of calls to next_token (). Now groups of OTHER, NUM and
- SPACE characters can be returned as a single token, since next_token
- () knows they have no special syntactical meaning to m4. This is,
- however, only possible if only single character quotes comments
- comments are used, because otherwise the quote and comment characters
- will not show up in the syntax-table.
-
- Having a syntax table allows new facilities. The new builtin
- "changesyntax" allows the user to change the category of any
- character.
-
- By default, '\n' is both ECOMM and SPACE, depending on the context.
- Hence we have basic categories (mutually exclusive, can introduce a
- context, and can be empty sets), and attribute categories
- (additive, only recognized in context, and will never be empty).
-
- The precedence as implemented by next_token () is:
-
- M4_SYNTAX_IGNORE *Filtered out below next_token ()
- M4_SYNTAX_ESCAPE Reads macro name iff set, else next character
- M4_SYNTAX_ALPHA Reads M4_SYNTAX_ALPHA and M4_SYNTAX_NUM as macro name
- M4_SYNTAX_LQUOTE Reads all until balanced M4_SYNTAX_RQUOTE
- M4_SYNTAX_BCOMM Reads all until M4_SYNTAX_ECOMM
-
- M4_SYNTAX_OTHER } Reads all M4_SYNTAX_OTHER, M4_SYNTAX_NUM
- M4_SYNTAX_NUM }
-
- M4_SYNTAX_SPACE Reads all M4_SYNTAX_SPACE, depending on buffering
- M4_SYNTAX_ACTIVE Returns a single char as a macro name
-
- M4_SYNTAX_OPEN } Returned as a single char
- M4_SYNTAX_CLOSE }
- M4_SYNTAX_COMMA }
-
- M4_SYNTAX_RQUOTE and M4_SYNTAX_ECOMM are context-sensitive, and
- close out M4_SYNTAX_LQUOTE and M4_SYNTAX_BCOMM, respectively.
- Also, M4_SYNTAX_DOLLAR, M4_SYNTAX_LBRACE, and M4_SYNTAX_RBRACE are
- context-sensitive, only mattering when expanding macro definitions.
-
- There are several optimizations that can be performed depending on
- known states of the syntax table. For example, when searching for
- quotes, if there is only a single start quote and end quote
- delimiter, we can use memchr2 and search a word at a time, instead
- of performing a table lookup a byte at a time. The is_single_*
- flags track whether quotes and comments have a single delimiter
- (always the case if changequote/changecom were used, and
- potentially the case after changesyntax). Since we frequently need
- to access quotes, we store the oldest valid quote outside the
- lookup table; the suspect flag tracks whether a cleanup pass is
- needed to restore our invariants. On the other hand, coalescing
- multiple M4_SYNTAX_OTHER bytes could form a delimiter, so many
- optimizations must be disabled if a multi-byte delimiter exists;
- this is handled by m4__safe_quotes. Meanwhile, quotes and comments
- can be disabled if the leading delimiter is length 0. */
-
-static int add_syntax_attribute (m4_syntax_table *, char, int);
-static int remove_syntax_attribute (m4_syntax_table *, char, int);
-static void set_quote_age (m4_syntax_table *, bool, bool);
-
-m4_syntax_table *
-m4_syntax_create (void)
-{
- m4_syntax_table *syntax = (m4_syntax_table *) xzalloc (sizeof *syntax);
- int ch;
-
- /* Set up default table. This table never changes during operation,
- and contains no context attributes. */
- for (ch = UCHAR_MAX + 1; --ch >= 0; )
- switch (ch)
- {
- case '(':
- syntax->orig[ch] = M4_SYNTAX_OPEN;
- break;
- case ')':
- syntax->orig[ch] = M4_SYNTAX_CLOSE;
- break;
- case ',':
- syntax->orig[ch] = M4_SYNTAX_COMMA;
- break;
- case '`':
- syntax->orig[ch] = M4_SYNTAX_LQUOTE;
- break;
- case '#':
- syntax->orig[ch] = M4_SYNTAX_BCOMM;
- break;
- default:
- if (isspace (ch))
- syntax->orig[ch] = M4_SYNTAX_SPACE;
- else if (isalpha (ch) || ch == '_')
- syntax->orig[ch] = M4_SYNTAX_ALPHA;
- else if (isdigit (ch))
- syntax->orig[ch] = M4_SYNTAX_NUM;
- else
- syntax->orig[ch] = M4_SYNTAX_OTHER;
- }
-
- /* Set up current table to match default. */
- m4_reset_syntax (syntax);
- syntax->cached_simple.str1 = syntax->cached_lquote;
- syntax->cached_simple.len1 = 1;
- syntax->cached_simple.str2 = syntax->cached_rquote;
- syntax->cached_simple.len2 = 1;
- return syntax;
-}
-
-void
-m4_syntax_delete (m4_syntax_table *syntax)
-{
- assert (syntax);
-
- free (syntax->quote.str1);
- free (syntax->quote.str2);
- free (syntax->comm.str1);
- free (syntax->comm.str2);
- free (syntax);
-}
-
-int
-m4_syntax_code (char ch)
-{
- int code;
-
- switch (ch)
- {
- /* Sorted according to the order of M4_SYNTAX_* in m4module.h. */
- /* FIXME - revisit the ignore syntax attribute. */
- case 'I': case 'i': code = M4_SYNTAX_IGNORE; break;
- /* Basic categories. */
- case '@': code = M4_SYNTAX_ESCAPE; break;
- case 'W': case 'w': code = M4_SYNTAX_ALPHA; break;
- case 'L': case 'l': code = M4_SYNTAX_LQUOTE; break;
- case 'B': case 'b': code = M4_SYNTAX_BCOMM; break;
- case 'A': case 'a': code = M4_SYNTAX_ACTIVE; break;
- case 'D': case 'd': code = M4_SYNTAX_NUM; break;
- case 'S': case 's': code = M4_SYNTAX_SPACE; break;
- case '(': code = M4_SYNTAX_OPEN; break;
- case ')': code = M4_SYNTAX_CLOSE; break;
- case ',': code = M4_SYNTAX_COMMA; break;
- case 'O': case 'o': code = M4_SYNTAX_OTHER; break;
- /* Context categories. */
- case '$': code = M4_SYNTAX_DOLLAR; break;
- case '{': code = M4_SYNTAX_LBRACE; break;
- case '}': code = M4_SYNTAX_RBRACE; break;
- case 'R': case 'r': code = M4_SYNTAX_RQUOTE; break;
- case 'E': case 'e': code = M4_SYNTAX_ECOMM; break;
-
- default: code = -1; break;
- }
-
- return code;
-}
-
-
-
-/* Functions to manipulate the syntax table. */
-static int
-add_syntax_attribute (m4_syntax_table *syntax, char ch, int code)
-{
- int c = to_uchar (ch);
- if (code & M4_SYNTAX_MASKS)
- {
- syntax->table[c] |= code;
- syntax->suspect = true;
- }
- else
- {
- if ((code & (M4_SYNTAX_SUSPECT)) != 0
- || m4_has_syntax (syntax, c, M4_SYNTAX_SUSPECT))
- syntax->suspect = true;
- syntax->table[c] = ((syntax->table[c] & M4_SYNTAX_MASKS) | code);
- }
-
-#ifdef DEBUG_SYNTAX
- xfprintf(stderr, "Set syntax %o %c = %04X\n", c, isprint(c) ? c : '-',
- syntax->table[c]);
-#endif
-
- return syntax->table[c];
-}
-
-static int
-remove_syntax_attribute (m4_syntax_table *syntax, char ch, int code)
-{
- int c = to_uchar (ch);
- assert (code & M4_SYNTAX_MASKS);
- syntax->table[c] &= ~code;
- syntax->suspect = true;
-
-#ifdef DEBUG_SYNTAX
- xfprintf(stderr, "Unset syntax %o %c = %04X\n", c, isprint(c) ? c : '-',
- syntax->table[c]);
-#endif
-
- return syntax->table[c];
-}
-
-/* Add the set CHARS of length LEN to syntax category CODE, removing
- them from whatever category they used to be in. */
-static void
-add_syntax_set (m4_syntax_table *syntax, const char *chars, size_t len,
- int code)
-{
- while (len--)
- add_syntax_attribute (syntax, *chars++, code);
-}
-
-/* Remove the set CHARS of length LEN from syntax category CODE,
- adding them to category M4_SYNTAX_OTHER instead. */
-static void
-subtract_syntax_set (m4_syntax_table *syntax, const char *chars, size_t len,
- int code)
-{
- while (len--)
- {
- char ch = *chars++;
- if ((code & M4_SYNTAX_MASKS) != 0)
- remove_syntax_attribute (syntax, ch, code);
- else if (m4_has_syntax (syntax, ch, code))
- add_syntax_attribute (syntax, ch, M4_SYNTAX_OTHER);
- }
-}
-
-/* Make the set CHARS of length LEN become syntax category CODE,
- removing CHARS from any other categories, and sending all bytes in
- the category but not in CHARS to category M4_SYNTAX_OTHER
- instead. */
-static void
-set_syntax_set (m4_syntax_table *syntax, const char *chars, size_t len,
- int code)
-{
- int ch;
- /* Explicit set of characters to install with this category; all
- other characters that used to have the category get reset to
- OTHER. */
- for (ch = UCHAR_MAX + 1; --ch >= 0; )
- {
- if ((code & M4_SYNTAX_MASKS) != 0)
- remove_syntax_attribute (syntax, ch, code);
- else if (m4_has_syntax (syntax, ch, code))
- add_syntax_attribute (syntax, ch, M4_SYNTAX_OTHER);
- }
- while (len--)
- {
- ch = *chars++;
- add_syntax_attribute (syntax, ch, code);
- }
-}
-
-/* Reset syntax category CODE to its default state, sending all other
- characters in the category back to their default state. */
-static void
-reset_syntax_set (m4_syntax_table *syntax, int code)
-{
- int ch;
- for (ch = UCHAR_MAX + 1; --ch >= 0; )
- {
- /* Reset the category back to its default state. All other
- characters that used to have this category get reset to
- their default state as well. */
- if (code == M4_SYNTAX_RQUOTE)
- {
- if (ch == '\'')
- add_syntax_attribute (syntax, ch, code);
- else
- remove_syntax_attribute (syntax, ch, code);
- }
- else if (code == M4_SYNTAX_ECOMM)
- {
- if (ch == '\n')
- add_syntax_attribute (syntax, ch, code);
- else
- remove_syntax_attribute (syntax, ch, code);
- }
- else if (code == M4_SYNTAX_DOLLAR)
- {
- if (ch == '$')
- add_syntax_attribute (syntax, ch, code);
- else
- remove_syntax_attribute (syntax, ch, code);
- }
- else if (code == M4_SYNTAX_LBRACE)
- {
- if (ch == '{')
- add_syntax_attribute (syntax, ch, code);
- else
- remove_syntax_attribute (syntax, ch, code);
- }
- else if (code == M4_SYNTAX_RBRACE)
- {
- if (ch == '}')
- add_syntax_attribute (syntax, ch, code);
- else
- remove_syntax_attribute (syntax, ch, code);
- }
- else if (syntax->orig[ch] == code || m4_has_syntax (syntax, ch, code))
- add_syntax_attribute (syntax, ch, syntax->orig[ch]);
- }
-}
-
-/* Reset the syntax table to its default state. */
-void
-m4_reset_syntax (m4_syntax_table *syntax)
-{
- /* Restore the default syntax, which has known quote and comment
- properties. */
- memcpy (syntax->table, syntax->orig, sizeof syntax->orig);
-
- free (syntax->quote.str1);
- free (syntax->quote.str2);
- free (syntax->comm.str1);
- free (syntax->comm.str2);
-
- /* The use of xmemdup0 is exploited by input.c. */
- syntax->quote.str1 = xmemdup0 (DEF_LQUOTE, 1);
- syntax->quote.len1 = 1;
- syntax->quote.str2 = xmemdup0 (DEF_RQUOTE, 1);
- syntax->quote.len2 = 1;
- syntax->comm.str1 = xmemdup0 (DEF_BCOMM, 1);
- syntax->comm.len1 = 1;
- syntax->comm.str2 = xmemdup0 (DEF_ECOMM, 1);
- syntax->comm.len2 = 1;
- syntax->dollar = '$';
-
- add_syntax_attribute (syntax, syntax->quote.str2[0], M4_SYNTAX_RQUOTE);
- add_syntax_attribute (syntax, syntax->comm.str2[0], M4_SYNTAX_ECOMM);
- add_syntax_attribute (syntax, '$', M4_SYNTAX_DOLLAR);
- add_syntax_attribute (syntax, '{', M4_SYNTAX_LBRACE);
- add_syntax_attribute (syntax, '}', M4_SYNTAX_RBRACE);
-
- syntax->is_single_quotes = true;
- syntax->is_single_comments = true;
- syntax->is_single_dollar = true;
- syntax->is_macro_escaped = false;
- set_quote_age (syntax, true, false);
-}
-
-/* Alter the syntax for category KEY, according to ACTION: '+' to add,
- '-' to subtract, '=' to set, or '\0' to reset. The array CHARS of
- length LEN describes the characters to modify; it is ignored if
- ACTION is '\0'. Return -1 if KEY is invalid, otherwise return the
- syntax category matching KEY. */
-int
-m4_set_syntax (m4_syntax_table *syntax, char key, char action,
- const char *chars, size_t len)
-{
- int code;
-
- assert (syntax && chars);
- code = m4_syntax_code (key);
- if (code < 0)
- {
- return -1;
- }
- syntax->suspect = false;
- switch (action)
- {
- case '+':
- add_syntax_set (syntax, chars, len, code);
- break;
- case '-':
- subtract_syntax_set (syntax, chars, len, code);
- break;
- case '=':
- set_syntax_set (syntax, chars, len, code);
- break;
- case '\0':
- assert (!len);
- reset_syntax_set (syntax, code);
- break;
- default:
- assert (false);
- }
-
- /* Check for any cleanup needed. */
- if (syntax->suspect)
- {
- int ch;
- int lquote = -1;
- int rquote = -1;
- int bcomm = -1;
- int ecomm = -1;
- bool single_quote_possible = true;
- bool single_comm_possible = true;
- int dollar = -1;
- if (m4_has_syntax (syntax, syntax->quote.str1[0], M4_SYNTAX_LQUOTE))
- {
- assert (syntax->quote.len1 == 1);
- lquote = to_uchar (syntax->quote.str1[0]);
- }
- if (m4_has_syntax (syntax, syntax->quote.str2[0], M4_SYNTAX_RQUOTE))
- {
- assert (syntax->quote.len2 == 1);
- rquote = to_uchar (syntax->quote.str2[0]);
- }
- if (m4_has_syntax (syntax, syntax->comm.str1[0], M4_SYNTAX_BCOMM))
- {
- assert (syntax->comm.len1 == 1);
- bcomm = to_uchar (syntax->comm.str1[0]);
- }
- if (m4_has_syntax (syntax, syntax->comm.str2[0], M4_SYNTAX_ECOMM))
- {
- assert (syntax->comm.len2 == 1);
- ecomm = to_uchar (syntax->comm.str2[0]);
- }
- syntax->is_single_dollar = false;
- syntax->is_macro_escaped = false;
- /* Find candidates for each category. */
- for (ch = UCHAR_MAX + 1; --ch >= 0; )
- {
- if (m4_has_syntax (syntax, ch, M4_SYNTAX_LQUOTE))
- {
- if (lquote == -1)
- lquote = ch;
- else if (lquote != ch)
- single_quote_possible = false;
- }
- if (m4_has_syntax (syntax, ch, M4_SYNTAX_RQUOTE))
- {
- if (rquote == -1)
- rquote = ch;
- else if (rquote != ch)
- single_quote_possible = false;
- }
- if (m4_has_syntax (syntax, ch, M4_SYNTAX_BCOMM))
- {
- if (bcomm == -1)
- bcomm = ch;
- else if (bcomm != ch)
- single_comm_possible = false;
- }
- if (m4_has_syntax (syntax, ch, M4_SYNTAX_ECOMM))
- {
- if (ecomm == -1)
- ecomm = ch;
- else if (ecomm != ch)
- single_comm_possible = false;
- }
- if (m4_has_syntax (syntax, ch, M4_SYNTAX_DOLLAR))
- {
- if (dollar == -1)
- {
- syntax->dollar = dollar = ch;
- syntax->is_single_dollar = true;
- }
- else
- syntax->is_single_dollar = false;
- }
- if (m4_has_syntax (syntax, ch, M4_SYNTAX_ESCAPE))
- syntax->is_macro_escaped = true;
- }
- /* Disable multi-character delimiters if we discovered
- delimiters. */
- if (!single_quote_possible)
- syntax->is_single_quotes = false;
- if (!single_comm_possible)
- syntax->is_single_comments = false;
- if ((1 < syntax->quote.len1 || 1 < syntax->quote.len2)
- && (!syntax->is_single_quotes || lquote != -1 || rquote != -1))
- {
- if (syntax->quote.len1)
- {
- syntax->quote.len1 = lquote == to_uchar (syntax->quote.str1[0]);
- syntax->quote.str1[syntax->quote.len1] = '\0';
- }
- if (syntax->quote.len2)
- {
- syntax->quote.len2 = rquote == to_uchar (syntax->quote.str2[0]);
- syntax->quote.str2[syntax->quote.len2] = '\0';
- }
- }
- if ((1 < syntax->comm.len1 || 1 < syntax->comm.len2)
- && (!syntax->is_single_comments || bcomm != -1 || ecomm != -1))
- {
- if (syntax->comm.len1)
- {
- syntax->comm.len1 = bcomm == to_uchar (syntax->comm.str1[0]);
- syntax->comm.str1[syntax->comm.len1] = '\0';
- }
- if (syntax->comm.len2)
- {
- syntax->comm.len2 = ecomm == to_uchar (syntax->comm.str2[0]);
- syntax->comm.str2[syntax->comm.len2] = '\0';
- }
- }
- /* Update the strings. */
- if (lquote != -1)
- {
- if (single_quote_possible)
- syntax->is_single_quotes = true;
- if (syntax->quote.len1)
- assert (syntax->quote.len1 == 1);
- else
- {
- free (syntax->quote.str1);
- syntax->quote.str1 = xcharalloc (2);
- syntax->quote.str1[1] = '\0';
- syntax->quote.len1 = 1;
- }
- syntax->quote.str1[0] = lquote;
- if (rquote == -1)
- {
- rquote = '\'';
- add_syntax_attribute (syntax, rquote, M4_SYNTAX_RQUOTE);
- }
- if (!syntax->quote.len2)
- {
- free (syntax->quote.str2);
- syntax->quote.str2 = xcharalloc (2);
- }
- syntax->quote.str2[0] = rquote;
- syntax->quote.str2[1] = '\0';
- syntax->quote.len2 = 1;
- }
- if (bcomm != -1)
- {
- if (single_comm_possible)
- syntax->is_single_comments = true;
- if (syntax->comm.len1)
- assert (syntax->comm.len1 == 1);
- else
- {
- free (syntax->comm.str1);
- syntax->comm.str1 = xcharalloc (2);
- syntax->comm.str1[1] = '\0';
- syntax->comm.len1 = 1;
- }
- syntax->comm.str1[0] = bcomm;
- if (ecomm == -1)
- {
- ecomm = '\n';
- add_syntax_attribute (syntax, ecomm, M4_SYNTAX_ECOMM);
- }
- if (!syntax->comm.len2)
- {
- free (syntax->comm.str2);
- syntax->comm.str2 = xcharalloc (2);
- }
- syntax->comm.str2[0] = ecomm;
- syntax->comm.str2[1] = '\0';
- syntax->comm.len2 = 1;
- }
- }
- set_quote_age (syntax, false, true);
- m4__quote_uncache (syntax);
- return code;
-}
-
-
-/* Functions for setting quotes and comment delimiters. Used by
- m4_changecom () and m4_changequote (). Both functions override the
- syntax table to maintain compatibility. */
-
-/* Set the quote delimiters to LQ and RQ, with respective lengths
- LQ_LEN and RQ_LEN. Pass NULL if the argument was not present, to
- distinguish from an explicit empty string. */
-void
-m4_set_quotes (m4_syntax_table *syntax, const char *lq, size_t lq_len,
- const char *rq, size_t rq_len)
-{
- int ch;
-
- assert (syntax);
-
- /* POSIX states that with 0 arguments, the default quotes are used.
- POSIX XCU ERN 112 states that behavior is implementation-defined
- if there was only one argument, or if there is an empty string in
- either position when there are two arguments. We allow an empty
- left quote to disable quoting, but a non-empty left quote will
- always create a non-empty right quote. See the texinfo for what
- some other implementations do. */
- if (!lq)
- {
- lq = DEF_LQUOTE;
- lq_len = 1;
- rq = DEF_RQUOTE;
- rq_len = 1;
- }
- else if (!rq || (lq_len && !rq_len))
- {
- rq = DEF_RQUOTE;
- rq_len = 1;
- }
-
- if (syntax->quote.len1 == lq_len && syntax->quote.len2 == rq_len
- && memcmp (syntax->quote.str1, lq, lq_len) == 0
- && memcmp (syntax->quote.str2, rq, rq_len) == 0)
- return;
-
- free (syntax->quote.str1);
- free (syntax->quote.str2);
- /* The use of xmemdup0 is exploited by input.c. */
- syntax->quote.str1 = xmemdup0 (lq, lq_len);
- syntax->quote.len1 = lq_len;
- syntax->quote.str2 = xmemdup0 (rq, rq_len);
- syntax->quote.len2 = rq_len;
-
- /* changequote overrides syntax_table, but be careful when it is
- used to select a start-quote sequence that is effectively
- disabled. */
- syntax->is_single_quotes = true;
- for (ch = UCHAR_MAX + 1; --ch >= 0; )
- {
- if (m4_has_syntax (syntax, ch, M4_SYNTAX_LQUOTE))
- add_syntax_attribute (syntax, ch,
- (syntax->orig[ch] == M4_SYNTAX_LQUOTE
- ? M4_SYNTAX_OTHER : syntax->orig[ch]));
- if (m4_has_syntax (syntax, ch, M4_SYNTAX_RQUOTE))
- remove_syntax_attribute (syntax, ch, M4_SYNTAX_RQUOTE);
- }
-
- if (!m4_has_syntax (syntax, *syntax->quote.str1,
- (M4_SYNTAX_IGNORE | M4_SYNTAX_ESCAPE | M4_SYNTAX_ALPHA
- | M4_SYNTAX_NUM)))
- {
- if (syntax->quote.len1 == 1)
- add_syntax_attribute (syntax, syntax->quote.str1[0], M4_SYNTAX_LQUOTE);
- if (syntax->quote.len2 == 1)
- add_syntax_attribute (syntax, syntax->quote.str2[0], M4_SYNTAX_RQUOTE);
- }
- set_quote_age (syntax, false, false);
-}
-
-/* Set the comment delimiters to BC and EC, with respective lengths
- BC_LEN and EC_LEN. Pass NULL if the argument was not present, to
- distinguish from an explicit empty string. */
-void
-m4_set_comment (m4_syntax_table *syntax, const char *bc, size_t bc_len,
- const char *ec, size_t ec_len)
-{
- int ch;
-
- assert (syntax);
-
- /* POSIX requires no arguments to disable comments, and that one
- argument use newline as the close-comment. POSIX XCU ERN 131
- states that empty arguments invoke implementation-defined
- behavior. We allow an empty begin comment to disable comments,
- and a non-empty begin comment will always create a non-empty end
- comment. See the texinfo for what some other implementations
- do. */
- if (!bc)
- {
- bc = ec = "";
- bc_len = ec_len = 0;
- }
- else if (!ec || (bc_len && !ec_len))
- {
- ec = DEF_ECOMM;
- ec_len = 1;
- }
-
- if (syntax->comm.len1 == bc_len && syntax->comm.len2 == ec_len
- && memcmp (syntax->comm.str1, bc, bc_len) == 0
- && memcmp (syntax->comm.str2, ec, ec_len) == 0)
- return;
-
- free (syntax->comm.str1);
- free (syntax->comm.str2);
- /* The use of xmemdup0 is exploited by input.c. */
- syntax->comm.str1 = xmemdup0 (bc, bc_len);
- syntax->comm.len1 = bc_len;
- syntax->comm.str2 = xmemdup0 (ec, ec_len);
- syntax->comm.len2 = ec_len;
-
- /* changecom overrides syntax_table, but be careful when it is used
- to select a start-comment sequence that is effectively
- disabled. */
- syntax->is_single_comments = true;
- for (ch = UCHAR_MAX + 1; --ch >= 0; )
- {
- if (m4_has_syntax (syntax, ch, M4_SYNTAX_BCOMM))
- add_syntax_attribute (syntax, ch,
- (syntax->orig[ch] == M4_SYNTAX_BCOMM
- ? M4_SYNTAX_OTHER : syntax->orig[ch]));
- if (m4_has_syntax (syntax, ch, M4_SYNTAX_ECOMM))
- remove_syntax_attribute (syntax, ch, M4_SYNTAX_ECOMM);
- }
- if (!m4_has_syntax (syntax, *syntax->comm.str1,
- (M4_SYNTAX_IGNORE | M4_SYNTAX_ESCAPE | M4_SYNTAX_ALPHA
- | M4_SYNTAX_NUM | M4_SYNTAX_LQUOTE)))
- {
- if (syntax->comm.len1 == 1)
- add_syntax_attribute (syntax, syntax->comm.str1[0], M4_SYNTAX_BCOMM);
- if (syntax->comm.len2 == 1)
- add_syntax_attribute (syntax, syntax->comm.str2[0], M4_SYNTAX_ECOMM);
- }
- set_quote_age (syntax, false, false);
-}
-
-/* Call this when changing anything that might impact the quote age,
- so that m4__quote_age and m4__safe_quotes will reflect the change.
- If RESET, changesyntax was reset to its default stage; if CHANGE,
- arbitrary syntax has changed; otherwise, just quotes or comment
- delimiters have changed. */
-static void
-set_quote_age (m4_syntax_table *syntax, bool reset, bool change)
-{
- /* Multi-character quotes are inherently unsafe, since concatenation
- of individual characters can result in a quote delimiter,
- consider:
-
- define(echo,``$1'')define(a,A)changequote(<[,]>)echo(<[]]><[>a]>)
- => A]> (not ]>a)
-
- Also, unquoted close delimiters are unsafe, consider:
-
- define(echo,``$1'')define(a,A)echo(`a''`a')
- => aA' (not a'a)
-
- Duplicated start and end quote delimiters, as well as comment
- delimiters that overlap with quote delimiters or active characters,
- also present a problem, consider:
-
- define(echo,$*)echo(a,a,a`'define(a,A)changecom(`,',`,'))
- => A,a,A (not A,A,A)
-
- The impact of arbitrary changesyntax is difficult to characterize.
- So if things are in their default state, we use 0 for the upper 16
- bits of quote_age; otherwise we increment syntax_age for each
- changesyntax, but saturate it at 0xffff rather than wrapping
- around. Perhaps a cache of other frequently used states is
- warranted, if changesyntax becomes more popular.
-
- Perhaps someday we will fix $@ expansion to use the current
- settings of the comma category, or even allow multi-character
- argument separators via changesyntax. Until then, we use a literal
- `,' in $@ expansion, therefore we must insist that `,' be an
- argument separator for quote_age to be non-zero.
-
- Rather than check every token for an unquoted delimiter, we merely
- encode current_quote_age to 0 when things are unsafe, and non-zero
- when safe (namely, the syntax_age in the upper 16 bits, coupled
- with the 16-bit value composed of the single-character start and
- end quote delimiters). There may be other situations which are
- safe even when this algorithm sets the quote_age to zero, but at
- least a quote_age of zero always produces correct results (although
- it may take more time in doing so). */
-
- unsigned short local_syntax_age;
- if (reset)
- local_syntax_age = 0;
- else if (change && syntax->syntax_age < 0xffff)
- local_syntax_age = ++syntax->syntax_age;
- else
- local_syntax_age = syntax->syntax_age;
- if (local_syntax_age < 0xffff && syntax->is_single_quotes
- && syntax->quote.len1 == 1 && syntax->quote.len2 == 1
- && !m4_has_syntax (syntax, *syntax->quote.str1,
- (M4_SYNTAX_ALPHA | M4_SYNTAX_NUM | M4_SYNTAX_OPEN
- | M4_SYNTAX_COMMA | M4_SYNTAX_CLOSE
- | M4_SYNTAX_SPACE))
- && !m4_has_syntax (syntax, *syntax->quote.str2,
- (M4_SYNTAX_ALPHA | M4_SYNTAX_NUM | M4_SYNTAX_OPEN
- | M4_SYNTAX_COMMA | M4_SYNTAX_CLOSE
- | M4_SYNTAX_SPACE))
- && *syntax->quote.str1 != *syntax->quote.str2
- && (!syntax->comm.len1
- || (*syntax->comm.str1 != *syntax->quote.str2
- && !m4_has_syntax (syntax, *syntax->comm.str1,
- (M4_SYNTAX_OPEN | M4_SYNTAX_COMMA
- | M4_SYNTAX_CLOSE))))
- && m4_has_syntax (syntax, ',', M4_SYNTAX_COMMA))
- {
- syntax->quote_age = ((local_syntax_age << 16)
- | ((*syntax->quote.str1 & 0xff) << 8)
- | (*syntax->quote.str2 & 0xff));
- }
- else
- syntax->quote_age = 0;
-}
-
-/* Interface for caching frequently used quote pairs, independently of
- the current quote delimiters (for example, consider a text macro
- expansion that includes several copies of $@), and using AGE for
- optimization. If QUOTES is NULL, don't use quoting. If OBS is
- non-NULL, AGE should be the current quote age, and QUOTES should be
- m4_get_syntax_quotes; the return value will be a cached quote pair,
- where the pointer is valid at least as long as OBS is not reset,
- but whose contents are only guaranteed until the next changequote
- or quote_cache. Otherwise, OBS is NULL, AGE should be the same as
- before, and QUOTES should be a previously returned cache value;
- used to refresh the contents of the result. */
-const m4_string_pair *
-m4__quote_cache (m4_syntax_table *syntax, m4_obstack *obs, unsigned int age,
- const m4_string_pair *quotes)
-{
- /* Implementation - if AGE is non-zero, then the implementation of
- set_quote_age guarantees that we can recreate the return value on
- the fly; so we use static storage, and the contents must be used
- immediately. If AGE is zero, then we must copy QUOTES onto OBS,
- but we might as well cache that copy. */
- if (!quotes)
- return NULL;
- if (age)
- {
- *syntax->cached_lquote = (age >> 8) & 0xff;
- *syntax->cached_rquote = age & 0xff;
- return &syntax->cached_simple;
- }
- if (!obs)
- return quotes;
- assert (quotes == &syntax->quote);
- if (!syntax->cached_quote)
- {
- assert (obstack_object_size (obs) == 0);
- syntax->cached_quote = (m4_string_pair *) obstack_copy (obs, quotes,
- sizeof *quotes);
- syntax->cached_quote->str1 = (char *) obstack_copy0 (obs, quotes->str1,
- quotes->len1);
- syntax->cached_quote->str2 = (char *) obstack_copy0 (obs, quotes->str2,
- quotes->len2);
- }
- return syntax->cached_quote;
-}
-
-
-/* Define these functions at the end, so that calls in the file use the
- faster macro version from m4module.h. */
-#undef m4_get_syntax_lquote
-const char *
-m4_get_syntax_lquote (m4_syntax_table *syntax)
-{
- assert (syntax);
- return syntax->quote.str1;
-}
-
-#undef m4_get_syntax_rquote
-const char *
-m4_get_syntax_rquote (m4_syntax_table *syntax)
-{
- assert (syntax);
- return syntax->quote.str2;
-}
-
-#undef m4_get_syntax_quotes
-const m4_string_pair *
-m4_get_syntax_quotes (m4_syntax_table *syntax)
-{
- assert (syntax);
- return &syntax->quote;
-}
-
-#undef m4_is_syntax_single_quotes
-bool
-m4_is_syntax_single_quotes (m4_syntax_table *syntax)
-{
- assert (syntax);
- return syntax->is_single_quotes;
-}
-
-#undef m4_get_syntax_bcomm
-const char *
-m4_get_syntax_bcomm (m4_syntax_table *syntax)
-{
- assert (syntax);
- return syntax->comm.str1;
-}
-
-#undef m4_get_syntax_ecomm
-const char *
-m4_get_syntax_ecomm (m4_syntax_table *syntax)
-{
- assert (syntax);
- return syntax->comm.str2;
-}
-
-#undef m4_get_syntax_comments
-const m4_string_pair *
-m4_get_syntax_comments (m4_syntax_table *syntax)
-{
- assert (syntax);
- return &syntax->comm;
-}
-
-#undef m4_is_syntax_single_comments
-bool
-m4_is_syntax_single_comments (m4_syntax_table *syntax)
-{
- assert (syntax);
- return syntax->is_single_comments;
-}
-
-#undef m4_is_syntax_single_dollar
-bool
-m4_is_syntax_single_dollar (m4_syntax_table *syntax)
-{
- assert (syntax);
- return syntax->is_single_dollar;
-}
-
-#undef m4_is_syntax_macro_escaped
-bool
-m4_is_syntax_macro_escaped (m4_syntax_table *syntax)
-{
- assert (syntax);
- return syntax->is_macro_escaped;
-}
diff --git a/m4/system_.h b/m4/system_.h
deleted file mode 100644
index 7176b383..00000000
--- a/m4/system_.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2000-2001, 2003, 2006-2008, 2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/**
- * @configure_output@
- *
- * This file is installed, so cannot rely on the contents of config.h.
- * It works best if included _before_ system headers.
- **/
-
-#ifndef M4_SYSTEM_H
-#define M4_SYSTEM_H 1
-
-#include <gnu/stdlib--.h>
-#include <gnu/stdio--.h>
-#include <gnu/unistd--.h>
-
-#include <assert.h>
-#include <ctype.h>
-#include <errno.h>
-#include <limits.h>
-#include <stdint.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-
-@INCLUDE_ERROR_H@
-@INCLUDE_OBSTACK_H@
-@INCLUDE_REGEX_H@
-@INCLUDE_STDBOOL_H@
-
-#include <gnu/xalloc.h>
-#include <gnu/xprintf.h>
-#include <gnu/xstrndup.h>
-
-/* In addition to EXIT_SUCCESS and EXIT_FAILURE, m4 can fail with version
- mismatch when trying to load a frozen file produced by a newer m4 than
- the version doing the reload. */
-#define EXIT_MISMATCH 63
-
-/* This is okay in an installed file, because it will not change the
- behaviour of the including program whether ENABLE_NLS is defined
- or not. */
-#ifndef _
-# ifdef ENABLE_NLS
-# include <libintl.h>
-# define _(Text) gettext (Text)
-# define N_(Text) gettext_noop (Text)
-# else
-# define _(Text) (Text)
-# define N_(Text) (Text)
-# endif
-#endif
-
-
-/* All header files should be inside BEGIN_C_DECLS ... END_C_DECLS, so
- that the library can be linked into a C++ program. The multi-include
- guard macros must be outside, as should any #includes -- for simplicity
- everything else should go inside. */
-
-#ifndef BEGIN_C_DECLS
-# ifdef __cplusplus
-# define BEGIN_C_DECLS extern "C" {
-# define END_C_DECLS }
-# else /* !__cplusplus */
-# define BEGIN_C_DECLS /* empty */
-# define END_C_DECLS /* empty */
-# endif /* __cplusplus */
-#endif /* !BEGIN_C_DECLS */
-
-BEGIN_C_DECLS
-
-
-
-/* Canonicalize UNIX recognition macros. */
-#if defined unix || defined __unix || defined __unix__ \
- || defined _POSIX_VERSION || defined _POSIX2_VERSION \
- || defined __NetBSD__ || defined __OpenBSD__ \
- || defined __APPLE__ || defined __APPLE_CC__
-# define UNIX 1
-#endif
-
-/* Canonicalize Windows recognition macros. */
-#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
-# define W32_NATIVE 1
-#endif
-
-/* Canonicalize OS/2 recognition macro. */
-#ifdef __EMX__
-# define OS2 1
-# undef UNIX
-#endif
-
-
-/* M4_STMT_START/END are used to create macros which expand to a
- a single compound statement in a portable way, but crucially in
- a way sympathetic to the compiler to maximise optimization. */
-#undef M4_STMT_START
-#undef M4_STMT_END
-#if defined __GNUC__ && !defined __STRICT_ANSI__ && !defined __cplusplus
-# define M4_STMT_START (void)(
-# define M4_STMT_END )
-#else
-# if defined sun || defined __sun__
-# define M4_STMT_START if (1)
-# define M4_STMT_END else (void)0
-# else
-# define M4_STMT_START do
-# define M4_STMT_END while (0)
-# endif
-#endif
-
-
-
-/* Take advantage of GNU C compiler source level optimization hints,
- using portable macros. */
-#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 6)
-# define M4_GNUC_ATTRIBUTE(args) __attribute__ (args)
-#else
-# define M4_GNUC_ATTRIBUTE(args)
-#endif /* __GNUC__ */
-
-#define M4_GNUC_PRINTF(fmt, arg) \
- M4_GNUC_ATTRIBUTE ((__format__ (__printf__, fmt, arg)))
-#define M4_GNUC_SCANF(fmt, arg) \
- M4_GNUC_ATTRIBUTE ((__format__ (__scanf__, fmt, arg)))
-#define M4_GNUC_NORETURN M4_GNUC_ATTRIBUTE ((__noreturn__))
-#define M4_GNUC_CONST M4_GNUC_ATTRIBUTE ((__const__))
-#define M4_GNUC_UNUSED M4_GNUC_ATTRIBUTE ((__unused__))
-#define M4_GNUC_PURE M4_GNUC_ATTRIBUTE ((__pure__))
-
-
-
-#if !defined __PRETTY_FUNCTION__
-# define __PRETTY_FUNCTION__ "<unknown>"
-#endif
-
-
-/* Preprocessor token manipulation. */
-
-/* The extra indirection to the _STR and _CONC macros is required so that
- if the arguments to STR() (or CONC()) are themselves macros, they will
- be expanded before being quoted. */
-#ifndef STR
-# define _STR(arg) #arg
-# define STR(arg) _STR (arg)
-#endif
-
-#ifndef CONC
-# define _CONC(a, b) a##b
-# define CONC(a, b) _CONC (a, b)
-#endif
-
-END_C_DECLS
-
-#endif /* !M4_SYSTEM_H */
diff --git a/m4/utility.c b/m4/utility.c
deleted file mode 100644
index 2063c6a3..00000000
--- a/m4/utility.c
+++ /dev/null
@@ -1,292 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 1998-1999, 2003, 2006-2010, 2013-2014, 2017
- Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include "m4private.h"
-
-#include "exitfail.h"
-#include "progname.h"
-#include "quotearg.h"
-#include "verror.h"
-#include "xvasprintf.h"
-
-static const char *skip_space (m4 *, const char *);
-
-
-
-/* Give friendly warnings if a builtin macro is passed an
- inappropriate number of arguments. MIN is the 0-based minimum
- number of acceptable arguments, MAX is the 0-based maximum number
- or UINT_MAX if not applicable, and SIDE_EFFECT is true if the macro
- has side effects even if min is not satisfied. ARGC is the 1-based
- count of supplied arguments, and CALLER is the name of the macro.
- Return true if the macro is guaranteed to expand to the empty
- string, false otherwise. */
-bool
-m4_bad_argc (m4 *context, size_t argc, const m4_call_info *caller, size_t min,
- size_t max, bool side_effect)
-{
- if (argc - 1 < min)
- {
- m4_warn (context, 0, caller, _("too few arguments: %zu < %zu"),
- argc - 1, min);
- return !side_effect;
- }
-
- if (argc - 1 > max)
- {
- m4_warn (context, 0, caller, _("extra arguments ignored: %zu > %zu"),
- argc - 1, max);
- }
-
- return false;
-}
-
-static const char *
-skip_space (m4 *context, const char *arg)
-{
- while (m4_has_syntax (M4SYNTAX, *arg, M4_SYNTAX_SPACE))
- arg++;
- return arg;
-}
-
-/* The function m4_numeric_arg () converts ARG of length LEN to an int
- pointed to by VALUEP. If the conversion fails, print error message
- for CALLER. Return true iff conversion succeeds. */
-/* FIXME: Convert this to use gnulib's xstrtoimax, xstrtoumax.
- Otherwise, we are arbitrarily limiting integer values. */
-bool
-m4_numeric_arg (m4 *context, const m4_call_info *caller, const char *arg,
- size_t len, int *valuep)
-{
- char *endp;
-
- if (!len)
- {
- *valuep = 0;
- m4_warn (context, 0, caller, _("empty string treated as 0"));
- }
- else
- {
- const char *str = skip_space (context, arg);
- *valuep = strtol (str, &endp, 10);
- if (endp - arg != len)
- {
- m4_warn (context, 0, caller, _("non-numeric argument %s"),
- quotearg_style_mem (locale_quoting_style, arg, len));
- return false;
- }
- if (str != arg)
- m4_warn (context, 0, caller, _("leading whitespace ignored"));
- else if (errno == ERANGE)
- m4_warn (context, 0, caller, _("numeric overflow detected"));
- }
- return true;
-}
-
-/* Parse ARG of length LEN as a truth value. If ARG is NUL, use ""
- instead; otherwise, ARG must have a NUL-terminator (even if it also
- has embedded NUL). If LEN is SIZE_MAX, use the string length of
- ARG. If unrecognized, issue a warning on behalf of CALLER and
- return PREVIOUS; otherwise return the parsed value. */
-bool
-m4_parse_truth_arg (m4 *context, const m4_call_info *caller, const char *arg,
- size_t len, bool previous)
-{
- /* 0, no, off, blank... */
- if (!arg || len == 0
- || arg[0] == '0'
- || arg[0] == 'n' || arg[0] == 'N'
- || ((arg[0] == 'o' || arg[0] == 'O')
- && (arg[1] == 'f' || arg[1] == 'F')))
- return false;
- /* 1, yes, on... */
- if (arg[0] == '1'
- || arg[0] == 'y' || arg[0] == 'Y'
- || ((arg[0] == 'o' || arg[0] == 'O')
- && (arg[1] == 'n' || arg[1] == 'N')))
- return true;
- m4_warn (context, 0, caller, _("unknown directive %s"),
- quotearg_style_mem (locale_quoting_style, arg, len));
- return previous;
-}
-
-/* Helper method to look up a symbol table entry given an argument.
- Warn on behalf of ARGV if VALUE is not a text argument, or if
- MUST_EXIST and no macro exists by the name in VALUE. Return the
- result of the lookup, or NULL. */
-m4_symbol *
-m4_symbol_value_lookup (m4 *context, m4_macro_args *argv, size_t i,
- bool must_exist)
-{
- m4_symbol *result = NULL;
- if (m4_is_arg_text (argv, i))
- {
- const char *name = M4ARG (i);
- size_t len = M4ARGLEN (i);
- result = m4_symbol_lookup (M4SYMTAB, name, len);
- if (must_exist && !result
- && m4_is_debug_bit (context, M4_DEBUG_TRACE_DEREF))
- m4_warn (context, 0, argv->info, _("undefined macro %s"),
- quotearg_style_mem (locale_quoting_style, name, len));
- }
- else
- m4_warn (context, 0, argv->info, _("invalid macro name ignored"));
- return result;
-}
-
-/* Return an escaped version of the macro name corresponding to
- CALLER, for use in error messages that do not use the m4_warn
- machinery. This call occupies slot 0 of the quotearg
- machinery. */
-const char *m4_info_name (const m4_call_info *caller)
-{
- return quotearg_style_mem (locale_quoting_style, caller->name,
- caller->name_len);
-}
-
-/* Helper for all error reporting. Report message based on FORMAT and
- ARGS, on behalf of CALLER (if any), otherwise at the global
- position in CONTEXT. If ERRNUM, decode the errno value as part of
- the message. If STATUS, exit immediately with that status. If
- WARN, prepend 'warning: '. */
-static void
-m4_verror_at_line (m4 *context, bool warn, int status, int errnum,
- const m4_call_info *caller, const char *format,
- va_list args)
-{
- char *full = NULL;
- char *safe_macro = NULL;
- const char *macro = caller ? caller->name : NULL;
- size_t len = caller ? caller->name_len : 0;
- const char *file = caller ? caller->file : m4_get_current_file (context);
- int line = caller ? caller->line : m4_get_current_line (context);
-
- assert (file || !line);
- /* Sanitize MACRO, since we are turning around and using it in a
- format string. The allocation is overly conservative, but
- problematic macro names only occur via indir or changesyntax. */
- if (macro && memchr (macro, '%', len))
- {
- char *p = safe_macro = xcharalloc (2 * len);
- const char *end = macro + len;
- while (macro != end)
- {
- if (*macro == '%')
- {
- *p++ = '%';
- len++;
- }
- *p++ = *macro++;
- }
- }
- if (macro)
- /* Use slot 1, so that the rest of the code can use the simpler
- quotearg interface in slot 0. */
- macro = quotearg_n_mem (1, safe_macro ? safe_macro : macro, len);
- /* Prepend warning and the macro name, as needed. But if that fails
- for non-memory reasons (unlikely), then still use the original
- format. */
- if (warn && macro)
- full = xasprintf (_("warning: %s: %s"), macro, format);
- else if (warn)
- full = xasprintf (_("warning: %s"), format);
- else if (macro)
- full = xasprintf (_("%s: %s"), macro, format);
- verror_at_line (status, errnum, line ? file : NULL, line,
- full ? full : format, args);
- free (full);
- free (safe_macro);
- if ((!warn || m4_get_fatal_warnings_opt (context))
- && !m4_get_exit_status (context))
- m4_set_exit_status (context, EXIT_FAILURE);
-}
-
-/* Issue an error. The message is printf-style, based on FORMAT and
- any other arguments, and the program name and location (if we are
- currently parsing an input file) are automatically prepended. If
- ERRNUM is non-zero, include strerror output in the message. If
- CALLER, prepend the message with the macro where the message
- occurred. If STATUS is non-zero, or if errors are fatal, call exit
- immediately; otherwise, remember that an error occurred so that m4
- cannot exit with success later on.*/
-void
-m4_error (m4 *context, int status, int errnum, const m4_call_info *caller,
- const char *format, ...)
-{
- va_list args;
- va_start (args, format);
- if (status == EXIT_SUCCESS && m4_get_warnings_exit_opt (context))
- status = EXIT_FAILURE;
- m4_verror_at_line (context, false, status, errnum, caller, format, args);
- va_end (args);
-}
-
-/* Issue a warning, if they are not being suppressed. The message is
- printf-style, based on FORMAT and any other arguments, and the
- program name, location (if we are currently parsing an input file),
- and "warning:" are automatically prepended. If ERRNUM is non-zero,
- include strerror output in the message. If CALLER, prepend the
- message with the macro where the message occurred. If warnings are
- fatal, call exit immediately, otherwise exit status is
- unchanged. */
-void
-m4_warn (m4 *context, int errnum, const m4_call_info *caller,
- const char *format, ...)
-{
- if (!m4_get_suppress_warnings_opt (context))
- {
- va_list args;
- int status = EXIT_SUCCESS;
- va_start (args, format);
- if (m4_get_warnings_exit_opt (context))
- status = EXIT_FAILURE;
- m4_verror_at_line (context, true, status, errnum, caller, format, args);
- va_end (args);
- }
-}
-
-/* Wrap the gnulib progname module, to avoid exporting a global
- variable from a library. Retrieve the program name for use in
- error messages and the __program__ macro. */
-const char *
-m4_get_program_name (void)
-{
- return program_name;
-}
-
-/* Wrap the gnulib progname module, to avoid exporting a global
- variable from a library. Set the program name for use in error
- messages and the __program__ macro to argv[0]. */
-void
-m4_set_program_name (const char *name)
-{
- set_program_name (name);
-}
-
-/* Wrap the gnulib exitfail module, to avoid exporting a global
- variable from a library. Set the exit status for use in gnulib
- modules and atexit handlers. */
-void
-m4_set_exit_failure (int status)
-{
- exit_failure = status;
-}
diff --git a/modules/evalparse.c b/modules/evalparse.c
deleted file mode 100644
index d70d6060..00000000
--- a/modules/evalparse.c
+++ /dev/null
@@ -1,1029 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2001, 2006-2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* This file contains the functions to evaluate integer expressions
- for the "eval" and "evalmp" builtins. It is a little, fairly
- self-contained module, with its own scanner, and a recursive descent
- parser.
-
- It has been carefully factored for use from the GMP module builtin,
- mpeval: any actual operation performed on numbers is abstracted by
- a set of macro definitions. For plain `eval', `number' is some
- long int type, and `numb_*' manipulate those long ints. When
- using GMP, `number' is typedef'd to `mpq_t' (the arbritrary
- precision fractional numbers type of GMP), and `numb_*' are mapped
- to GMP functions.
-
- There is only one entry point, `m4_evaluate', a single function for
- both `eval' and `mpeval', but which is redefined appropriately when
- this file is #included into its clients. */
-
-#include "quotearg.h"
-
-typedef enum eval_token
- {
- ERROR, BADOP,
- PLUS, MINUS,
- EXPONENT,
- TIMES, DIVIDE, MODULO, RATIO,
- EQ, NOTEQ, GT, GTEQ, LS, LSEQ,
- LSHIFT, RSHIFT, URSHIFT,
- LNOT, LAND, LOR,
- NOT, AND, OR, XOR,
- LEFTP, RIGHTP,
- QUESTION, COLON, COMMA,
- NUMBER, EOTEXT
- }
-eval_token;
-
-/* Error types. */
-
-typedef enum eval_error
- {
- NO_ERROR,
- DIVIDE_ZERO,
- MODULO_ZERO,
- NEGATIVE_EXPONENT,
- /* All errors prior to SYNTAX_ERROR can be ignored in a dead
- branch of && and ||. All errors after are just more details
- about a syntax error. */
- SYNTAX_ERROR,
- MISSING_RIGHT,
- MISSING_COLON,
- UNKNOWN_INPUT,
- EXCESS_INPUT,
- INVALID_OPERATOR
- }
-eval_error;
-
-static eval_error comma_term (m4 *, eval_token, number *);
-static eval_error condition_term (m4 *, eval_token, number *);
-static eval_error logical_or_term (m4 *, eval_token, number *);
-static eval_error logical_and_term (m4 *, eval_token, number *);
-static eval_error or_term (m4 *, eval_token, number *);
-static eval_error xor_term (m4 *, eval_token, number *);
-static eval_error and_term (m4 *, eval_token, number *);
-static eval_error equality_term (m4 *, eval_token, number *);
-static eval_error cmp_term (m4 *, eval_token, number *);
-static eval_error shift_term (m4 *, eval_token, number *);
-static eval_error add_term (m4 *, eval_token, number *);
-static eval_error mult_term (m4 *, eval_token, number *);
-static eval_error exp_term (m4 *, eval_token, number *);
-static eval_error unary_term (m4 *, eval_token, number *);
-static eval_error simple_term (m4 *, eval_token, number *);
-static eval_error numb_pow (number *, number *);
-
-
-
-/* --- LEXICAL FUNCTIONS --- */
-
-/* Pointer to next character of input text. */
-static const char *eval_text;
-
-/* Value of eval_text, from before last call of eval_lex (). This is so we
- can back up, if we have read too much. */
-static const char *last_text;
-
-/* Detect when to end parsing. */
-static const char *end_text;
-
-/* Prime the lexer at the start of TEXT, with length LEN. */
-static void
-eval_init_lex (const char *text, size_t len)
-{
- eval_text = text;
- end_text = text + len;
- last_text = NULL;
-}
-
-static void
-eval_undo (void)
-{
- eval_text = last_text;
-}
-
-/* VAL is numerical value, if any. Recognize C assignment operators,
- even though we cannot support them, to issue better error
- messages. */
-
-static eval_token
-eval_lex (number *val)
-{
- while (eval_text != end_text && isspace (to_uchar (*eval_text)))
- eval_text++;
-
- last_text = eval_text;
-
- if (eval_text == end_text)
- return EOTEXT;
-
- if (isdigit (to_uchar (*eval_text)))
- {
- int base, digit;
-
- if (*eval_text == '0')
- {
- eval_text++;
- switch (*eval_text)
- {
- case 'x':
- case 'X':
- base = 16;
- eval_text++;
- break;
-
- case 'b':
- case 'B':
- base = 2;
- eval_text++;
- break;
-
- case 'r':
- case 'R':
- base = 0;
- eval_text++;
- while (isdigit (to_uchar (*eval_text)) && base <= 36)
- base = 10 * base + *eval_text++ - '0';
- if (base == 0 || base > 36 || *eval_text != ':')
- return ERROR;
- eval_text++;
- break;
-
- default:
- base = 8;
- }
- }
- else
- base = 10;
-
- numb_set_si (val, 0);
- for (; *eval_text; eval_text++)
- {
- if (isdigit (to_uchar (*eval_text)))
- digit = *eval_text - '0';
- else if (islower (to_uchar (*eval_text)))
- digit = *eval_text - 'a' + 10;
- else if (isupper (to_uchar (*eval_text)))
- digit = *eval_text - 'A' + 10;
- else
- break;
-
- if (base == 1)
- {
- if (digit == 1)
- numb_incr (*val);
- else if (digit == 0 && numb_zerop (*val))
- continue;
- else
- break;
- }
- else if (digit >= base)
- break;
- else
- {
- number xbase;
- number xdigit;
-
- /* (*val) = (*val) * base; */
- numb_init (xbase);
- numb_set_si (&xbase, base);
- numb_times (*val, xbase);
- numb_fini (xbase);
- /* (*val) = (*val) + digit; */
- numb_init (xdigit);
- numb_set_si (&xdigit, digit);
- numb_plus (*val, xdigit);
- numb_fini (xdigit);
- }
- }
- return NUMBER;
- }
-
- switch (*eval_text++)
- {
- case '+':
- if (*eval_text == '+' || *eval_text == '=')
- return BADOP;
- return PLUS;
- case '-':
- if (*eval_text == '-' || *eval_text == '=')
- return BADOP;
- return MINUS;
- case '*':
- if (*eval_text == '*')
- {
- eval_text++;
- return EXPONENT;
- }
- else if (*eval_text == '=')
- return BADOP;
- return TIMES;
- case '/':
- if (*eval_text == '=')
- return BADOP;
- return DIVIDE;
- case '%':
- if (*eval_text == '=')
- return BADOP;
- return MODULO;
- case '\\':
- return RATIO;
- case '=':
- if (*eval_text == '=')
- {
- eval_text++;
- return EQ;
- }
- return BADOP;
- case '!':
- if (*eval_text == '=')
- {
- eval_text++;
- return NOTEQ;
- }
- return LNOT;
- case '>':
- if (*eval_text == '=')
- {
- eval_text++;
- return GTEQ;
- }
- else if (*eval_text == '>')
- {
- eval_text++;
- if (*eval_text == '=')
- return BADOP;
- else if (*eval_text == '>')
- {
- eval_text++;
- return URSHIFT;
- }
- return RSHIFT;
- }
- else
- return GT;
- case '<':
- if (*eval_text == '=')
- {
- eval_text++;
- return LSEQ;
- }
- else if (*eval_text == '<')
- {
- if (*++eval_text == '=')
- return BADOP;
- return LSHIFT;
- }
- else
- return LS;
- case '^':
- if (*eval_text == '=')
- return BADOP;
- return XOR;
- case '~':
- return NOT;
- case '&':
- if (*eval_text == '&')
- {
- eval_text++;
- return LAND;
- }
- else if (*eval_text == '=')
- return BADOP;
- return AND;
- case '|':
- if (*eval_text == '|')
- {
- eval_text++;
- return LOR;
- }
- else if (*eval_text == '=')
- return BADOP;
- return OR;
- case '(':
- return LEFTP;
- case ')':
- return RIGHTP;
- case '?':
- return QUESTION;
- case ':':
- return COLON;
- case ',':
- return COMMA;
- default:
- return ERROR;
- }
-}
-
-/* Recursive descent parser. */
-static eval_error
-comma_term (m4 *context, eval_token et, number *v1)
-{
- number v2;
- eval_error er;
-
- if ((er = condition_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((et = eval_lex (&v2)) == COMMA)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = condition_term (context, et, &v2)) != NO_ERROR)
- return er;
- numb_set (*v1, v2);
- }
- numb_fini (v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-condition_term (m4 *context, eval_token et, number *v1)
-{
- number v2;
- number v3;
- eval_error er;
-
- if ((er = logical_or_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- numb_init (v3);
- if ((et = eval_lex (&v2)) == QUESTION)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- /* Implement short-circuiting of valid syntax. */
- er = comma_term (context, et, &v2);
- if (er != NO_ERROR
- && !(numb_zerop (*v1) && er < SYNTAX_ERROR))
- return er;
-
- et = eval_lex (&v3);
- if (et == ERROR)
- return UNKNOWN_INPUT;
- if (et != COLON)
- return MISSING_COLON;
-
- et = eval_lex (&v3);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- er = condition_term (context, et, &v3);
- if (er != NO_ERROR
- && !(! numb_zerop (*v1) && er < SYNTAX_ERROR))
- return er;
-
- numb_set (*v1, ! numb_zerop (*v1) ? v2 : v3);
- }
- numb_fini (v2);
- numb_fini (v3);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-logical_or_term (m4 *context, eval_token et, number *v1)
-{
- number v2;
- eval_error er;
-
- if ((er = logical_and_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((et = eval_lex (&v2)) == LOR)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- /* Implement short-circuiting of valid syntax. */
- er = logical_and_term (context, et, &v2);
- if (er == NO_ERROR)
- numb_lior (*v1, v2);
- else if (! numb_zerop (*v1) && er < SYNTAX_ERROR)
- numb_set (*v1, numb_ONE);
- else
- return er;
- }
- numb_fini (v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-logical_and_term (m4 *context, eval_token et, number *v1)
-{
- number v2;
- eval_error er;
-
- if ((er = or_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((et = eval_lex (&v2)) == LAND)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- /* Implement short-circuiting of valid syntax. */
- er = or_term (context, et, &v2);
- if (er == NO_ERROR)
- numb_land (*v1, v2);
- else if (numb_zerop (*v1) && er < SYNTAX_ERROR)
- numb_set (*v1, numb_ZERO);
- else
- return er;
- }
- numb_fini (v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-or_term (m4 *context, eval_token et, number *v1)
-{
- number v2;
- eval_error er;
-
- if ((er = xor_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((et = eval_lex (&v2)) == OR)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = xor_term (context, et, &v2)) != NO_ERROR)
- return er;
-
- numb_ior (context, v1, &v2);
- }
- numb_fini (v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-xor_term (m4 *context, eval_token et, number *v1)
-{
- number v2;
- eval_error er;
-
- if ((er = and_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((et = eval_lex (&v2)) == XOR)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = and_term (context, et, &v2)) != NO_ERROR)
- return er;
-
- numb_eor (context, v1, &v2);
- }
- numb_fini (v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-and_term (m4 *context, eval_token et, number *v1)
-{
- number v2;
- eval_error er;
-
- if ((er = equality_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((et = eval_lex (&v2)) == AND)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = equality_term (context, et, &v2)) != NO_ERROR)
- return er;
-
- numb_and (context, v1, &v2);
- }
- numb_fini (v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-equality_term (m4 *context, eval_token et, number *v1)
-{
- eval_token op;
- number v2;
- eval_error er;
-
- if ((er = cmp_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((op = eval_lex (&v2)) == EQ || op == NOTEQ)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = cmp_term (context, et, &v2)) != NO_ERROR)
- return er;
-
- if (op == EQ)
- numb_eq (*v1, v2);
- else
- numb_ne (*v1, v2);
- }
- numb_fini (v2);
- if (op == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-cmp_term (m4 *context, eval_token et, number *v1)
-{
- eval_token op;
- number v2;
- eval_error er;
-
- if ((er = shift_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((op = eval_lex (&v2)) == GT || op == GTEQ
- || op == LS || op == LSEQ)
- {
-
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = shift_term (context, et, &v2)) != NO_ERROR)
- return er;
-
- switch (op)
- {
- case GT:
- numb_gt (*v1, v2);
- break;
-
- case GTEQ:
- numb_ge (*v1, v2);
- break;
-
- case LS:
- numb_lt (*v1, v2);
- break;
-
- case LSEQ:
- numb_le (*v1, v2);
- break;
-
- default:
- assert (!"INTERNAL ERROR: bad comparison operator in cmp_term ()");
- abort ();
- }
- }
- numb_fini (v2);
- if (op == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-shift_term (m4 *context, eval_token et, number *v1)
-{
- eval_token op;
- number v2;
- eval_error er;
-
- if ((er = add_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((op = eval_lex (&v2)) == LSHIFT || op == RSHIFT || op == URSHIFT)
- {
-
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = add_term (context, et, &v2)) != NO_ERROR)
- return er;
-
- switch (op)
- {
- case LSHIFT:
- numb_lshift (context, v1, &v2);
- break;
-
- case RSHIFT:
- numb_rshift (context, v1, &v2);
- break;
-
- case URSHIFT:
- numb_urshift (context, v1, &v2);
- break;
-
- default:
- assert (!"INTERNAL ERROR: bad shift operator in shift_term ()");
- abort ();
- }
- }
- numb_fini (v2);
- if (op == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-add_term (m4 *context, eval_token et, number *v1)
-{
- eval_token op;
- number v2;
- eval_error er;
-
- if ((er = mult_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((op = eval_lex (&v2)) == PLUS || op == MINUS)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = mult_term (context, et, &v2)) != NO_ERROR)
- return er;
-
- if (op == PLUS)
- numb_plus (*v1, v2);
- else
- numb_minus (*v1, v2);
- }
- numb_fini (v2);
- if (op == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-mult_term (m4 *context, eval_token et, number *v1)
-{
- eval_token op;
- number v2;
- eval_error er;
-
- if ((er = exp_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while (op = eval_lex (&v2),
- op == TIMES
- || op == DIVIDE
- || op == MODULO
- || op == RATIO)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = exp_term (context, et, &v2)) != NO_ERROR)
- return er;
-
- switch (op)
- {
- case TIMES:
- numb_times (*v1, v2);
- break;
-
- case DIVIDE:
- if (numb_zerop (v2))
- return DIVIDE_ZERO;
- else
- numb_divide(v1, &v2);
- break;
-
- case RATIO:
- if (numb_zerop (v2))
- return DIVIDE_ZERO;
- else
- numb_ratio (*v1, v2);
- break;
-
- case MODULO:
- if (numb_zerop (v2))
- return MODULO_ZERO;
- else
- numb_modulo (context, v1, &v2);
- break;
-
- default:
- assert (!"INTERNAL ERROR: bad operator in mult_term ()");
- abort ();
- }
- }
- numb_fini (v2);
- if (op == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-exp_term (m4 *context, eval_token et, number *v1)
-{
- number v2;
- eval_error er;
-
- if ((er = unary_term (context, et, v1)) != NO_ERROR)
- return er;
-
- numb_init (v2);
- while ((et = eval_lex (&v2)) == EXPONENT)
- {
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = exp_term (context, et, &v2)) != NO_ERROR)
- return er;
-
- if ((er = numb_pow (v1, &v2)) != NO_ERROR)
- return er;
- }
- numb_fini (v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- eval_undo ();
- return NO_ERROR;
-}
-
-static eval_error
-unary_term (m4 *context, eval_token et, number *v1)
-{
- eval_error er;
-
- if (et == PLUS || et == MINUS || et == NOT || et == LNOT)
- {
- eval_token et2 = eval_lex (v1);
- if (et2 == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = unary_term (context, et2, v1)) != NO_ERROR)
- return er;
-
- if (et == MINUS)
- numb_negate(*v1);
- else if (et == NOT)
- numb_not (context, v1);
- else if (et == LNOT)
- numb_lnot (*v1);
- }
- else if ((er = simple_term (context, et, v1)) != NO_ERROR)
- return er;
-
- return NO_ERROR;
-}
-
-static eval_error
-simple_term (m4 *context, eval_token et, number *v1)
-{
- number v2;
- eval_error er;
-
- switch (et)
- {
- case LEFTP:
- et = eval_lex (v1);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if ((er = comma_term (context, et, v1)) != NO_ERROR)
- return er;
-
- et = eval_lex (&v2);
- if (et == ERROR)
- return UNKNOWN_INPUT;
-
- if (et != RIGHTP)
- return MISSING_RIGHT;
-
- break;
-
- case NUMBER:
- break;
-
- case BADOP:
- return INVALID_OPERATOR;
-
- default:
- return SYNTAX_ERROR;
- }
- return NO_ERROR;
-}
-
-/* Main entry point, called from "eval" and "mpeval" builtins. */
-void
-m4_evaluate (m4 *context, m4_obstack *obs, size_t argc, m4_macro_args *argv)
-{
- const m4_call_info *me = m4_arg_info (argv);
- const char * str = M4ARG (1);
- int radix = 10;
- int min = 1;
- number val;
- eval_token et;
- eval_error err = NO_ERROR;
-
- if (!m4_arg_empty (argv, 2)
- && !m4_numeric_arg (context, me, M4ARG (2), M4ARGLEN (2), &radix))
- return;
-
- if (radix < 1 || radix > 36)
- {
- m4_warn (context, 0, me, _("radix out of range: %d"), radix);
- return;
- }
-
- if (argc >= 4 && !m4_numeric_arg (context, me, M4ARG (3), M4ARGLEN (3),
- &min))
- return;
-
- if (min < 0)
- {
- m4_warn (context, 0, me, _("negative width: %d"), min);
- return;
- }
-
- numb_initialise ();
- eval_init_lex (str, M4ARGLEN (1));
-
- numb_init (val);
- et = eval_lex (&val);
- if (et == EOTEXT)
- {
- m4_warn (context, 0, me, _("empty string treated as 0"));
- numb_set (val, numb_ZERO);
- }
- else
- err = comma_term (context, et, &val);
-
- if (err == NO_ERROR && *eval_text != '\0')
- {
- if (eval_lex (&val) == BADOP)
- err = INVALID_OPERATOR;
- else
- err = EXCESS_INPUT;
- }
-
- if (err != NO_ERROR)
- str = quotearg_style_mem (locale_quoting_style, str, M4ARGLEN (1));
- switch (err)
- {
- case NO_ERROR:
- numb_obstack (obs, val, radix, min);
- break;
-
- case MISSING_RIGHT:
- m4_warn (context, 0, me, _("missing right parenthesis: %s"), str);
- break;
-
- case MISSING_COLON:
- m4_warn (context, 0, me, _("missing colon: %s"), str);
- break;
-
- case SYNTAX_ERROR:
- m4_warn (context, 0, me, _("bad expression: %s"), str);
- break;
-
- case UNKNOWN_INPUT:
- m4_warn (context, 0, me, _("bad input: %s"), str);
- break;
-
- case EXCESS_INPUT:
- m4_warn (context, 0, me, _("excess input: %s"), str);
- break;
-
- case INVALID_OPERATOR:
- m4_warn (context, 0, me, _("invalid operator: %s"), str);
- break;
-
- case DIVIDE_ZERO:
- m4_warn (context, 0, me, _("divide by zero: %s"), str);
- break;
-
- case MODULO_ZERO:
- m4_warn (context, 0, me, _("modulo by zero: %s"), str);
- break;
-
- case NEGATIVE_EXPONENT:
- m4_warn (context, 0, me, _("negative exponent: %s"), str);
- break;
-
- default:
- assert (!"INTERNAL ERROR: bad error code in evaluate ()");
- abort ();
- }
-
- numb_fini (val);
-}
-
-static eval_error
-numb_pow (number *x, number *y)
-{
- /* y should be integral */
-
- number ans, yy;
-
- numb_init (ans);
- numb_set_si (&ans, 1);
-
- if (numb_zerop (*x) && numb_zerop (*y))
- return DIVIDE_ZERO;
-
- numb_init (yy);
- numb_set (yy, *y);
-
- if (numb_negativep (yy))
- {
- numb_negate (yy);
- numb_invert (*x);
- }
-
- while (numb_positivep (yy))
- {
- numb_times (ans, *x);
- numb_decr (yy);
- }
- numb_set (*x, ans);
-
- numb_fini (ans);
- numb_fini (yy);
- return NO_ERROR;
-}
diff --git a/modules/format.c b/modules/format.c
deleted file mode 100644
index 2c87fcc3..00000000
--- a/modules/format.c
+++ /dev/null
@@ -1,425 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2001, 2006-2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* printf like formatting for m4. */
-
-#include "vasnprintf.h"
-
-/* Simple varargs substitute. We assume int and unsigned int are the
- same size; likewise for long and unsigned long. We do not yet
- handle long double or long long. */
-
-/* Parse STR of length LEN as an integer, reporting warnings on behalf
- of ME. */
-static int
-arg_int (struct m4 *context, const m4_call_info *me, const char *str,
- size_t len)
-{
- char *endp;
- long value;
-
- /* TODO - also allow parsing `'a' or `"a' which results in the
- numeric value of 'a', as in printf(1). */
- if (!len)
- {
- m4_warn (context, 0, me, _("empty string treated as 0"));
- return 0;
- }
- errno = 0;
- value = strtol (str, &endp, 10);
- if (endp - str != len)
- m4_warn (context, 0, me, _("non-numeric argument %s"),
- quotearg_style_mem (locale_quoting_style, str, len));
- else if (isspace (to_uchar (*str)))
- m4_warn (context, 0, me, _("leading whitespace ignored"));
- else if (errno == ERANGE || (int) value != value)
- m4_warn (context, 0, me, _("numeric overflow detected"));
- return value;
-}
-
-/* Parse STR of length LEN as a long, reporting warnings on behalf of
- ME. */
-static long
-arg_long (struct m4 *context, const m4_call_info *me, const char *str,
- size_t len)
-{
- char *endp;
- long value;
-
- /* TODO - also allow parsing `'a' or `"a' which results in the
- numeric value of 'a', as in printf(1). */
- if (!len)
- {
- m4_warn (context, 0, me, _("empty string treated as 0"));
- return 0L;
- }
- errno = 0;
- value = strtol (str, &endp, 10);
- if (endp - str != len)
- m4_warn (context, 0, me, _("non-numeric argument %s"),
- quotearg_style_mem (locale_quoting_style, str, len));
- else if (isspace (to_uchar (*str)))
- m4_warn (context, 0, me, _("leading whitespace ignored"));
- else if (errno == ERANGE)
- m4_warn (context, 0, me, _("numeric overflow detected"));
- return value;
-}
-
-/* Check STR of length LEN for embedded NUL, reporting warnings on
- behalf of ME. */
-static const char *
-arg_string (struct m4 *context, const m4_call_info *me, const char *str,
- size_t len)
-{
- if (strlen (str) < len)
- m4_warn (context, 0, me, _("argument %s truncated"),
- quotearg_style_mem (locale_quoting_style, str, len));
- return str;
-}
-
-/* Parse STR of length LEN as a double, reporting warnings on behalf
- of ME. */
-static double
-arg_double (struct m4 *context, const m4_call_info *me, const char *str,
- size_t len)
-{
- char *endp;
- double value;
-
- if (!len)
- {
- m4_warn (context, 0, me, _("empty string treated as 0"));
- return 0.0;
- }
- errno = 0;
- value = strtod (str, &endp);
- if (endp - str != len)
- m4_warn (context, 0, me, _("non-numeric argument %s"),
- quotearg_style_mem (locale_quoting_style, str, len));
- else if (isspace (to_uchar (*str)))
- m4_warn (context, 0, me, _("leading whitespace ignored"));
- else if (errno == ERANGE)
- m4_warn (context, 0, me, _("numeric overflow detected"));
- return value;
-}
-
-#define ARG_INT(i, argc, argv) \
- ((argc <= ++i) ? 0 : arg_int (context, me, M4ARG (i), M4ARGLEN (i)))
-
-#define ARG_LONG(i, argc, argv) \
- ((argc <= ++i) ? 0L : arg_long (context, me, M4ARG (i), M4ARGLEN (i)))
-
-#define ARG_STR(i, argc, argv) \
- ((argc <= ++i) ? "" : arg_string (context, me, M4ARG (i), M4ARGLEN (i)))
-
-#define ARG_DOUBLE(i, argc, argv) \
- ((argc <= ++i) ? 0.0 : arg_double (context, me, M4ARG (i), M4ARGLEN (i)))
-
-
-/* The main formatting function. Output is placed on the obstack OBS,
- the first argument in ARGV is the formatting string, and the rest
- is arguments for the string. Warn rather than invoke unspecified
- behavior in the underlying printf when we do not recognize a
- format. */
-
-static void
-format (m4 *context, m4_obstack *obs, int argc, m4_macro_args *argv)
-{
- const m4_call_info *me = m4_arg_info (argv);
- const char *f; /* Format control string. */
- size_t f_len; /* Length of f. */
- const char *fmt; /* Position within f. */
- char fstart[] = "%'+- 0#*.*hhd"; /* Current format spec. */
- char *p; /* Position within fstart. */
- unsigned char c; /* A simple character. */
- int i = 1; /* Index within argc used so far. */
- bool valid_format = true; /* True if entire format string ok. */
-
- /* Flags. */
- char flags; /* Flags to use in fstart. */
- enum {
- THOUSANDS = 0x01, /* '\''. */
- PLUS = 0x02, /* '+'. */
- MINUS = 0x04, /* '-'. */
- SPACE = 0x08, /* ' '. */
- ZERO = 0x10, /* '0'. */
- ALT = 0x20, /* '#'. */
- DONE = 0x40 /* No more flags. */
- };
-
- /* Precision specifiers. */
- int width; /* Minimum field width. */
- int prec; /* Precision. */
- char lflag; /* Long flag. */
-
- /* Specifiers we are willing to accept. ok['x'] implies %x is ok.
- Various modifiers reduce the set, in order to avoid undefined
- behavior in printf. */
- char ok[128];
-
- /* Check that formatted text succeeded with correct type. */
- int result = 0;
- enum {CHAR, INT, LONG, DOUBLE, STR} datatype;
-
- f = fmt = M4ARG (1);
- f_len = M4ARGLEN (1);
- assert (!f[f_len]); /* Requiring a terminating NUL makes parsing simpler. */
- memset (ok, 0, sizeof ok);
- while (1)
- {
- const char *percent = (char *) memchr (fmt, '%', f_len);
- if (!percent)
- {
- obstack_grow (obs, fmt, f_len);
- break;
- }
- obstack_grow (obs, fmt, percent - fmt);
- f_len -= percent - fmt + 1;
- fmt = percent + 1;
-
- if (*fmt == '%')
- {
- obstack_1grow (obs, '%');
- fmt++;
- f_len--;
- continue;
- }
-
- p = fstart + 1; /* % */
- lflag = 0;
- ok['a'] = ok['A'] = ok['c'] = ok['d'] = ok['e'] = ok['E']
- = ok['f'] = ok['F'] = ok['g'] = ok['G'] = ok['i'] = ok['o']
- = ok['s'] = ok['u'] = ok['x'] = ok['X'] = 1;
-
- /* Parse flags. */
- flags = 0;
- do
- {
- switch (*fmt)
- {
- case '\'': /* thousands separator */
- ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E']
- = ok['o'] = ok['s'] = ok['x'] = ok['X'] = 0;
- flags |= THOUSANDS;
- break;
-
- case '+': /* mandatory sign */
- ok['c'] = ok['o'] = ok['s'] = ok['u'] = ok['x'] = ok['X'] = 0;
- flags |= PLUS;
- break;
-
- case ' ': /* space instead of positive sign */
- ok['c'] = ok['o'] = ok['s'] = ok['u'] = ok['x'] = ok['X'] = 0;
- flags |= SPACE;
- break;
-
- case '0': /* zero padding */
- ok['c'] = ok['s'] = 0;
- flags |= ZERO;
- break;
-
- case '#': /* alternate output */
- ok['c'] = ok['d'] = ok['i'] = ok['s'] = ok['u'] = 0;
- flags |= ALT;
- break;
-
- case '-': /* left justification */
- flags |= MINUS;
- break;
-
- default:
- flags |= DONE;
- break;
- }
- }
- while (!(flags & DONE) && (f_len--, fmt++));
- if (flags & THOUSANDS)
- *p++ = '\'';
- if (flags & PLUS)
- *p++ = '+';
- if (flags & MINUS)
- *p++ = '-';
- if (flags & SPACE)
- *p++ = ' ';
- if (flags & ZERO)
- *p++ = '0';
- if (flags & ALT)
- *p++ = '#';
-
- /* Minimum field width; an explicit 0 is the same as not giving
- the width. */
- width = 0;
- *p++ = '*';
- if (*fmt == '*')
- {
- width = ARG_INT (i, argc, argv);
- fmt++;
- f_len--;
- }
- else
- while (isdigit ((unsigned char) *fmt))
- {
- width = 10 * width + *fmt - '0';
- fmt++;
- f_len--;
- }
-
- /* Maximum precision; an explicit negative precision is the same
- as not giving the precision. A lone '.' is a precision of 0. */
- prec = -1;
- *p++ = '.';
- *p++ = '*';
- if (*fmt == '.')
- {
- ok['c'] = 0;
- f_len--;
- if (*(++fmt) == '*')
- {
- prec = ARG_INT (i, argc, argv);
- ++fmt;
- f_len--;
- }
- else
- {
- prec = 0;
- while (isdigit ((unsigned char) *fmt))
- {
- prec = 10 * prec + *fmt - '0';
- fmt++;
- f_len--;
- }
- }
- }
-
- /* Length modifiers. We don't yet recognize ll, j, t, or z. */
- if (*fmt == 'l')
- {
- *p++ = 'l';
- lflag = 1;
- fmt++;
- f_len--;
- ok['c'] = ok['s'] = 0;
- }
- else if (*fmt == 'h')
- {
- *p++ = 'h';
- fmt++;
- f_len--;
- if (*fmt == 'h')
- {
- *p++ = 'h';
- fmt++;
- f_len--;
- }
- ok['a'] = ok['A'] = ok['c'] = ok['e'] = ok['E'] = ok['f'] = ok['F']
- = ok['g'] = ok['G'] = ok['s'] = 0;
- }
-
- c = *fmt;
- if (sizeof ok <= c || !ok[c] || !f_len)
- {
- m4_warn (context, 0, me, _("unrecognized specifier in %s"),
- quotearg_style_mem (locale_quoting_style, f, M4ARGLEN (1)));
- valid_format = false;
- if (f_len > 0)
- {
- fmt++;
- f_len--;
- }
- continue;
- }
- fmt++;
- f_len--;
-
- /* Specifiers. We don't yet recognize C, S, n, or p. */
- switch (c)
- {
- case 'c':
- datatype = CHAR;
- p -= 2; /* %.*c is undefined, so undo the '.*'. */
- break;
-
- case 's':
- datatype = STR;
- break;
-
- case 'd':
- case 'i':
- case 'o':
- case 'x':
- case 'X':
- case 'u':
- datatype = lflag ? LONG : INT;
- break;
-
- case 'a':
- case 'A':
- case 'e':
- case 'E':
- case 'f':
- case 'F':
- case 'g':
- case 'G':
- datatype = DOUBLE;
- break;
-
- default:
- abort ();
- }
- *p++ = c;
- *p = '\0';
-
- switch (datatype)
- {
- case CHAR:
- result = obstack_printf (obs, fstart, width,
- ARG_INT (i, argc, argv));
- break;
-
- case INT:
- result = obstack_printf (obs, fstart, width, prec,
- ARG_INT (i, argc, argv));
- break;
-
- case LONG:
- result = obstack_printf (obs, fstart, width, prec,
- ARG_LONG (i, argc, argv));
- break;
-
- case DOUBLE:
- result = obstack_printf (obs, fstart, width, prec,
- ARG_DOUBLE (i, argc, argv));
- break;
-
- case STR:
- result = obstack_printf (obs, fstart, width, prec,
- ARG_STR (i, argc, argv));
- break;
-
- default:
- abort ();
- }
- /* Since obstack_printf can only fail with EILSEQ or EINVAL, but
- we constructed fstart, the result should not be negative. */
- assert (0 <= result);
- }
- if (valid_format)
- m4_bad_argc (context, argc, me, i, i, true);
-}
diff --git a/modules/gnu.c b/modules/gnu.c
deleted file mode 100644
index 334ab67d..00000000
--- a/modules/gnu.c
+++ /dev/null
@@ -1,1077 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2000, 2004-2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-/* Build using only the exported interfaces, unles NDEBUG is set, in
- which case use private symbols to speed things up as much as possible. */
-#ifndef NDEBUG
-# include <m4/m4module.h>
-#else
-# include "m4private.h"
-#endif
-
-#include "modules/m4.h"
-#include "quotearg.h"
-#include "spawn-pipe.h"
-#include "wait-process.h"
-
-/* Maintain each of the builtins implemented in this modules along
- with their details in a single table for easy maintenance.
-
- function macros blind side minargs maxargs */
-#define builtin_functions \
- BUILTIN (__file__, false, false, false, 0, 0 ) \
- BUILTIN (__line__, false, false, false, 0, 0 ) \
- BUILTIN (__program__, false, false, false, 0, 0 ) \
- BUILTIN (builtin, true, true, false, 1, -1 ) \
- BUILTIN (changeresyntax,false,true, false, 1, 1 ) \
- BUILTIN (changesyntax,false, true, false, 1, -1 ) \
- BUILTIN (debugfile, false, false, false, 0, 1 ) \
- BUILTIN (debuglen, false, true, false, 1, 1 ) \
- BUILTIN (debugmode, false, false, false, 0, 1 ) \
- BUILTIN (esyscmd, false, true, true, 1, 1 ) \
- BUILTIN (format, false, true, false, 1, -1 ) \
- BUILTIN (indir, true, true, false, 1, -1 ) \
- BUILTIN (mkdtemp, false, true, false, 1, 1 ) \
- BUILTIN (patsubst, false, true, true, 2, 4 ) \
- BUILTIN (regexp, false, true, true, 2, 4 ) \
- BUILTIN (renamesyms, false, true, false, 2, 3 ) \
- BUILTIN (m4modules, false, false, false, 0, 0 ) \
- BUILTIN (m4symbols, true, false, false, 0, -1 ) \
- BUILTIN (syncoutput, false, true, false, 1, 1 ) \
-
-
-/* Generate prototypes for each builtin handler function. */
-#define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler)
- builtin_functions
-#undef BUILTIN
-
-
-/* Generate a table for mapping m4 symbol names to handler functions. */
-static const m4_builtin m4_builtin_table[] =
-{
-#define BUILTIN(handler, macros, blind, side, min, max) \
- M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
-
- builtin_functions
-#undef BUILTIN
-
- { NULL, NULL, 0, 0, 0 },
-};
-
-
-/* A table for mapping m4 symbol names to simple expansion text. */
-static const m4_macro m4_macro_table[] =
-{
- /* name text min max */
-#if UNIX
- { "__unix__", "", 0, 0 },
-#endif
-#if W32_NATIVE
- { "__windows__", "", 0, 0 },
-#endif
-#if OS2
- { "__os2__", "", 0, 0 },
-#endif
- { "__gnu__", "", 0, 0 },
- { "__m4_version__", VERSION,0, 0 },
-
- { NULL, NULL, 0, 0 },
-};
-
-
-void
-include_gnu (m4 *context, m4_module *module, m4_obstack *obs)
-{
- m4_install_builtins (context, module, m4_builtin_table);
- m4_install_macros (context, module, m4_macro_table);
-}
-
-
-
-/* Regular expressions. Reuse re_registers among multiple
- re_pattern_buffer allocations to reduce malloc usage. */
-
-/* Maybe this is worth making runtime tunable. Too small, and nothing
- gets cached because the working set of active regex is larger than
- the cache, and we are always swapping out entries. Too large, and
- the time spent searching the cache for a match overtakes the time
- saved by caching. For now, this size proved reasonable for the
- typical working set of Autoconf 2.62. */
-#define REGEX_CACHE_SIZE 16
-
-/* Structure for using a compiled regex, as well as making it easier
- to cache frequently used expressions. */
-typedef struct {
- unsigned count; /* usage counter */
- int resyntax; /* flavor of regex */
- size_t len; /* length of string */
- char *str; /* copy of compiled string */
- struct re_pattern_buffer *pat; /* compiled regex, allocated */
- struct re_registers regs; /* match registers, reused */
-} m4_pattern_buffer;
-
-/* Storage for the cache of regular expressions. */
-static m4_pattern_buffer regex_cache[REGEX_CACHE_SIZE];
-
-/* Compile a REGEXP of length LEN using the RESYNTAX flavor, and
- return the buffer. On error, report the problem on behalf of
- CALLER, and return NULL. */
-
-static m4_pattern_buffer *
-regexp_compile (m4 *context, const m4_call_info *caller, const char *regexp,
- size_t len, int resyntax)
-{
- /* regex_cache is guaranteed to start life 0-initialized, which
- works in the algorithm below.
-
- FIXME - this method is not reentrant, since re_compile_pattern
- mallocs memory, depends on the global variable re_syntax_options
- for its syntax (but at least the compiled regex remembers its
- syntax even if the global variable changes later), and since we
- use a static variable. To be reentrant, we would need a mutex in
- this method, and move the storage for regex_cache into context. */
-
- const char *msg; /* error message from re_compile_pattern */
- int i; /* iterator */
- m4_pattern_buffer *victim; /* cache slot to replace */
- unsigned victim_count; /* track which victim to replace */
- struct re_pattern_buffer *pat;/* newly compiled regex */
-
- /* First, check if REGEXP is already cached with the given RESYNTAX.
- If so, increase its use count and return it. */
- for (i = 0; i < REGEX_CACHE_SIZE; i++)
- if (len == regex_cache[i].len && resyntax == regex_cache[i].resyntax
- && regex_cache[i].str && memcmp (regexp, regex_cache[i].str, len) == 0)
- {
- regex_cache[i].count++;
- return &regex_cache[i];
- }
-
- /* Next, check if REGEXP can be compiled. */
- pat = (struct re_pattern_buffer *) xzalloc (sizeof *pat);
- re_set_syntax (resyntax);
- msg = re_compile_pattern (regexp, len, pat);
-
- if (msg != NULL)
- {
- m4_warn (context, 0, caller, _("bad regular expression %s: %s"),
- quotearg_style_mem (locale_quoting_style, regexp, len), msg);
- regfree (pat);
- free (pat);
- return NULL;
- }
- /* Use a fastmap for speed; it is freed by regfree. */
- pat->fastmap = xcharalloc (UCHAR_MAX + 1);
-
- /* Now, find a victim slot. Decrease the count of all entries, then
- prime the count of the victim slot at REGEX_CACHE_SIZE. This
- way, frequently used entries and newly created entries are least
- likely to be victims next time we have a cache miss. */
- victim = regex_cache;
- victim_count = victim->count;
- if (victim_count)
- victim->count--;
- for (i = 1; i < REGEX_CACHE_SIZE; i++)
- {
- if (regex_cache[i].count < victim_count)
- {
- victim_count = regex_cache[i].count;
- victim = &regex_cache[i];
- }
- if (regex_cache[i].count)
- regex_cache[i].count--;
- }
- victim->count = REGEX_CACHE_SIZE;
- victim->resyntax = resyntax;
- victim->len = len;
- if (victim->str)
- {
- free (victim->str);
- regfree (victim->pat);
- free (victim->pat);
- }
- victim->str = xstrdup (regexp);
- victim->pat = pat;
- re_set_registers (pat, &victim->regs, victim->regs.num_regs,
- victim->regs.start, victim->regs.end);
- return victim;
-}
-
-
-/* Wrap up GNU Regex re_search call to work with an m4_pattern_buffer.
- If NO_SUB, then storing matches in buf->regs is not necessary. */
-
-static regoff_t
-regexp_search (m4_pattern_buffer *buf, const char *string, const int size,
- const int start, const int range, bool no_sub)
-{
- return re_search (buf->pat, string, size, start, range,
- no_sub ? NULL : &buf->regs);
-}
-
-
-/* Function to perform substitution by regular expressions. Used by
- the builtins regexp, patsubst and renamesyms. The changed text is
- placed on the obstack OBS. The substitution is REPL of length
- REPL_LEN, with \& substituted by this part of VICTIM matched by the
- last whole regular expression, and \N substituted by the text
- matched by the Nth parenthesized sub-expression in BUF. Any
- warnings are issued on behalf of CALLER. BUF may be NULL for the
- empty regex. */
-
-static void
-substitute (m4 *context, m4_obstack *obs, const m4_call_info *caller,
- const char *victim, const char *repl, size_t repl_len,
- m4_pattern_buffer *buf)
-{
- int ch;
- while (1)
- {
- const char *backslash = (char *) memchr (repl, '\\', repl_len);
- if (!backslash)
- {
- obstack_grow (obs, repl, repl_len);
- return;
- }
- obstack_grow (obs, repl, backslash - repl);
- repl_len -= backslash - repl + 1;
- if (!repl_len)
- {
- m4_warn (context, 0, caller,
- _("trailing \\ ignored in replacement"));
- return;
- }
- repl = backslash + 1;
- ch = *repl++;
- repl_len--;
- switch (ch)
- {
- case '&':
- if (buf)
- obstack_grow (obs, victim + buf->regs.start[0],
- buf->regs.end[0] - buf->regs.start[0]);
- break;
-
- case '1': case '2': case '3': case '4': case '5': case '6':
- case '7': case '8': case '9':
- ch -= '0';
- if (!buf || buf->pat->re_nsub < ch)
- m4_warn (context, 0, caller, _("sub-expression %d not present"),
- ch);
- else if (buf->regs.end[ch] > 0)
- obstack_grow (obs, victim + buf->regs.start[ch],
- buf->regs.end[ch] - buf->regs.start[ch]);
- break;
-
- default:
- obstack_1grow (obs, ch);
- break;
- }
- }
-}
-
-
-/* For each match against REGEXP of length REGEXP_LEN (precompiled in
- BUF as returned by regexp_compile) in VICTIM of length LEN,
- substitute REPLACE of length REPL_LEN. Non-matching characters are
- copied verbatim, and the result copied to the obstack. Errors are
- reported on behalf of CALLER. Return true if a substitution was
- made. If OPTIMIZE is set, don't worry about copying the input if
- no changes are made. */
-
-static bool
-regexp_substitute (m4 *context, m4_obstack *obs, const m4_call_info *caller,
- const char *victim, size_t len, const char *regexp,
- size_t regexp_len, m4_pattern_buffer *buf,
- const char *replace, size_t repl_len, bool optimize)
-{
- regoff_t matchpos = 0; /* start position of match */
- size_t offset = 0; /* current match offset */
- bool subst = !optimize; /* if a substitution has been made */
-
- while (offset <= len)
- {
- matchpos = regexp_search (buf, victim, len, offset, len - offset,
- false);
-
- if (matchpos < 0)
- {
-
- /* Match failed -- either error or there is no match in the
- rest of the string, in which case the rest of the string is
- copied verbatim. */
-
- if (matchpos == -2)
- m4_error (context, 0, 0, caller,
- _("problem matching regular expression %s"),
- quotearg_style_mem (locale_quoting_style, regexp,
- regexp_len));
- else if (offset < len && subst)
- obstack_grow (obs, victim + offset, len - offset);
- break;
- }
-
- /* Copy the part of the string that was skipped by re_search (). */
-
- if (matchpos > offset)
- obstack_grow (obs, victim + offset, matchpos - offset);
-
- /* Handle the part of the string that was covered by the match. */
-
- substitute (context, obs, caller, victim, replace, repl_len, buf);
- subst = true;
-
- /* Update the offset to the end of the match. If the regexp
- matched a null string, advance offset one more, to avoid
- infinite loops. */
-
- offset = buf->regs.end[0];
- if (buf->regs.start[0] == buf->regs.end[0])
- {
- if (offset < len)
- obstack_1grow (obs, victim[offset]);
- offset++;
- }
- }
-
- return subst;
-}
-
-
-
-/**
- * __file__
- **/
-M4BUILTIN_HANDLER (__file__)
-{
- m4_shipout_string (context, obs, m4_get_current_file (context), SIZE_MAX,
- true);
-}
-
-
-/**
- * __line__
- **/
-M4BUILTIN_HANDLER (__line__)
-{
- m4_shipout_int (obs, m4_get_current_line (context));
-}
-
-
-/**
- * __program__
- **/
-M4BUILTIN_HANDLER (__program__)
-{
- m4_shipout_string (context, obs, m4_get_program_name (), SIZE_MAX, true);
-}
-
-
-/* The builtin "builtin" allows calls to builtin macros, even if their
- definition has been overridden or shadowed. It is thus possible to
- redefine builtins, and still access their original definition. A
- special form allows one to retrieve the special token that defn
- would normally return, even if that builtin is not currently
- defined and hence can't be passed to defn. */
-
-/**
- * builtin(MACRO, [...])
- * builtin(defn(`builtin'), MACRO)
- **/
-M4BUILTIN_HANDLER (builtin)
-{
- const m4_call_info *me = m4_arg_info (argv);
- const char *name;
- size_t len;
- m4_symbol_value *value = NULL;
-
- if (!m4_is_arg_text (argv, 1))
- {
- assert (m4_is_arg_func (argv, 1));
- if (m4_arg_func (argv, 1) == builtin_builtin)
- {
- if (m4_bad_argc (context, argc, me, 2, 2, false))
- return;
- if (!m4_is_arg_text (argv, 2))
- {
- m4_warn (context, 0, me, _("invalid macro name ignored"));
- return;
- }
- name = M4ARG (2);
- len = M4ARGLEN (2);
- if (len == strlen (name))
- value = m4_builtin_find_by_name (context, NULL, name);
- if (value)
- {
- m4_push_builtin (context, obs, value);
- free (value);
- }
- else if (m4_is_debug_bit (context, M4_DEBUG_TRACE_DEREF))
- m4_warn (context, 0, me, _("undefined builtin %s"),
- quotearg_style_mem (locale_quoting_style, name, len));
- }
- else
- m4_warn (context, 0, me, _("invalid macro name ignored"));
- }
- else
- {
- name = M4ARG (1);
- len = M4ARGLEN (1);
- if (len == strlen (name))
- value = m4_builtin_find_by_name (context, NULL, name);
- if (value == NULL)
- {
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_DEREF))
- m4_warn (context, 0, me, _("undefined builtin %s"),
- quotearg_style_mem (locale_quoting_style, name, len));
- }
- else
- {
- const m4_builtin *bp = m4_get_symbol_value_builtin (value);
- m4_macro_args *new_argv;
- bool flatten = (bp->flags & M4_BUILTIN_FLATTEN_ARGS) != 0;
- new_argv = m4_make_argv_ref (context, argv, name, len, flatten,
- false);
- if (!m4_bad_argc (context, argc - 1, m4_arg_info (new_argv),
- bp->min_args, bp->max_args,
- (bp->flags & M4_BUILTIN_SIDE_EFFECT) != 0))
- bp->func (context, obs, argc - 1, new_argv);
- free (value);
- }
- }
-}
-
-
-/* Change the current regexp syntax to SPEC of length LEN, or report
- failure on behalf of CALLER. Currently this affects the builtins:
- `patsubst', `regexp' and `renamesyms'. */
-
-static int
-m4_resyntax_encode_safe (m4 *context, const m4_call_info *caller,
- const char *spec, size_t len)
-{
- int resyntax;
-
- if (strlen (spec) < len)
- resyntax = -1;
- else
- resyntax = m4_regexp_syntax_encode (spec);
-
- if (resyntax < 0)
- m4_warn (context, 0, caller, _("bad syntax-spec: %s"),
- quotearg_style_mem (locale_quoting_style, spec, len));
-
- return resyntax;
-}
-
-
-/**
- * changeresyntax(RESYNTAX-SPEC)
- **/
-M4BUILTIN_HANDLER (changeresyntax)
-{
- int resyntax = m4_resyntax_encode_safe (context, m4_arg_info (argv),
- M4ARG (1), M4ARGLEN (1));
-
- if (resyntax >= 0)
- m4_set_regexp_syntax_opt (context, resyntax);
-}
-
-
-/* Change the current input syntax. The function m4_set_syntax ()
- lives in syntax.c. Any changes to comment delimiters and quotes
- made here will be overridden by a call to `changecom' or
- `changequote'. */
-
-/**
- * changesyntax(SYNTAX-SPEC, ...)
- **/
-M4BUILTIN_HANDLER (changesyntax)
-{
- const m4_call_info *me = m4_arg_info (argv);
- M4_MODULE_IMPORT (m4, m4_expand_ranges);
-
- if (m4_expand_ranges)
- {
- size_t i;
- for (i = 1; i < argc; i++)
- {
- size_t len = M4ARGLEN (i);
- const char *spec;
- char key;
- char action;
-
- if (!len)
- {
- m4_reset_syntax (M4SYNTAX);
- continue;
- }
- spec = M4ARG (i);
- key = *spec++;
- len--;
- action = len ? *spec : '\0';
- switch (action)
- {
- case '-':
- case '+':
- case '=':
- spec++;
- len--;
- break;
- case '\0':
- if (!len)
- break;
- /* fall through */
- default:
- action = '=';
- break;
- }
- if (len)
- spec = m4_expand_ranges (spec, &len, m4_arg_scratch (context));
- if (m4_set_syntax (M4SYNTAX, key, action, spec, len) < 0)
- m4_warn (context, 0, me, _("undefined syntax code: %s"),
- quotearg_style_mem (locale_quoting_style, &key, 1));
- }
- }
- else
- assert (!"Unable to import from m4 module");
-}
-
-
-/* Specify the destination of the debugging output. With one argument, the
- argument is taken as a file name, with no arguments, revert to stderr. */
-
-/**
- * debugfile([FILENAME])
- **/
-M4BUILTIN_HANDLER (debugfile)
-{
- const m4_call_info *me = m4_arg_info (argv);
-
- if (argc == 1)
- m4_debug_set_output (context, me, NULL);
- else if (m4_get_safer_opt (context) && !m4_arg_empty (argv, 1))
- m4_error (context, 0, 0, me, _("disabled by --safer"));
- else
- {
- const char *str = M4ARG (1);
- size_t len = M4ARGLEN (1);
- if (strlen (str) < len)
- m4_warn (context, 0, me, _("argument %s truncated"),
- quotearg_style_mem (locale_quoting_style, str, len));
- if (!m4_debug_set_output (context, me, str))
- m4_warn (context, errno, me, _("cannot set debug file %s"),
- quotearg_style (locale_quoting_style, str));
- }
-}
-
-
-/* On-the-fly control of debug length. It takes one integer
- argument. */
-
-/**
- * debuglen(LEN)
- **/
-M4BUILTIN_HANDLER (debuglen)
-{
- int i;
- size_t s;
- if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1),
- &i))
- return;
- /* FIXME - make m4_numeric_arg more powerful - we want to accept
- suffixes, and limit the result to size_t. */
- s = i <= 0 ? SIZE_MAX : i;
- m4_set_max_debug_arg_length_opt (context, s);
-}
-
-/* On-the-fly control of the format of the tracing output. It takes one
- argument, which is a character string like given to the -d option, or
- none in which case the debug_level is zeroed. */
-
-/**
- * debugmode([FLAGS])
- **/
-M4BUILTIN_HANDLER (debugmode)
-{
- const char* mode = M4ARG (1);
- size_t len = M4ARGLEN (1);
- if (argc == 1)
- m4_set_debug_level_opt (context, 0);
- else if (m4_debug_decode (context, mode, len) < 0)
- m4_warn (context, 0, m4_arg_info (argv),
- _("bad debug flags: %s"),
- quotearg_style_mem (locale_quoting_style, mode, len));
-}
-
-
-/* Same as the sysymd builtin from m4.c module, but expand to the
- output of SHELL-COMMAND. */
-
-/**
- * esyscmd(SHELL-COMMAND)
- **/
-
-M4BUILTIN_HANDLER (esyscmd)
-{
- const m4_call_info *me = m4_arg_info (argv);
- const char *cmd = M4ARG (1);
- size_t len = M4ARGLEN (1);
- M4_MODULE_IMPORT (m4, m4_set_sysval);
- M4_MODULE_IMPORT (m4, m4_sysval_flush);
-
- if (m4_set_sysval && m4_sysval_flush)
- {
- pid_t child;
- int fd;
- FILE *pin;
- int status;
- int sig_status;
- const char *prog_args[4] = { "sh", "-c" };
- const char *caller;
-
- if (m4_get_safer_opt (context))
- {
- m4_error (context, 0, 0, me, _("disabled by --safer"));
- return;
- }
- if (strlen (cmd) != len)
- m4_warn (context, 0, me, _("argument %s truncated"),
- quotearg_style_mem (locale_quoting_style, cmd, len));
-
- /* Optimize the empty command. */
- if (!*cmd)
- {
- m4_set_sysval (0);
- return;
- }
-
- m4_sysval_flush (context, false);
-#if W32_NATIVE
- if (strstr (M4_SYSCMD_SHELL, "cmd"))
- {
- prog_args[0] = "cmd";
- prog_args[1] = "/c";
- }
-#endif
- prog_args[2] = cmd;
- caller = m4_info_name (me);
- errno = 0;
- child = create_pipe_in (caller, M4_SYSCMD_SHELL, (char **) prog_args,
- NULL, false, true, false, &fd);
- if (child == -1)
- {
- m4_error (context, 0, errno, me, _("cannot run command %s"),
- quotearg_style (locale_quoting_style, cmd));
- m4_set_sysval (127);
- return;
- }
-#if OS2
- /* On OS/2 kLIBC, fdopen() creates a stream in a mode of a file
- descriptor. So incldue "t" to open stream in a text mode explicitly. */
- pin = fdopen (fd, "rt");
-#else
- pin = fdopen (fd, "r");
-#endif
- if (!pin)
- {
- m4_error (context, 0, errno, me, _("cannot run command %s"),
- quotearg_style (locale_quoting_style, cmd));
- m4_set_sysval (127);
- close (fd);
- return;
- }
- while (1)
- {
- size_t avail = obstack_room (obs);
- if (!avail)
- {
- int ch = getc (pin);
- if (ch == EOF)
- break;
- obstack_1grow (obs, ch);
- }
- else
- {
- size_t len = fread (obstack_next_free (obs), 1, avail, pin);
- if (len <= 0)
- break;
- obstack_blank_fast (obs, len);
- }
- }
- if (ferror (pin) || fclose (pin))
- m4_error (context, EXIT_FAILURE, errno, me,
- _("cannot read pipe to command %s"),
- quotearg_style (locale_quoting_style, cmd));
- errno = 0;
- status = wait_subprocess (child, caller, false, true, true, false,
- &sig_status);
- if (sig_status)
- {
- assert (status == 127);
- m4_set_sysval (sig_status << 8);
- }
- else
- {
- if (status == 127 && errno)
- m4_error (context, 0, errno, me, _("cannot run command %s"),
- quotearg_style (locale_quoting_style, cmd));
- m4_set_sysval (status);
- }
- }
- else
- assert (!"Unable to import from m4 module");
-}
-
-
-/* Frontend for printf like formatting. The function format () lives in
- the file format.c. */
-
-#include "format.c"
-
-/**
- * format(FORMAT-STRING, [...])
- **/
-M4BUILTIN_HANDLER (format)
-{
- format (context, obs, argc, argv);
-}
-
-
-/* The builtin "indir" allows indirect calls to macros, even if their name
- is not a proper macro name. It is thus possible to define macros with
- ill-formed names for internal use in larger macro packages. */
-
-/**
- * indir(MACRO, [...])
- **/
-M4BUILTIN_HANDLER (indir)
-{
- const m4_call_info *me = m4_arg_info (argv);
- if (!m4_is_arg_text (argv, 1))
- m4_warn (context, 0, me, _("invalid macro name ignored"));
- else
- {
- const char *name = M4ARG (1);
- size_t len = M4ARGLEN (1);
- m4_symbol *symbol = m4_symbol_lookup (M4SYMTAB, name, len);
-
- if (symbol == NULL)
- {
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_DEREF))
- m4_warn (context, 0, me, _("undefined macro %s"),
- quotearg_style_mem (locale_quoting_style, name, len));
- }
- else
- {
- m4_macro_args *new_argv;
- m4_symbol_value *value = m4_get_symbol_value (symbol);
- new_argv = m4_make_argv_ref (context, argv, name, len,
- m4_symbol_flatten_args (symbol),
- m4_get_symbol_traced (symbol));
- m4_trace_prepare (context, m4_arg_info (new_argv), value);
- m4_macro_call (context, value, obs, new_argv);
- }
- }
-}
-
-
-/* The builtin "mkdtemp" allows creation of temporary directories. */
-
-/**
- * mkdtemp(TEMPLATE)
- **/
-M4BUILTIN_HANDLER (mkdtemp)
-{
- M4_MODULE_IMPORT (m4, m4_make_temp);
-
- if (m4_make_temp)
- m4_make_temp (context, obs, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1),
- true);
- else
- assert (!"Unable to import from m4 module");
-}
-
-
-/* Substitute all matches of a regexp occurring in a string. Each
- match of the second argument (a regexp) in the first argument is
- changed to the optional third argument, with \& substituted by the
- matched text, and \N substituted by the text matched by the Nth
- parenthesized sub-expression. The optional fourth argument changes
- the regex flavor. */
-
-/**
- * patsubst(VICTIM, REGEXP, [REPLACEMENT], [RESYNTAX])
- **/
-M4BUILTIN_HANDLER (patsubst)
-{
- const m4_call_info *me = m4_arg_info (argv);
- const char *pattern; /* regular expression */
- const char *replace; /* replacement */
- m4_pattern_buffer *buf; /* compiled regular expression */
- int resyntax;
-
- resyntax = m4_get_regexp_syntax_opt (context);
- if (argc >= 5) /* additional args ignored */
- {
- resyntax = m4_resyntax_encode_safe (context, me, M4ARG (4),
- M4ARGLEN (4));
- if (resyntax < 0)
- return;
- }
-
- /* The empty regex matches everywhere, but if there is no
- replacement, we need not waste time with it. */
- if (m4_arg_empty (argv, 2) && m4_arg_empty (argv, 3))
- {
- m4_push_arg (context, obs, argv, 1);
- return;
- }
-
- pattern = M4ARG (2);
- replace = M4ARG (3);
-
- buf = regexp_compile (context, me, pattern, M4ARGLEN (2), resyntax);
- if (!buf)
- return;
-
- regexp_substitute (context, obs, me, M4ARG (1), M4ARGLEN (1), pattern,
- M4ARGLEN (2), buf, replace, M4ARGLEN (3), false);
-}
-
-
-/* Regular expression version of index. Given two arguments, expand
- to the index of the first match of the second argument (a regexp)
- in the first. Expand to -1 if there is no match. Given a third
- argument, a match is substituted according to this argument. The
- optional fourth argument changes the regex flavor. */
-
-/**
- * regexp(VICTIM, REGEXP, RESYNTAX)
- * regexp(VICTIM, REGEXP, [REPLACEMENT], [RESYNTAX])
- **/
-M4BUILTIN_HANDLER (regexp)
-{
- const m4_call_info *me = m4_arg_info (argv);
- const char *victim; /* string to search */
- const char *pattern; /* regular expression */
- const char *replace; /* optional replacement string */
- m4_pattern_buffer *buf; /* compiled regular expression */
- regoff_t startpos; /* start position of match */
- size_t len; /* length of first argument */
- int resyntax;
-
- pattern = M4ARG (2);
- replace = M4ARG (3);
- resyntax = m4_get_regexp_syntax_opt (context);
-
- if (argc == 4)
- {
- resyntax = m4_regexp_syntax_encode (replace);
-
- /* The first case is the most difficult, because the empty string
- is a valid RESYNTAX, yet we want `regexp(aab, a*, )' to return
- an empty string as per M4 1.4.x. */
-
- if (m4_arg_empty (argv, 3) || (resyntax < 0))
- /* regexp(VICTIM, REGEXP, REPLACEMENT) */
- resyntax = m4_get_regexp_syntax_opt (context);
- else
- /* regexp(VICTIM, REGEXP, RESYNTAX) */
- replace = NULL;
- }
- else if (argc >= 5)
- {
- /* regexp(VICTIM, REGEXP, REPLACEMENT, RESYNTAX) */
- resyntax = m4_resyntax_encode_safe (context, me, M4ARG (4),
- M4ARGLEN (4));
- if (resyntax < 0)
- return;
- }
- else
- /* regexp(VICTIM, REGEXP) */
- replace = NULL;
-
- if (m4_arg_empty (argv, 2))
- {
- /* The empty regex matches everything. */
- if (replace)
- substitute (context, obs, me, M4ARG (1), replace, M4ARGLEN (3), NULL);
- else
- m4_shipout_int (obs, 0);
- return;
- }
-
- buf = regexp_compile (context, me, pattern, M4ARGLEN (2), resyntax);
- if (!buf)
- return;
-
- victim = M4ARG (1);
- len = M4ARGLEN (1);
- startpos = regexp_search (buf, victim, len, 0, len, replace == NULL);
-
- if (startpos == -2)
- {
- m4_error (context, 0, 0, me, _("problem matching regular expression %s"),
- quotearg_style_mem (locale_quoting_style, pattern,
- M4ARGLEN (2)));
- return;
- }
-
- if (replace == NULL)
- m4_shipout_int (obs, startpos);
- else if (startpos >= 0)
- substitute (context, obs, me, victim, replace, M4ARGLEN (3), buf);
-}
-
-
-/* Rename all current symbols that match REGEXP according to the
- REPLACEMENT specification. */
-
-/**
- * renamesyms(REGEXP, REPLACEMENT, [RESYNTAX])
- **/
-M4BUILTIN_HANDLER (renamesyms)
-{
- M4_MODULE_IMPORT (m4, m4_dump_symbols);
-
- if (m4_dump_symbols)
- {
- const m4_call_info *me = m4_arg_info (argv);
- const char *regexp; /* regular expression string */
- size_t regexp_len;
- const char *replace; /* replacement expression string */
- size_t replace_len;
-
- m4_pattern_buffer *buf; /* compiled regular expression */
-
- m4_dump_symbol_data data;
-
- int resyntax;
-
- regexp = M4ARG (1);
- regexp_len = M4ARGLEN (1);
- replace = M4ARG (2);
- replace_len = M4ARGLEN (2);
-
- resyntax = m4_get_regexp_syntax_opt (context);
- if (argc >= 4)
- {
- resyntax = m4_resyntax_encode_safe (context, me, M4ARG (3),
- M4ARGLEN (3));
- if (resyntax < 0)
- return;
- }
-
- buf = regexp_compile (context, me, regexp, regexp_len, resyntax);
- if (!buf)
- return;
-
- data.obs = m4_arg_scratch (context);
- m4_dump_symbols (context, &data, 1, argv, false);
-
- for (; data.size > 0; --data.size, data.base++)
- {
- const m4_string *key = &data.base[0];
-
- if (regexp_substitute (context, data.obs, me, key->str, key->len,
- regexp, regexp_len, buf, replace, replace_len,
- true))
- {
- size_t newlen = obstack_object_size (data.obs);
- m4_symbol_rename (M4SYMTAB, key->str, key->len,
- (char *) obstack_finish (data.obs), newlen);
- }
- }
- }
- else
- assert (!"Unable to import from m4 module");
-}
-
-
-/**
- * m4modules()
- **/
-M4BUILTIN_HANDLER (m4modules)
-{
- /* The expansion of this builtin is a comma separated list of
- loaded modules. */
- m4_module *module = m4_module_next (context, NULL);
-
- if (module)
- do
- {
- m4_shipout_string (context, obs, m4_get_module_name (module), SIZE_MAX,
- true);
-
- if ((module = m4_module_next (context, module)))
- obstack_1grow (obs, ',');
- }
- while (module);
-}
-
-
-/* Implementation of "m4symbols". It builds up a table of pointers to
- symbols, sorts it and ships out the symbol names. */
-
-/**
- * m4symbols([...])
- **/
-M4BUILTIN_HANDLER (m4symbols)
-{
- M4_MODULE_IMPORT (m4, m4_dump_symbols);
-
- if (m4_dump_symbols)
- {
- m4_dump_symbol_data data;
-
- data.obs = m4_arg_scratch (context);
- m4_dump_symbols (context, &data, argc, argv, false);
-
- for (; data.size > 0; --data.size, data.base++)
- {
- m4_shipout_string (context, obs, data.base->str, data.base->len,
- true);
- if (data.size > 1)
- obstack_1grow (obs, ',');
- }
- }
- else
- assert (!"Unable to import from m4 module");
-}
-
-
-/* This contains macro which implements syncoutput() which takes one arg
- 1, on, yes - turn on sync lines
- 0, off, no, blank - turn off sync lines
- everything else is silently ignored */
-
-/**
- * syncoutput(TRUTH)
- **/
-M4BUILTIN_HANDLER (syncoutput)
-{
- bool value = m4_get_syncoutput_opt (context);
- value = m4_parse_truth_arg (context, m4_arg_info (argv), M4ARG (1),
- M4ARGLEN (1), value);
- m4_set_syncoutput_opt (context, value);
-}
diff --git a/modules/m4.c b/modules/m4.c
deleted file mode 100644
index ed06942b..00000000
--- a/modules/m4.c
+++ /dev/null
@@ -1,1324 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2000, 2002-2004, 2006-2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-/* Build using only the exported interfaces, unless NDEBUG is set, in
- which case use private symbols to speed things up as much as possible. */
-#ifndef NDEBUG
-# include <m4/m4module.h>
-#else
-# include "m4private.h"
-#endif
-
-#include "execute.h"
-#include "memchr2.h"
-#include "memcmp2.h"
-#include "quotearg.h"
-#include "stdlib--.h"
-#include "tempname.h"
-#include "unistd--.h"
-
-#include <modules/m4.h>
-
-extern void m4_set_sysval (int);
-extern void m4_sysval_flush (m4 *, bool);
-extern void m4_dump_symbols (m4 *, m4_dump_symbol_data *, size_t,
- m4_macro_args *, bool);
-extern const char *m4_expand_ranges (const char *, size_t *, m4_obstack *);
-extern void m4_make_temp (m4 *, m4_obstack *, const m4_call_info *,
- const char *, size_t, bool);
-
-/* Maintain each of the builtins implemented in this modules along
- with their details in a single table for easy maintenance.
-
- function macros blind side minargs maxargs */
-#define builtin_functions \
- BUILTIN (changecom, false, false, false, 0, 2 ) \
- BUILTIN (changequote, false, false, false, 0, 2 ) \
- BUILTIN (decr, false, true, true, 1, 1 ) \
- BUILTIN (define, true, true, false, 1, 2 ) \
- BUILTIN (defn, true, true, false, 1, -1 ) \
- BUILTIN (divert, false, false, false, 0, 2 ) \
- BUILTIN (divnum, false, false, false, 0, 0 ) \
- BUILTIN (dnl, false, false, false, 0, 0 ) \
- BUILTIN (dumpdef, true, false, false, 0, -1 ) \
- BUILTIN (errprint, false, true, false, 1, -1 ) \
- BUILTIN (eval, false, true, true, 1, 3 ) \
- BUILTIN (ifdef, true, true, false, 2, 3 ) \
- BUILTIN (ifelse, true, true, false, 1, -1 ) \
- BUILTIN (include, false, true, false, 1, 1 ) \
- BUILTIN (incr, false, true, true, 1, 1 ) \
- BUILTIN (index, false, true, true, 2, 3 ) \
- BUILTIN (len, false, true, true, 1, 1 ) \
- BUILTIN (m4exit, false, false, false, 0, 1 ) \
- BUILTIN (m4wrap, true, true, false, 1, -1 ) \
- BUILTIN (maketemp, false, true, false, 1, 1 ) \
- BUILTIN (mkstemp, false, true, false, 1, 1 ) \
- BUILTIN (popdef, true, true, false, 1, -1 ) \
- BUILTIN (pushdef, true, true, false, 1, 2 ) \
- BUILTIN (shift, true, true, false, 1, -1 ) \
- BUILTIN (sinclude, false, true, false, 1, 1 ) \
- BUILTIN (substr, false, true, true, 2, 4 ) \
- BUILTIN (syscmd, false, true, true, 1, 1 ) \
- BUILTIN (sysval, false, false, false, 0, 0 ) \
- BUILTIN (traceoff, true, false, false, 0, -1 ) \
- BUILTIN (traceon, true, false, false, 0, -1 ) \
- BUILTIN (translit, false, true, true, 2, 3 ) \
- BUILTIN (undefine, true, true, false, 1, -1 ) \
- BUILTIN (undivert, false, false, false, 0, -1 ) \
-
-
-typedef intmax_t number;
-typedef uintmax_t unumber;
-
-static void include (m4 *context, m4_obstack *obs, size_t argc,
- m4_macro_args *argv, bool silent);
-static int dumpdef_cmp_CB (const void *s1, const void *s2);
-static void * dump_symbol_CB (m4_symbol_table *, const char *, size_t,
- m4_symbol *symbol, void *userdata);
-static const char *ntoa (number value, int radix);
-static void numb_obstack (m4_obstack *obs, number value,
- int radix, int min);
-
-
-/* Generate prototypes for each builtin handler function. */
-#define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler)
- builtin_functions
-#undef BUILTIN
-
-
-/* Generate a table for mapping m4 symbol names to handler functions. */
-static const m4_builtin m4_builtin_table[] =
-{
-#define BUILTIN(handler, macros, blind, side, min, max) \
- M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
-
- builtin_functions
-#undef BUILTIN
-
- { NULL, NULL, 0, 0, 0 },
-};
-
-
-void
-include_m4 (m4 *context, m4_module *module, m4_obstack *obs)
-{
- m4_install_builtins (context, module, m4_builtin_table);
-}
-
-
-
-/* The rest of this file is code for builtins and expansion of user
- defined macros. All the functions for builtins have a prototype as:
-
- void builtin_MACRONAME (m4_obstack *obs, int argc, char *argv[]);
-
- The function are expected to leave their expansion on the obstack OBS,
- as an unfinished object. ARGV is a table of ARGC pointers to the
- individual arguments to the macro. Please note that in general
- argv[argc] != NULL. */
-
-M4BUILTIN_HANDLER (define)
-{
- const m4_call_info *me = m4_arg_info (argv);
-
- if (m4_is_arg_text (argv, 1))
- {
- m4_symbol_value *value = m4_symbol_value_create ();
-
- if (m4_symbol_value_copy (context, value, m4_arg_symbol (argv, 2)))
- m4_warn (context, 0, me, _("cannot concatenate builtins"));
- m4_symbol_define (M4SYMTAB, M4ARG (1), M4ARGLEN (1), value);
- }
- else
- m4_warn (context, 0, me, _("invalid macro name ignored"));
-}
-
-M4BUILTIN_HANDLER (undefine)
-{
- size_t i;
- for (i = 1; i < argc; i++)
- if (m4_symbol_value_lookup (context, argv, i, true))
- m4_symbol_delete (M4SYMTAB, M4ARG (i), M4ARGLEN (i));
-}
-
-M4BUILTIN_HANDLER (pushdef)
-{
- const m4_call_info *me = m4_arg_info (argv);
-
- if (m4_is_arg_text (argv, 1))
- {
- m4_symbol_value *value = m4_symbol_value_create ();
-
- if (m4_symbol_value_copy (context, value, m4_arg_symbol (argv, 2)))
- m4_warn (context, 0, me, _("cannot concatenate builtins"));
- m4_symbol_pushdef (M4SYMTAB, M4ARG (1), M4ARGLEN (1), value);
- }
- else
- m4_warn (context, 0, me, _("invalid macro name ignored"));
-}
-
-M4BUILTIN_HANDLER (popdef)
-{
- size_t i;
- for (i = 1; i < argc; i++)
- if (m4_symbol_value_lookup (context, argv, i, true))
- m4_symbol_popdef (M4SYMTAB, M4ARG (i), M4ARGLEN (i));
-}
-
-
-
-/* --- CONDITIONALS OF M4 --- */
-
-
-M4BUILTIN_HANDLER (ifdef)
-{
- m4_push_arg (context, obs, argv,
- m4_symbol_value_lookup (context, argv, 1, false) ? 2 : 3);
-}
-
-M4BUILTIN_HANDLER (ifelse)
-{
- const m4_call_info *me = m4_arg_info (argv);
- size_t i;
-
- /* The valid ranges of argc for ifelse is discontinuous, we cannot
- rely on the regular mechanisms. */
- if (argc == 2 || m4_bad_argc (context, argc, me, 3, -1, false))
- return;
- else if (argc % 3 == 0)
- /* Diagnose excess arguments if 5, 8, 11, etc., actual arguments. */
- m4_bad_argc (context, argc, me, 0, argc - 2, false);
-
- i = 1;
- argc--;
-
- while (true)
- {
- if (m4_arg_equal (context, argv, i, i + 1))
- {
- m4_push_arg (context, obs, argv, i + 2);
- return;
- }
- switch (argc)
- {
- case 3:
- return;
-
- case 4:
- case 5:
- m4_push_arg (context, obs, argv, i + 3);
- return;
-
- default:
- argc -= 3;
- i += 3;
- }
- }
-}
-
-
-/* qsort comparison routine, for sorting the table made in m4_dumpdef (). */
-static int
-dumpdef_cmp_CB (const void *s1, const void *s2)
-{
- const m4_string *a = (const m4_string *) s1;
- const m4_string *b = (const m4_string *) s2;
- return memcmp2 (a->str, a->len, b->str, b->len);
-}
-
-/* The function m4_dump_symbols () is for use by "dumpdef". It builds up a
- table of all defined symbol names. */
-static void *
-dump_symbol_CB (m4_symbol_table *ignored M4_GNUC_UNUSED, const char *name,
- size_t len, m4_symbol *symbol, void *userdata)
-{
- m4_dump_symbol_data *symbol_data = (m4_dump_symbol_data *) userdata;
- m4_string *key;
-
- assert (name);
- assert (symbol);
- assert (!m4_is_symbol_value_void (m4_get_symbol_value (symbol)));
-
- if (symbol_data->size == 0)
- {
- char *base;
- size_t offset = obstack_object_size (symbol_data->obs);
- obstack_blank (symbol_data->obs, sizeof *symbol_data->base);
- symbol_data->size = (obstack_room (symbol_data->obs)
- / sizeof *symbol_data->base);
- base = (char *) obstack_base (symbol_data->obs) + offset;
- symbol_data->base = (m4_string *) base;
- }
- else
- {
- obstack_blank_fast (symbol_data->obs, sizeof *symbol_data->base);
- symbol_data->size--;
- }
-
- /* Safe to cast away const, since m4_dump_symbols adds it back. */
- key = (m4_string *) symbol_data->base++;
- key->str = (char *) name;
- key->len = len;
- return NULL;
-}
-
-/* If there are no arguments, build a sorted list of all defined
- symbols, otherwise, only the specified symbols. */
-void
-m4_dump_symbols (m4 *context, m4_dump_symbol_data *data, size_t argc,
- m4_macro_args *argv, bool complain)
-{
- assert (obstack_object_size (data->obs) == 0);
- data->size = obstack_room (data->obs) / sizeof *data->base;
- data->base = (m4_string *) obstack_base (data->obs);
-
- if (argc == 1)
- m4_symtab_apply (M4SYMTAB, false, dump_symbol_CB, data);
- else
- {
- size_t i;
- m4_symbol *symbol;
-
- for (i = 1; i < argc; i++)
- {
- symbol = m4_symbol_value_lookup (context, argv, i, complain);
- if (symbol)
- dump_symbol_CB (NULL, M4ARG (i), M4ARGLEN (i), symbol, data);
- }
- }
-
- data->size = obstack_object_size (data->obs) / sizeof *data->base;
- data->base = (m4_string *) obstack_finish (data->obs);
- /* Safe to cast away const, since we don't modify entries. */
- qsort ((m4_string *) data->base, data->size, sizeof *data->base,
- dumpdef_cmp_CB);
-}
-
-
-/* Implementation of "dumpdef" itself. It builds up a table of pointers to
- symbols, sorts it and prints the sorted table. */
-M4BUILTIN_HANDLER (dumpdef)
-{
- m4_dump_symbol_data data;
- const m4_string_pair *quotes = NULL;
- bool stack = m4_is_debug_bit (context, M4_DEBUG_TRACE_STACK);
- size_t arg_length = m4_get_max_debug_arg_length_opt (context);
- bool module = m4_is_debug_bit (context, M4_DEBUG_TRACE_MODULE);
- FILE *output = (m4_is_debug_bit (context, M4_DEBUG_TRACE_OUTPUT_DUMPDEF)
- ? stderr : m4_get_debug_file (context));
-
- if (!output)
- return;
- if (m4_is_debug_bit (context, M4_DEBUG_TRACE_QUOTE))
- quotes = m4_get_syntax_quotes (M4SYNTAX);
- data.obs = m4_arg_scratch (context);
- m4_dump_symbols (context, &data, argc, argv, true);
- m4_sysval_flush (context, false);
-
- for (; data.size > 0; --data.size, data.base++)
- {
- m4_symbol *symbol = m4_symbol_lookup (M4SYMTAB, data.base->str,
- data.base->len);
- char *value;
- size_t len;
- assert (symbol);
-
- /* TODO - add debugmode(b) option to control quoting style. */
- obstack_grow (obs, data.base->str, data.base->len);
- obstack_1grow (obs, ':');
- obstack_1grow (obs, '\t');
- m4_symbol_print (context, symbol, obs, quotes, stack, arg_length,
- module);
- obstack_1grow (obs, '\n');
- len = obstack_object_size (obs);
- value = (char *) obstack_finish (obs);
- fwrite (value, 1, len, output);
- obstack_free (obs, value);
- }
-}
-
-/* The macro "defn" returns the quoted definition of the macro named by
- the first argument. If the macro is builtin, it will push a special
- macro-definition token on the input stack. */
-M4BUILTIN_HANDLER (defn)
-{
- const m4_call_info *me = m4_arg_info (argv);
- size_t i;
-
- for (i = 1; i < argc; i++)
- {
- m4_symbol *symbol = m4_symbol_value_lookup (context, argv, i, true);
-
- if (!symbol)
- ;
- else if (m4_is_symbol_text (symbol))
- m4_shipout_string (context, obs, m4_get_symbol_text (symbol),
- m4_get_symbol_len (symbol), true);
- else if (m4_is_symbol_func (symbol))
- m4_push_builtin (context, obs, m4_get_symbol_value (symbol));
- else if (m4_is_symbol_placeholder (symbol))
- m4_warn (context, 0, me,
- _("%s: builtin %s requested by frozen file not found"),
- quotearg_n_mem (2, M4ARG (i), M4ARGLEN (i)),
- quotearg_style (locale_quoting_style,
- m4_get_symbol_placeholder (symbol)));
- else
- {
- assert (!"Bad token data type in m4_defn");
- abort ();
- }
- }
-}
-
-
-/* This section contains macros to handle the builtins "syscmd"
- and "sysval". */
-
-/* Exit code from last "syscmd" command. */
-/* FIXME - we should preserve this value across freezing. See
- http://lists.gnu.org/archive/html/bug-m4/2006-06/msg00059.html
- for ideas on how do to that. */
-static int m4_sysval = 0;
-
-void
-m4_set_sysval (int value)
-{
- m4_sysval = value;
-}
-
-/* Flush a given output STREAM. If REPORT, also print an error
- message and clear the stream error bit. */
-static void
-sysval_flush_helper (m4 *context, FILE *stream, bool report)
-{
- if (fflush (stream) == EOF && report)
- {
- m4_error (context, 0, errno, NULL, _("write error"));
- clearerr (stream);
- }
-}
-
-/* Flush all user output streams, prior to doing something that can
- could lose unflushed data or interleave debug and normal output
- incorrectly. If REPORT, then print an error message on failure and
- clear the stream error bit; otherwise a subsequent ferror can track
- that an error occurred. */
-void
-m4_sysval_flush (m4 *context, bool report)
-{
- FILE *debug_file = m4_get_debug_file (context);
-
- if (debug_file != stdout)
- sysval_flush_helper (context, stdout, report);
- if (debug_file != stderr)
- /* If we have problems with stderr, we can't really report that
- problem to stderr. The closeout module will ensure the exit
- status reflects the problem, though. */
- fflush (stderr);
- if (debug_file != NULL)
- sysval_flush_helper (context, debug_file, report);
- /* POSIX requires that if m4 doesn't consume all input, but stdin is
- opened on a seekable file, that the file pointer be left at the
- next character on exit (but places no restrictions on the file
- pointer location on a non-seekable file). It also requires that
- fflush() followed by fseeko() on an input file set the underlying
- file pointer, and gnulib guarantees these semantics. However,
- fflush() on a non-seekable file can lose buffered data, which we
- might otherwise want to process after syscmd. Hence, we must
- check whether stdin is seekable. We must also be tolerant of
- operating with stdin closed, so we don't report any failures in
- this attempt. The stdio-safer module and friends are essential,
- so that if stdin was closed, this lseek is not on some other file
- that we have since opened. */
- if (lseek (STDIN_FILENO, 0, SEEK_CUR) >= 0
- && fflush (stdin) == 0)
- {
- fseeko (stdin, 0, SEEK_CUR);
- }
-}
-
-M4BUILTIN_HANDLER (syscmd)
-{
- const m4_call_info *me = m4_arg_info (argv);
- const char *cmd = M4ARG (1);
- size_t len = M4ARGLEN (1);
- int status;
- int sig_status;
- const char *prog_args[4] = { "sh", "-c" };
-
- if (m4_get_safer_opt (context))
- {
- m4_error (context, 0, 0, m4_arg_info (argv), _("disabled by --safer"));
- return;
- }
- if (strlen (cmd) != len)
- m4_warn (context, 0, me, _("argument %s truncated"),
- quotearg_style_mem (locale_quoting_style, cmd, len));
-
- /* Optimize the empty command. */
- if (!*cmd)
- {
- m4_set_sysval (0);
- return;
- }
- m4_sysval_flush (context, false);
-#if W32_NATIVE
- if (strstr (M4_SYSCMD_SHELL, "cmd"))
- {
- prog_args[0] = "cmd";
- prog_args[1] = "/c";
- }
-#endif
- prog_args[2] = cmd;
- errno = 0;
- status = execute (m4_info_name (me), M4_SYSCMD_SHELL, (char **) prog_args,
- false, false, false, false, true, false, &sig_status);
- if (sig_status)
- {
- assert (status == 127);
- m4_sysval = sig_status << 8;
- }
- else
- {
- if (status == 127 && errno)
- m4_warn (context, errno, me, _("cannot run command %s"),
- quotearg_style (locale_quoting_style, cmd));
- m4_sysval = status;
- }
-}
-
-
-M4BUILTIN_HANDLER (sysval)
-{
- m4_shipout_int (obs, m4_sysval);
-}
-
-
-M4BUILTIN_HANDLER (incr)
-{
- int value;
-
- if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1),
- &value))
- return;
-
- m4_shipout_int (obs, value + 1);
-}
-
-M4BUILTIN_HANDLER (decr)
-{
- int value;
-
- if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1),
- &value))
- return;
-
- m4_shipout_int (obs, value - 1);
-}
-
-
-/* This section contains the macros "divert", "undivert" and "divnum" for
- handling diversion. The utility functions used lives in output.c. */
-
-/* Divert further output to the diversion given by ARGV[1]. Out of range
- means discard further output. */
-M4BUILTIN_HANDLER (divert)
-{
- int i = 0;
-
- if (argc >= 2 && !m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1),
- M4ARGLEN (1), &i))
- return;
- m4_make_diversion (context, i);
- m4_divert_text (context, NULL, M4ARG (2), M4ARGLEN (2),
- m4_get_current_line (context));
-}
-
-/* Expand to the current diversion number. */
-M4BUILTIN_HANDLER (divnum)
-{
- m4_shipout_int (obs, m4_get_current_diversion (context));
-}
-
-/* Bring back the diversion given by the argument list. If none is
- specified, bring back all diversions. GNU specific is the option
- of undiverting the named file, by passing a non-numeric argument to
- undivert (). */
-
-M4BUILTIN_HANDLER (undivert)
-{
- size_t i = 0;
- const m4_call_info *me = m4_arg_info (argv);
-
- if (argc == 1)
- m4_undivert_all (context);
- else
- for (i = 1; i < argc; i++)
- {
- const char *str = M4ARG (i);
- size_t len = M4ARGLEN (i);
- char *endp;
- int diversion = strtol (str, &endp, 10);
- if (endp - str == len && !isspace ((unsigned char) *str))
- m4_insert_diversion (context, diversion);
- else if (m4_get_posixly_correct_opt (context))
- m4_warn (context, 0, me, _("non-numeric argument %s"),
- quotearg_style_mem (locale_quoting_style, str, len));
- else if (strlen (str) != len)
- m4_warn (context, 0, me, _("invalid file name %s"),
- quotearg_style_mem (locale_quoting_style, str, len));
- else
- {
- char *filepath = m4_path_search (context, str, NULL);
- FILE *fp = m4_fopen (context, filepath, "r");
-
- free (filepath);
- if (fp != NULL)
- {
- m4_insert_file (context, fp);
- if (fclose (fp) == EOF)
- m4_error (context, 0, errno, me, _("error undiverting %s"),
- quotearg_style (locale_quoting_style, str));
- }
- else
- m4_error (context, 0, errno, me, _("cannot undivert %s"),
- quotearg_style (locale_quoting_style, str));
- }
- }
-}
-
-
-/* This section contains various macros, which does not fall into
- any specific group. These are "dnl", "shift", "changequote",
- "changecom" and "changesyntax" */
-
-/* Delete all subsequent whitespace from input. The function skip_line ()
- lives in input.c. */
-M4BUILTIN_HANDLER (dnl)
-{
- m4_skip_line (context, m4_arg_info (argv));
-}
-
-/* Shift all arguments one to the left, discarding the first argument.
- Each output argument is quoted with the current quotes. */
-M4BUILTIN_HANDLER (shift)
-{
- m4_push_args (context, obs, argv, true, true);
-}
-
-/* Change the current quotes. The function set_quotes () lives in
- syntax.c. */
-M4BUILTIN_HANDLER (changequote)
-{
- m4_set_quotes (M4SYNTAX,
- (argc >= 2) ? M4ARG (1) : NULL, M4ARGLEN (1),
- (argc >= 3) ? M4ARG (2) : NULL, M4ARGLEN (2));
-}
-
-/* Change the current comment delimiters. The function set_comment ()
- lives in syntax.c. */
-M4BUILTIN_HANDLER (changecom)
-{
- m4_set_comment (M4SYNTAX,
- (argc >= 2) ? M4ARG (1) : NULL, M4ARGLEN (1),
- (argc >= 3) ? M4ARG (2) : NULL, M4ARGLEN (2));
-}
-
-
-/* This section contains macros for inclusion of other files -- "include"
- and "sinclude". This differs from bringing back diversions, in that
- the input is scanned before being copied to the output. */
-
-static void
-include (m4 *context, m4_obstack *obs, size_t argc, m4_macro_args *argv, bool silent)
-{
- const m4_call_info *me = m4_arg_info (argv);
- const char *arg = M4ARG (1);
- size_t len = M4ARGLEN (1);
-
- if (strlen (arg) != len)
- m4_warn (context, 0, me, _("argument %s truncated"),
- quotearg_style_mem (locale_quoting_style, arg, len));
- m4_load_filename (context, me, arg, obs, silent);
-}
-
-/* Include a file, complaining in case of errors. */
-M4BUILTIN_HANDLER (include)
-{
- include (context, obs, argc, argv, false);
-}
-
-/* Include a file, ignoring errors. */
-M4BUILTIN_HANDLER (sinclude)
-{
- include (context, obs, argc, argv, true);
-}
-
-
-/* More miscellaneous builtins -- "maketemp", "errprint". */
-
-/* Add trailing `X' to PATTERN of length LEN as necessary, then
- securely create the temporary file system object. If DIR, create a
- directory instead of a file. Report errors on behalf of CALLER. If
- successful, output the quoted resulting name on OBS. */
-void
-m4_make_temp (m4 *context, m4_obstack *obs, const m4_call_info *caller,
- const char *pattern, size_t len, bool dir)
-{
- int fd;
- int i;
- char *name;
- const m4_string_pair *quotes = m4_get_syntax_quotes (M4SYNTAX);
-
- if (m4_get_safer_opt (context))
- {
- m4_error (context, 0, 0, caller, _("disabled by --safer"));
- return;
- }
-
- /* Guarantee that there are six trailing 'X' characters, even if the
- user forgot to supply them. Output must be quoted if
- successful. */
- assert (obstack_object_size (obs) == 0);
- obstack_grow (obs, quotes->str1, quotes->len1);
- if (strlen (pattern) < len)
- {
- m4_warn (context, 0, caller, _("argument %s truncated"),
- quotearg_style_mem (locale_quoting_style, pattern, len));
- len = strlen (pattern);
- }
- obstack_grow (obs, pattern, len);
- for (i = 0; len > 0 && i < 6; i++)
- if (pattern[--len] != 'X')
- break;
- obstack_grow0 (obs, "XXXXXX", 6 - i);
- name = (char *) obstack_base (obs) + quotes->len1;
-
- /* Make the temporary object. */
- errno = 0;
- fd = gen_tempname (name, 0, 0, dir ? GT_DIR : GT_FILE);
- if (fd < 0)
- {
- /* This use of _() will need to change if xgettext ever changes
- its undocumented behavior of parsing both string options. */
-
- m4_warn (context, errno, caller,
- _(dir ? "cannot create directory from template %s"
- : "cannot create file from template %s"),
- quotearg_style (locale_quoting_style, pattern));
- obstack_free (obs, obstack_finish (obs));
- }
- else
- {
- if (!dir)
- close (fd);
- /* Remove NUL, then finish quote. */
- obstack_blank_fast (obs, -1);
- obstack_grow (obs, quotes->str2, quotes->len2);
- }
-}
-
-/* Use the first argument as at template for a temporary file name. */
-M4BUILTIN_HANDLER (maketemp)
-{
- const m4_call_info *me = m4_arg_info (argv);
- m4_warn (context, 0, me, _("recommend using mkstemp instead"));
- if (m4_get_posixly_correct_opt (context))
- {
- /* POSIX states "any trailing 'X' characters [are] replaced with
- the current process ID as a string", without referencing the
- file system. Horribly insecure, but we have to do it.
-
- For reference, Solaris m4 does:
- maketemp() -> `'
- maketemp(X) -> `X'
- maketemp(XX) -> `Xn', where n is last digit of pid
- maketemp(XXXXXXXX) -> `X00nnnnn', where nnnnn is 16-bit pid
- */
- const char *str = M4ARG (1);
- size_t len = M4ARGLEN (1);
- size_t i;
- m4_obstack *scratch = m4_arg_scratch (context);
- size_t pid_len = obstack_printf (scratch, "%lu",
- (unsigned long) getpid ());
- char *pid = (char *) obstack_copy0 (scratch, "", 0);
-
- for (i = len; i > 1; i--)
- if (str[i - 1] != 'X')
- break;
- obstack_grow (obs, str, i);
- if (len - i < pid_len)
- obstack_grow (obs, pid + pid_len - (len - i), len - i);
- else
- obstack_printf (obs, "%.*d%s", (int) (len - i - pid_len), 0, pid);
- }
- else
- m4_make_temp (context, obs, me, M4ARG (1), M4ARGLEN (1), false);
-}
-
-/* Use the first argument as a template for a temporary file name. */
-M4BUILTIN_HANDLER (mkstemp)
-{
- m4_make_temp (context, obs, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1),
- false);
-}
-
-/* Print all arguments on standard error. */
-M4BUILTIN_HANDLER (errprint)
-{
- size_t i;
-
- m4_sysval_flush (context, false);
- /* The close_stdin module makes it safe to skip checking the return
- values here. */
- fwrite (M4ARG (1), 1, M4ARGLEN (1), stderr);
- for (i = 2; i < m4_arg_argc (argv); i++)
- {
- fputc (' ', stderr);
- fwrite (M4ARG (i), 1, M4ARGLEN (i), stderr);
- }
- fflush (stderr);
-}
-
-
-/* This section contains various macros for exiting, saving input until
- EOF is seen, and tracing macro calls. That is: "m4exit", "m4wrap",
- "traceon" and "traceoff". */
-
-/* Exit immediately, with exitcode specified by the first argument, 0 if no
- arguments are present. */
-M4BUILTIN_HANDLER (m4exit)
-{
- const m4_call_info *me = m4_arg_info (argv);
- int exit_code = EXIT_SUCCESS;
-
- /* Warn on bad arguments, but still exit. */
- if (argc >= 2 && !m4_numeric_arg (context, me, M4ARG (1), M4ARGLEN (1),
- &exit_code))
- exit_code = EXIT_FAILURE;
- if (exit_code < 0 || exit_code > 255)
- {
- m4_warn (context, 0, me, _("exit status out of range: `%d'"), exit_code);
- exit_code = EXIT_FAILURE;
- }
-
- /* Ensure that atexit handlers see correct nonzero status. */
- if (exit_code != EXIT_SUCCESS)
- m4_set_exit_failure (exit_code);
-
- /* Change debug stream back to stderr, to force flushing debug
- stream and detect any errors. */
- m4_debug_set_output (context, me, NULL);
- m4_sysval_flush (context, true);
-
- /* Check for saved error. */
- if (exit_code == 0 && m4_get_exit_status (context) != 0)
- exit_code = m4_get_exit_status (context);
- exit (exit_code);
-}
-
-/* Save the argument text until EOF has been seen, allowing for user
- specified cleanup action. GNU version saves all arguments, the standard
- version only the first. */
-M4BUILTIN_HANDLER (m4wrap)
-{
- m4_wrap_args (context, argv);
-}
-
-/* Enable tracing of all specified macros, or all, if none is specified.
- Tracing is disabled by default, when a macro is defined. This can be
- overridden by the "t" debug flag. */
-
-M4BUILTIN_HANDLER (traceon)
-{
- const m4_call_info *me = m4_arg_info (argv);
- size_t i;
-
- if (argc == 1)
- m4_set_debug_level_opt (context, (m4_get_debug_level_opt (context)
- | M4_DEBUG_TRACE_ALL));
- else
- for (i = 1; i < argc; i++)
- if (m4_is_arg_text (argv, i))
- m4_set_symbol_name_traced (M4SYMTAB, M4ARG (i), M4ARGLEN (i), true);
- else
- m4_warn (context, 0, me, _("invalid macro name ignored"));
-}
-
-/* Disable tracing of all specified macros, or all, if none is specified. */
-M4BUILTIN_HANDLER (traceoff)
-{
- const m4_call_info *me = m4_arg_info (argv);
- size_t i;
-
- if (argc == 1)
- m4_set_debug_level_opt (context, (m4_get_debug_level_opt (context)
- & ~M4_DEBUG_TRACE_ALL));
- else
- for (i = 1; i < argc; i++)
- if (m4_is_arg_text (argv, i))
- m4_set_symbol_name_traced (M4SYMTAB, M4ARG (i), M4ARGLEN (i), false);
- else
- m4_warn (context, 0, me, _("invalid macro name ignored"));
-}
-
-
-/* This section contains text processing macros: "len", "index",
- "substr", "translit", "format", "regexp" and "patsubst". The last
- three are GNU specific. */
-
-/* Expand to the length of the first argument. */
-M4BUILTIN_HANDLER (len)
-{
- m4_shipout_int (obs, M4ARGLEN (1));
-}
-
-/* The macro expands to the first index of the second argument in the
- first argument. As an extension, start the search at the index
- indicated by the third argument. */
-M4BUILTIN_HANDLER (index)
-{
- const char *haystack = M4ARG (1);
- size_t haystack_len = M4ARGLEN (1);
- const char *needle = M4ARG (2);
- const char *result = NULL;
- int offset = 0;
- int retval = -1;
-
- if (!m4_arg_empty (argv, 3) && !m4_numeric_arg (context, m4_arg_info (argv),
- M4ARG (3), M4ARGLEN (3),
- &offset))
- return;
- if (offset < 0)
- {
- offset += haystack_len;
- if (offset < 0)
- offset = 0;
- }
- else if (haystack_len < offset)
- {
- m4_shipout_int (obs, -1);
- return;
- }
-
- /* Rely on the optimizations guaranteed by gnulib's memmem
- module. */
- result = (char *) memmem (haystack + offset, haystack_len - offset, needle,
- M4ARGLEN (2));
- if (result)
- retval = result - haystack;
-
- m4_shipout_int (obs, retval);
-}
-
-/* The macro "substr" extracts substrings from the first argument,
- starting from the index given by the second argument, extending for
- a length given by the third argument. If the third argument is
- missing or empty, the substring extends to the end of the first
- argument. As an extension, negative arguments are treated as
- indices relative to the string length. Also, if a fourth argument
- is supplied, the original string is output with the selected
- substring replaced by the argument. */
-M4BUILTIN_HANDLER (substr)
-{
- const m4_call_info *me = m4_arg_info (argv);
- const char *str = M4ARG (1);
- int start = 0;
- int end;
- int length;
-
- if (argc <= 2)
- {
- m4_push_arg (context, obs, argv, 1);
- return;
- }
-
- length = M4ARGLEN (1);
- if (!m4_arg_empty (argv, 2)
- && !m4_numeric_arg (context, me, M4ARG (2), M4ARGLEN (2), &start))
- return;
- if (start < 0)
- start += length;
-
- if (m4_arg_empty (argv, 3))
- end = length;
- else
- {
- if (!m4_numeric_arg (context, me, M4ARG (3), M4ARGLEN (3), &end))
- return;
- if (end < 0)
- end += length;
- else
- end += start;
- }
-
- if (5 <= argc)
- {
- /* Replacement text provided. */
- if (end < start)
- end = start;
- if (end < 0 || length < start)
- {
- m4_warn (context, 0, me, _("substring out of range"));
- return;
- }
- if (start < 0)
- start = 0;
- if (length < end)
- end = length;
- obstack_grow (obs, str, start);
- m4_push_arg (context, obs, argv, 4);
- obstack_grow (obs, str + end, length - end);
- return;
- }
-
- if (start < 0)
- start = 0;
- if (length < end)
- end = length;
- if (end <= start)
- return;
-
- obstack_grow (obs, str + start, end - start);
-}
-
-
-/* Any ranges in string S of length *LEN are expanded, using OBS for
- scratch space, and the expansion returned. *LEN is set to the
- expanded length. A single - (dash) can be included in the strings
- by being the first or the last character in the string. If the
- first character in a range is after the first in the character set,
- the range is made backwards, thus 9-0 is the string 9876543210. */
-const char *
-m4_expand_ranges (const char *s, size_t *len, m4_obstack *obs)
-{
- unsigned char from;
- unsigned char to;
- const char *end = s + *len;
-
- assert (obstack_object_size (obs) == 0);
- assert (s != end);
- from = *s++;
- obstack_1grow (obs, from);
-
- for ( ; s != end; from = *s++)
- {
- if (*s == '-')
- {
- if (++s == end)
- {
- /* trailing dash */
- obstack_1grow (obs, '-');
- break;
- }
- to = *s;
- if (from <= to)
- {
- while (from++ < to)
- obstack_1grow (obs, from);
- }
- else
- {
- while (--from >= to)
- obstack_1grow (obs, from);
- }
- }
- else
- obstack_1grow (obs, *s);
- }
- *len = obstack_object_size (obs);
- return (char *) obstack_finish (obs);
-}
-
-/* The macro "translit" translates all characters in the first
- argument, which are present in the second argument, into the
- corresponding character from the third argument. If the third
- argument is shorter than the second, the extra characters in the
- second argument are deleted from the first. */
-M4BUILTIN_HANDLER (translit)
-{
- const char *data;
- const char *from;
- const char *to;
- size_t from_len;
- size_t to_len;
- char map[UCHAR_MAX + 1];
- char found[UCHAR_MAX + 1];
- unsigned char ch;
-
- enum { ASIS, REPLACE, DELETE };
-
- if (m4_arg_empty (argv, 1) || m4_arg_empty (argv, 2))
- {
- m4_push_arg (context, obs, argv, 1);
- return;
- }
-
- from = M4ARG (2);
- from_len = M4ARGLEN (2);
-
- to = M4ARG (3);
- to_len = M4ARGLEN (3);
- if (memchr (to, '-', to_len) != NULL)
- to = m4_expand_ranges (to, &to_len, m4_arg_scratch (context));
-
- /* If there are only one or two bytes to replace, it is faster to
- use memchr2. Using expand_ranges does nothing unless there are
- at least three bytes. */
- if (from_len <= 2)
- {
- const char *p;
- size_t len = M4ARGLEN (1);
- int second = from[from_len / 2];
- data = M4ARG (1);
- while ((p = (char *) memchr2 (data, from[0], second, len)))
- {
- obstack_grow (obs, data, p - data);
- len -= p - data + 1;
- data = p + 1;
- if (*p == from[0] && to_len)
- obstack_1grow (obs, to[0]);
- else if (*p == second && 1 < to_len)
- obstack_1grow (obs, to[1]);
- }
- obstack_grow (obs, data, len);
- return;
- }
-
- if (memchr (from, '-', from_len) != NULL)
- from = m4_expand_ranges (from, &from_len, m4_arg_scratch (context));
-
- /* Calling memchr(from) for each character in data is quadratic,
- since both strings can be arbitrarily long. Instead, create a
- from-to mapping in one pass of from, then use that map in one
- pass of data, for linear behavior. Traditional behavior is that
- only the first instance of a character in from is consulted,
- hence the found map. */
- memset (map, 0, sizeof map);
- memset (found, 0, sizeof found);
- while (from_len--)
- {
- ch = *from++;
- if (found[ch] == ASIS)
- {
- if (to_len)
- {
- found[ch] = REPLACE;
- map[ch] = *to;
- }
- else
- found[ch] = DELETE;
- }
- if (to_len)
- {
- to++;
- to_len--;
- }
- }
-
- data = M4ARG (1);
- from_len = M4ARGLEN (1);
- while (from_len--)
- {
- ch = *data++;
- switch (found[ch])
- {
- case ASIS:
- obstack_1grow (obs, ch);
- break;
- case REPLACE:
- obstack_1grow (obs, map[ch]);
- break;
- case DELETE:
- break;
- default:
- assert (!"translit");
- abort ();
- }
- }
-}
-
-
-
-/* The rest of this file contains the functions to evaluate integer
- * expressions for the "eval" macro. `number' should be at least 32 bits.
- */
-#define numb_set(ans, x) ((ans) = (x))
-#define numb_set_si(ans, si) (*(ans) = (number) (si))
-
-#define numb_ZERO ((number) 0)
-#define numb_ONE ((number) 1)
-
-#define numb_init(x) ((x) = numb_ZERO)
-#define numb_fini(x)
-
-#define numb_incr(n) ((n) += numb_ONE)
-#define numb_decr(n) ((n) -= numb_ONE)
-
-#define numb_zerop(x) ((x) == numb_ZERO)
-#define numb_positivep(x) ((x) > numb_ZERO)
-#define numb_negativep(x) ((x) < numb_ZERO)
-
-#define numb_eq(x, y) ((x) = ((x) == (y)))
-#define numb_ne(x, y) ((x) = ((x) != (y)))
-#define numb_lt(x, y) ((x) = ((x) < (y)))
-#define numb_le(x, y) ((x) = ((x) <= (y)))
-#define numb_gt(x, y) ((x) = ((x) > (y)))
-#define numb_ge(x, y) ((x) = ((x) >= (y)))
-
-#define numb_lnot(x) ((x) = (!(x)))
-#define numb_lior(x, y) ((x) = ((x) || (y)))
-#define numb_land(x, y) ((x) = ((x) && (y)))
-
-#define numb_not(c, x) (*(x) = ~ *(x))
-#define numb_eor(c, x, y) (*(x) = *(x) ^ *(y))
-#define numb_ior(c, x, y) (*(x) = *(x) | *(y))
-#define numb_and(c, x, y) (*(x) = *(x) & *(y))
-
-#define numb_plus(x, y) ((x) = ((x) + (y)))
-#define numb_minus(x, y) ((x) = ((x) - (y)))
-#define numb_negate(x) ((x) = (- (x)))
-
-#define numb_times(x, y) ((x) = ((x) * (y)))
-/* Be careful of x86 SIGFPE. */
-#define numb_ratio(x, y) \
- (((y) == -1) ? (numb_negate (x)) : ((x) /= (y)))
-#define numb_divide(x, y) \
- ((*(y) == -1) ? (numb_negate (*(y))) : (*(x) /= *(y)))
-#define numb_modulo(c, x, y) \
- ((*(y) == -1) ? (*(x) = numb_ZERO) : (*(x) %= *(y)))
-/* numb_invert is only used in the context of x**-y, which integral math
- does not support. */
-#define numb_invert(x) return NEGATIVE_EXPONENT
-
-/* Minimize undefined C behavior (shifting by a negative number,
- shifting by the width or greater, left shift overflow, or right
- shift of a negative number). Implement Java wrap-around semantics,
- with implicit masking of shift amount. This code assumes that the
- implementation-defined overflow when casting unsigned to signed is
- a silent twos-complement wrap-around. */
-#define shift_mask (sizeof (number) * CHAR_BIT - 1)
-#define numb_lshift(c, x, y) \
- (*(x) = (number) ((unumber) *(x) << (*(y) & shift_mask)))
-#define numb_rshift(c, x, y) \
- (*(x) = (number) (*(x) < 0 \
- ? ~(~(unumber) *(x) >> (*(y) & shift_mask)) \
- : (unumber) *(x) >> (*(y) & shift_mask)))
-#define numb_urshift(c, x, y) \
- (*(x) = (number) ((unumber) *(x) >> (*(y) & shift_mask)))
-
-
-/* The function ntoa () converts VALUE to a signed ASCII representation in
- radix RADIX. Radix must be between 2 and 36, inclusive. */
-static const char *
-ntoa (number value, int radix)
-{
- /* Digits for number to ASCII conversions. */
- static char const ntoa_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-
- bool negative;
- unumber uvalue;
- /* Sized for radix 2, plus sign and trailing NUL. */
- static char str[sizeof value * CHAR_BIT + 2];
- char *s = &str[sizeof str];
-
- *--s = '\0';
-
- if (value < 0)
- {
- negative = true;
- uvalue = (unumber) -value;
- }
- else
- {
- negative = false;
- uvalue = (unumber) value;
- }
-
- do
- {
- *--s = ntoa_digits[uvalue % radix];
- uvalue /= radix;
- }
- while (uvalue > 0);
-
- if (negative)
- *--s = '-';
- return s;
-}
-
-static void
-numb_obstack (m4_obstack *obs, number value, int radix, int min)
-{
- const char *s;
- size_t len;
- unumber uvalue;
-
- if (radix == 1)
- {
- if (value < 0)
- {
- obstack_1grow (obs, '-');
- uvalue = -value;
- }
- else
- uvalue = value;
- if (uvalue < min)
- {
- obstack_blank (obs, min - uvalue);
- memset ((char *) obstack_next_free (obs) - (min - uvalue), '0',
- min - uvalue);
- }
- obstack_blank (obs, uvalue);
- memset ((char *) obstack_next_free (obs) - uvalue, '1', uvalue);
- return;
- }
-
- s = ntoa (value, radix);
-
- if (*s == '-')
- {
- obstack_1grow (obs, '-');
- s++;
- }
- len = strlen (s);
- if (len < min)
- {
- min -= len;
- obstack_blank (obs, min);
- memset ((char *) obstack_next_free (obs) - min, '0', min);
- }
- obstack_grow (obs, s, len);
-}
-
-
-static void
-numb_initialise (void)
-{
- ;
-}
-
-/* This macro defines the top level code for the "eval" builtin. The
- actual work is done in the function m4_evaluate (), which lives in
- evalparse.c. */
-#define m4_evaluate builtin_eval
-#include "evalparse.c"
diff --git a/modules/m4.h b/modules/m4.h
deleted file mode 100644
index 769665e5..00000000
--- a/modules/m4.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2003, 2006-2008, 2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef MODULES_M4_H
-#define MODULES_M4_H 1
-
-#include <m4/m4module.h>
-
-BEGIN_C_DECLS
-
-/* This structure is used to pass the information needed
- from call to call in m4_dump_symbols. */
-typedef struct
-{
- m4_obstack *obs; /* obstack for table */
- const m4_string *base; /* base of table */
- int size; /* size of table */
-} m4_dump_symbol_data;
-
-
-/* Types used to cast imported symbols to, so we get type checking
- across the interface boundary. */
-typedef void m4_sysval_flush_func (m4 *context, bool report);
-typedef void m4_set_sysval_func (int value);
-typedef void m4_dump_symbols_func (m4 *context, m4_dump_symbol_data *data,
- size_t argc, m4_macro_args *argv,
- bool complain);
-typedef const char *m4_expand_ranges_func (const char *s, size_t *len,
- m4_obstack *obs);
-typedef void m4_make_temp_func (m4 *context, m4_obstack *obs,
- const m4_call_info *macro, const char *name,
- size_t len, bool dir);
-
-END_C_DECLS
-
-#endif /* !MODULES_M4_H */
diff --git a/modules/mpeval.c b/modules/mpeval.c
deleted file mode 100644
index 1c998b6a..00000000
--- a/modules/mpeval.c
+++ /dev/null
@@ -1,453 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2000-2001, 2006-2008, 2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-/* Build using only the exported interfaces, unless NDEBUG is set, in
- which case use private symbols to speed things up as much as possible. */
-#ifndef NDEBUG
-# include <m4/m4module.h>
-#else
-# include "m4private.h"
-#endif
-
-#if HAVE_GMP_H
-# include <gmp.h>
-#endif
-
-/* Maintain each of the builtins implemented in this modules along
- with their details in a single table for easy maintenance.
-
- function macros blind side minargs maxargs */
-#define builtin_functions \
- BUILTIN (mpeval, false, true, true, 1, 3 ) \
-
-
-
-#define numb_set(ans, i) mpq_set (ans, i)
-#define numb_set_si(ans, i) mpq_set_si (*(ans), (long) i, (unsigned long) 1)
-
-#define numb_init(x) mpq_init (x)
-#define numb_fini(x) mpq_clear (x)
-
-#define numb_zerop(x) (mpq_cmp (x, numb_ZERO) == 0)
-#define numb_positivep(x) (mpq_cmp (x, numb_ZERO) > 0)
-#define numb_negativep(x) (mpq_cmp (x, numb_ZERO) < 0)
-
-#define numb_eq(x, y) numb_set (x, mpq_cmp (x, y) == 0 ? numb_ONE : numb_ZERO)
-#define numb_ne(x, y) numb_set (x, mpq_cmp (x, y) != 0 ? numb_ONE : numb_ZERO)
-#define numb_lt(x, y) numb_set (x, mpq_cmp (x, y) < 0 ? numb_ONE : numb_ZERO)
-#define numb_le(x, y) numb_set (x, mpq_cmp (x, y) <= 0 ? numb_ONE : numb_ZERO)
-#define numb_gt(x, y) numb_set (x, mpq_cmp (x, y) > 0 ? numb_ONE : numb_ZERO)
-#define numb_ge(x, y) numb_set (x, mpq_cmp (x, y) >= 0 ? numb_ONE : numb_ZERO)
-
-#define numb_lnot(x) numb_set (x, numb_zerop (x) ? numb_ONE : numb_ZERO)
-#define numb_lior(x, y) numb_set (x, numb_zerop (x) ? y : x)
-#define numb_land(x, y) numb_set (x, numb_zerop (x) ? numb_ZERO : y)
-
-#define reduce1(f1, x) \
- do \
- { \
- number T; \
- mpq_init (T); \
- f1 (T, x); \
- mpq_set (x, T); \
- mpq_clear (T); \
- } \
- while (0)
-#define reduce2(f2,x,y) \
- do \
- { \
- number T; \
- mpq_init (T); \
- f2 (T, (x), (y)); \
- mpq_set ((x), T); \
- mpq_clear (T); \
- } \
- while (0)
-
-#define numb_plus(x, y) reduce2 (mpq_add, x, y)
-#define numb_minus(x, y) reduce2 (mpq_sub, x, y)
-#define numb_negate(x) reduce1 (mpq_neg, x)
-
-#define numb_times(x, y) reduce2 (mpq_mul, x, y)
-#define numb_ratio(x, y) reduce2 (mpq_div, x, y)
-#define numb_invert(x) reduce1 (mpq_inv, x)
-
-#define numb_incr(n) numb_plus (n, numb_ONE)
-#define numb_decr(n) numb_minus (n, numb_ONE)
-
-/* Generate prototypes for each builtin handler function. */
-#define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler)
- builtin_functions
-#undef BUILTIN
-
-
-/* Generate a table for mapping m4 symbol names to handler functions. */
-static const m4_builtin m4_builtin_table[] =
-{
-#define BUILTIN(handler, macros, blind, side, min, max) \
- M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
-
- builtin_functions
-#undef BUILTIN
-
- { NULL, NULL, 0, 0, 0 },
-};
-
-
-/* A table for mapping m4 symbol names to simple expansion text. */
-static const m4_macro m4_macro_table[] =
-{
- /* name text min max */
- { "__mpeval__", "", 0, 0 },
- { NULL, NULL, 0, 0 },
-};
-
-
-void
-include_mpeval (m4 *context, m4_module *module, m4_obstack *obs)
-{
- m4_install_builtins (context, module, m4_builtin_table);
- m4_install_macros (context, module, m4_macro_table);
-}
-
-
-/* GMP defines mpq_t as a 1-element array of struct. Therefore, `mpq_t'
- is not compatible with `const mpq_t'. */
-typedef mpq_t number;
-
-static void numb_initialise (void);
-static void numb_obstack (m4_obstack *obs, const number value,
- const int radix, int min);
-static void mpq2mpz (m4 *context, mpz_t z, const number q, const char *noisily);
-static void mpz2mpq (number q, const mpz_t z);
-static void numb_divide (number *x, number *y);
-static void numb_modulo (m4 *context, number *x, number *y);
-static void numb_and (m4 *context, number *x, number *y);
-static void numb_ior (m4 *context, number *x, number *y);
-static void numb_eor (m4 *context, number *x, number *y);
-static void numb_not (m4 *context, number *x);
-static void numb_lshift (m4 *context, number *x, number *y);
-static void numb_rshift (m4 *context, number *x, number *y);
-#define numb_urshift(c, x, y) numb_rshift (c, x, y)
-
-
-static number numb_ZERO;
-static number numb_ONE;
-
-static int numb_initialised = 0;
-
-static void
-numb_initialise (void)
-{
- if (numb_initialised)
- return;
-
- numb_init (numb_ZERO);
- numb_set_si (&numb_ZERO, 0);
-
- numb_init (numb_ONE);
- numb_set_si (&numb_ONE, 1);
-
- numb_initialised = 1;
-}
-
-static void
-numb_obstack (m4_obstack *obs, const number value, const int radix,
- int min)
-{
- const char *s;
- size_t len;
-
- mpz_t i;
- mpz_init (i);
-
- mpq_get_num (i, value);
- s = mpz_get_str (NULL, radix, i);
-
- if (*s == '-')
- {
- obstack_1grow (obs, '-');
- s++;
- }
- len = strlen (s);
- for (min -= len; --min >= 0;)
- obstack_1grow (obs, '0');
-
- obstack_grow (obs, s, len);
-
- mpq_get_den (i, value);
- if (mpz_cmp_si (i, (long) 1) != 0)
- {
- obstack_1grow (obs, '\\');
- s = mpz_get_str ((char *) 0, radix, i);
- obstack_grow (obs, s, strlen (s));
- }
-
- mpz_clear (i);
-}
-
-#define NOISY ""
-#define QUIET (char *)0
-
-static void
-mpq2mpz (m4 *context, mpz_t z, const number q, const char *noisily)
-{
- if (noisily && mpz_cmp_si (mpq_denref (q), (long) 1) != 0)
- m4_warn (context, 0, NULL, _("loss of precision in eval: %s"), noisily);
-
- mpz_div (z, mpq_numref (q), mpq_denref (q));
-}
-
-static void
-mpz2mpq (number q, const mpz_t z)
-{
- mpq_set_si (q, (long) 0, (unsigned long) 1);
- mpq_set_num (q, z);
-}
-
-static void
-numb_divide (number * x, number * y)
-{
- mpq_t qres;
- mpz_t zres;
-
- mpq_init (qres);
- mpq_div (qres, *x, *y);
-
- mpz_init (zres);
- mpz_div (zres, mpq_numref (qres), mpq_denref (qres));
- mpq_clear (qres);
-
- mpz2mpq (*x, zres);
- mpz_clear (zres);
-}
-
-static void
-numb_modulo (m4 *context, number * x, number * y)
-{
- mpz_t xx, yy, res;
-
- /* x should be integral */
- /* y should be integral */
-
- mpz_init (xx);
- mpq2mpz (context, xx, *x, NOISY);
-
- mpz_init (yy);
- mpq2mpz (context, yy, *y, NOISY);
-
- mpz_init (res);
- mpz_mod (res, xx, yy);
-
- mpz_clear (xx);
- mpz_clear (yy);
-
- mpz2mpq (*x, res);
- mpz_clear (res);
-}
-
-static void
-numb_and (m4 *context, number * x, number * y)
-{
- mpz_t xx, yy, res;
-
- /* x should be integral */
- /* y should be integral */
-
- mpz_init (xx);
- mpq2mpz (context, xx, *x, NOISY);
-
- mpz_init (yy);
- mpq2mpz (context, yy, *y, NOISY);
-
- mpz_init (res);
- mpz_and (res, xx, yy);
-
- mpz_clear (xx);
- mpz_clear (yy);
-
- mpz2mpq (*x, res);
- mpz_clear (res);
-}
-
-static void
-numb_ior (m4 *context, number * x, number * y)
-{
- mpz_t xx, yy, res;
-
- /* x should be integral */
- /* y should be integral */
-
- mpz_init (xx);
- mpq2mpz (context, xx, *x, NOISY);
-
- mpz_init (yy);
- mpq2mpz (context, yy, *y, NOISY);
-
- mpz_init (res);
- mpz_ior (res, xx, yy);
-
- mpz_clear (xx);
- mpz_clear (yy);
-
- mpz2mpq (*x, res);
- mpz_clear (res);
-}
-
-static void
-numb_eor (m4 *context, number * x, number * y)
-{
- mpz_t xx, yy, res;
-
- /* x should be integral */
- /* y should be integral */
-
- mpz_init (xx);
- mpq2mpz (context, xx, *x, NOISY);
-
- mpz_init (yy);
- mpq2mpz (context, yy, *y, NOISY);
-
- mpz_init (res);
-
-#if 0
- mpz_xor (res, xx, yy);
-#else /* 0 */
- /* a^b = (a|b) & !(a&b) */
- {
- mpz_t and_ab, ior_ab, nand_ab;
-
- mpz_init (ior_ab);
- mpz_ior (ior_ab, xx, yy);
-
- mpz_init (and_ab);
- mpz_and (and_ab, xx, yy);
-
- mpz_init (nand_ab);
- mpz_com (nand_ab, and_ab);
-
- mpz_and (res, ior_ab, nand_ab);
-
- mpz_clear (and_ab);
- mpz_clear (ior_ab);
- mpz_clear (nand_ab);
- }
-#endif /* 0 */
-
- mpz_clear (xx);
- mpz_clear (yy);
-
- mpz2mpq (*x, res);
- mpz_clear (res);
-}
-
-static void
-numb_not (m4 *context, number * x)
-{
- mpz_t xx, res;
-
- /* x should be integral */
-
- mpz_init (xx);
- mpq2mpz (context, xx, *x, NOISY);
-
- mpz_init (res);
- mpz_com (res, xx);
-
- mpz_clear (xx);
-
- mpz2mpq (*x, res);
- mpz_clear (res);
-}
-
-static void
-numb_lshift (m4 *context, number * x, number * y)
-{
- mpz_t xx, yy, res;
-
- /* x should be integral */
- /* y should be integral */
-
- mpz_init (xx);
- mpq2mpz (context, xx, *x, NOISY);
-
- mpz_init (yy);
- mpq2mpz (context, yy, *y, NOISY);
-
- mpz_init (res);
- {
- /* bug: need to determine if y is too big or negative. */
- long int exp = mpz_get_si (yy);
- if (exp >= 0)
- {
- mpz_mul_2exp (res, xx, (unsigned) exp);
- }
- else
- {
- mpz_div_2exp (res, xx, (unsigned) -exp);
- }
- }
-
- mpz_clear (xx);
- mpz_clear (yy);
-
- mpz2mpq (*x, res);
- mpz_clear (res);
-}
-
-static void
-numb_rshift (m4 *context, number * x, number * y)
-{
- mpz_t xx, yy, res;
-
- /* x should be integral */
- /* y should be integral */
-
- mpz_init (xx);
- mpq2mpz (context, xx, *x, NOISY);
-
- mpz_init (yy);
- mpq2mpz (context, yy, *y, NOISY);
-
- mpz_init (res);
- {
- /* FIXME: bug - need to determine if y is too big or negative */
- long int exp = mpz_get_si (yy);
- if (exp >= 0)
- {
- mpz_div_2exp (res, xx, (unsigned) exp);
- }
- else
- {
- mpz_mul_2exp (res, xx, (unsigned) -exp);
- }
- }
-
- mpz_clear (xx);
- mpz_clear (yy);
-
- mpz2mpq (*x, res);
- mpz_clear (res);
-}
-
-#define m4_evaluate builtin_mpeval
-#include "evalparse.c"
diff --git a/modules/stdlib.c b/modules/stdlib.c
deleted file mode 100644
index 708f8c61..00000000
--- a/modules/stdlib.c
+++ /dev/null
@@ -1,288 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1999-2001, 2006-2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include <pwd.h>
-#if TM_IN_SYS_TIME
-# include <sys/time.h>
-#else
-# include <time.h>
-#endif
-#include <sys/utsname.h>
-
-/* Build using only the exported interfaces, unless NDEBUG is set, in
- which case use private symbols to speed things up as much as possible. */
-#ifndef NDEBUG
-# include <m4/m4module.h>
-#else
-# include "m4private.h"
-#endif
-
-/* function macros blind side minargs maxargs */
-#define builtin_functions \
- BUILTIN (getcwd, false, false, false, 0, 0 ) \
- BUILTIN (getenv, false, true, false, 1, 1 ) \
- BUILTIN (getlogin, false, false, false, 0, 0 ) \
- BUILTIN (getpid, false, false, false, 0, 0 ) \
- BUILTIN (getppid, false, false, false, 0, 0 ) \
- BUILTIN (getuid, false, false, false, 0, 0 ) \
- BUILTIN (getpwnam, false, true, false, 1, 1 ) \
- BUILTIN (getpwuid, false, true, false, 1, 1 ) \
- BUILTIN (hostname, false, false, false, 0, 0 ) \
- BUILTIN (rand, false, false, false, 0, 0 ) \
- BUILTIN (srand, false, false, false, 0, 1 ) \
- BUILTIN (setenv, false, true, false, 2, 3 ) \
- BUILTIN (unsetenv, false, true, false, 1, 1 ) \
- BUILTIN (uname, false, false, false, 0, 0 ) \
-
-
-#define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler);
- builtin_functions
-#undef BUILTIN
-
-static const m4_builtin m4_builtin_table[] =
-{
-#define BUILTIN(handler, macros, blind, side, min, max) \
- M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
-
- builtin_functions
-#undef BUILTIN
-
- { NULL, NULL, 0, 0, 0 },
-};
-
-
-void
-include_stdlib (m4 *context, m4_module *module, m4_obstack *obs)
-{
- m4_install_builtins (context, module, m4_builtin_table);
-}
-
-
-/**
- * getcwd()
- **/
-M4BUILTIN_HANDLER (getcwd)
-{
- /* FIXME - Use gnulib module for arbitrary-length cwd. */
- char buf[1024];
- char *bp;
-
- bp = getcwd (buf, sizeof buf);
-
- if (bp != NULL) /* in case of error return null string */
- m4_shipout_string (context, obs, buf, SIZE_MAX, false);
-}
-
-/**
- * getenv(NAME)
- **/
-M4BUILTIN_HANDLER (getenv)
-{
- char *env;
-
- env = getenv (M4ARG (1));
-
- if (env != NULL)
- m4_shipout_string (context, obs, env, SIZE_MAX, false);
-}
-
-/**
- * setenv(NAME, VALUE, [OVERWRITE])
- **/
-M4BUILTIN_HANDLER (setenv)
-{
- int overwrite = 1;
-
- if (argc >= 4)
- if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (3), M4ARGLEN (3),
- &overwrite))
- return;
-
- /* TODO - error checking. */
- setenv (M4ARG (1), M4ARG (2), overwrite);
-}
-
-/**
- * unsetenv(NAME)
- **/
-M4BUILTIN_HANDLER (unsetenv)
-{
- /* TODO - error checking. */
- unsetenv (M4ARG (1));
-}
-
-/**
- * getlogin()
- **/
-M4BUILTIN_HANDLER (getlogin)
-{
- char *login;
-
- login = getlogin ();
-
- if (login != NULL)
- m4_shipout_string (context, obs, login, SIZE_MAX, false);
-}
-
-/**
- * getpid()
- **/
-M4BUILTIN_HANDLER (getpid)
-{
- m4_shipout_int (obs, getpid ());
-}
-
-/**
- * getppid()
- **/
-M4BUILTIN_HANDLER (getppid)
-{
- m4_shipout_int (obs, getppid ());
-}
-
-/**
- * getpwnam(NAME)
- **/
-M4BUILTIN_HANDLER (getpwnam)
-{
- struct passwd *pw;
-
- pw = getpwnam (M4ARG (1));
-
- if (pw != NULL)
- {
- m4_shipout_string (context, obs, pw->pw_name, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, pw->pw_passwd, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_int (obs, pw->pw_uid);
- obstack_1grow (obs, ',');
- m4_shipout_int (obs, pw->pw_gid);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, pw->pw_gecos, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, pw->pw_dir, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, pw->pw_shell, SIZE_MAX, true);
- }
-}
-
-/**
- * getpwuid(UID)
- **/
-M4BUILTIN_HANDLER (getpwuid)
-{
- struct passwd *pw;
- int uid;
-
- if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1),
- &uid))
- return;
-
- pw = getpwuid (uid);
-
- if (pw != NULL)
- {
- m4_shipout_string (context, obs, pw->pw_name, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, pw->pw_passwd, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_int (obs, pw->pw_uid);
- obstack_1grow (obs, ',');
- m4_shipout_int (obs, pw->pw_gid);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, pw->pw_gecos, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, pw->pw_dir, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, pw->pw_shell, SIZE_MAX, true);
- }
-}
-
-/**
- * hostname()
- **/
-M4BUILTIN_HANDLER (hostname)
-{
- char buf[1024];
-
- if (gethostname (buf, sizeof buf) < 0)
- return;
-
- m4_shipout_string (context, obs, buf, SIZE_MAX, false);
-}
-
-/**
- * rand()
- **/
-M4BUILTIN_HANDLER (rand)
-{
- m4_shipout_int (obs, rand ());
-}
-
-/**
- * srand()
- **/
-M4BUILTIN_HANDLER (srand)
-{
- int seed;
-
- if (argc == 1)
- seed = time (0L) * getpid ();
- else
- {
- if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1),
- M4ARGLEN (1), &seed))
- return;
- }
-
- srand (seed);
-}
-
-/**
- * uname()
- **/
-M4BUILTIN_HANDLER (uname)
-{
- struct utsname ut;
-
- if (uname (&ut) == 0)
- {
- m4_shipout_string (context, obs, ut.sysname, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, ut.nodename, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, ut.release, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, ut.version, SIZE_MAX, true);
- obstack_1grow (obs, ',');
- m4_shipout_string (context, obs, ut.machine, SIZE_MAX, true);
- }
-}
-
-/**
- * getuid()
- **/
-M4BUILTIN_HANDLER (getuid)
-{
- m4_shipout_int (obs, getuid ());
-}
diff --git a/modules/time.c b/modules/time.c
deleted file mode 100644
index 7f64f922..00000000
--- a/modules/time.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1999-2001, 2006-2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#if TM_IN_SYS_TIME
-# include <sys/time.h>
-#else
-# include <time.h>
-#endif /* TM_IN_SYS_TIME */
-
-/* Build using only the exported interfaces, unless NDEBUG is set, in
- which case use private symbols to speed things up as much as possible. */
-#ifndef NDEBUG
-# include <m4/m4module.h>
-#else
-# include "m4private.h"
-#endif
-
-/* function macros blind side minargs maxargs */
-#define builtin_functions \
- BUILTIN (currenttime, false, false, false, 0, 0 ) \
- BUILTIN (ctime, false, false, false, 0, 1 ) \
- BUILTIN (gmtime, false, true, false, 1, 1 ) \
- BUILTIN (localtime, false, true, false, 1, 1 ) \
-
-#define mktime_functions \
- BUILTIN (mktime, false, true, false, 6, 7 ) \
-
-#define strftime_functions \
- BUILTIN (strftime, false, true, false, 2, 2 ) \
-
-
-#define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler)
- builtin_functions
-# if HAVE_MKTIME
- mktime_functions
-# endif
-# if HAVE_STRFTIME
- strftime_functions
-# endif
-#undef BUILTIN
-
-static const m4_builtin m4_builtin_table[] =
-{
-#define BUILTIN(handler, macros, blind, side, min, max) \
- M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
-
- builtin_functions
-# if HAVE_MKTIME
- mktime_functions
-# endif
-# if HAVE_STRFTIME
- strftime_functions
-# endif
-#undef BUILTIN
-
- { NULL, NULL, 0, 0, 0 },
-};
-
-
-void
-include_time (m4 *context, m4_module *module, m4_obstack *obs)
-{
- m4_install_builtins (context, module, m4_builtin_table);
-}
-
-
-
-/**
- * currenttime()
- **/
-M4BUILTIN_HANDLER (currenttime)
-{
- char buf[64];
- time_t now;
- int l;
-
- now = time (0L);
- l = sprintf (buf, "%ld", now);
-
- obstack_grow (obs, buf, l);
-}
-
-/**
- * ctime([SECONDS])
- **/
-M4BUILTIN_HANDLER (ctime)
-{
- time_t t;
- int i;
- const char *s;
-
- if (argc == 2)
- {
- m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1),
- &i);
- t = i;
- }
- else
- t = time (0L);
-
- s = ctime (&t);
- obstack_grow (obs, s, 24);
-}
-
-static void
-format_tm (m4_obstack *obs, struct tm *tm)
-{
- m4_shipout_int (obs, tm->tm_sec);
- obstack_1grow (obs, ',');
-
- m4_shipout_int (obs, tm->tm_min);
- obstack_1grow (obs, ',');
-
- m4_shipout_int (obs, tm->tm_hour);
- obstack_1grow (obs, ',');
-
- m4_shipout_int (obs, tm->tm_mday);
- obstack_1grow (obs, ',');
-
- m4_shipout_int (obs, tm->tm_mon);
- obstack_1grow (obs, ',');
-
- m4_shipout_int (obs, tm->tm_year);
- obstack_1grow (obs, ',');
-
- m4_shipout_int (obs, tm->tm_wday);
- obstack_1grow (obs, ',');
-
- m4_shipout_int (obs, tm->tm_yday);
- obstack_1grow (obs, ',');
-
- m4_shipout_int (obs, tm->tm_isdst);
-}
-
-/**
- * gmtime(SECONDS)
- **/
-M4BUILTIN_HANDLER (gmtime)
-{
- time_t t;
- int i;
-
- if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1),
- &i))
- return;
-
- t = i;
- format_tm (obs, gmtime (&t));
-}
-
-/**
- * localtime(SECONDS)
- **/
-M4BUILTIN_HANDLER (localtime)
-{
- time_t t;
- int i;
-
- if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (1), M4ARGLEN (1),
- &i))
- return;
-
- t = i;
- format_tm (obs, localtime (&t));
-}
-
-#if HAVE_MKTIME
-/**
- * mktime(SEC, MIN, HOUR, MDAY, MONTH, YEAR, [ISDST])
- **/
-M4BUILTIN_HANDLER (mktime)
-{
- const m4_call_info *me = m4_arg_info (argv);
- struct tm tm;
- time_t t;
-
- if (!m4_numeric_arg (context, me, M4ARG (1), M4ARGLEN (1), &tm.tm_sec))
- return;
- if (!m4_numeric_arg (context, me, M4ARG (2), M4ARGLEN (2), &tm.tm_min))
- return;
- if (!m4_numeric_arg (context, me, M4ARG (3), M4ARGLEN (3), &tm.tm_hour))
- return;
- if (!m4_numeric_arg (context, me, M4ARG (4), M4ARGLEN (4), &tm.tm_mday))
- return;
- if (!m4_numeric_arg (context, me, M4ARG (5), M4ARGLEN (5), &tm.tm_mon))
- return;
- if (!m4_numeric_arg (context, me, M4ARG (6), M4ARGLEN (6), &tm.tm_year))
- return;
- if (M4ARG (7) && !m4_numeric_arg (context, me, M4ARG (7), M4ARGLEN (7),
- &tm.tm_isdst))
- return;
-
- t = mktime (&tm);
-
- m4_shipout_int (obs, t);
-}
-#endif /* HAVE_MKTIME */
-
-#if HAVE_STRFTIME
-/**
- * strftime(FORMAT, SECONDS)
- **/
-M4BUILTIN_HANDLER (strftime)
-{
- struct tm *tm;
- time_t t;
- char *buf;
- int l;
-
- if (!m4_numeric_arg (context, m4_arg_info (argv), M4ARG (2), M4ARGLEN (2),
- &l))
- return;
-
- t = l;
- tm = localtime (&t);
-
- buf = (char *) obstack_alloc (obs, 1024);
- l = strftime (buf, 1024, M4ARG (1), tm);
- obstack_grow (obs, buf, l);
-}
-#endif /* HAVE_STRFTIME */
diff --git a/modules/traditional.c b/modules/traditional.c
deleted file mode 100644
index 648cef76..00000000
--- a/modules/traditional.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2000, 2006-2008, 2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-/* Build using only the exported interfaces, unless NDEBUG is set, in
- which case use private symbols to speed things up as much as possible. */
-#ifndef NDEBUG
-# include <m4/m4module.h>
-#else
-# include "m4private.h"
-#endif
-
-/* A table for mapping m4 symbol names to simple expansion text. */
-static const m4_macro m4_macro_table[] =
-{
- /* name text min max */
-#if UNIX
- { "unix", "", 0, 0 },
-#elif W32_NATIVE
- { "windows", "", 0, 0 },
-#elif OS2
- { "os2", "", 0, 0 },
-#else
-# warning Platform macro not provided
-#endif
- { "__traditional__", "", 0, 0 },
- { NULL, NULL, 0, 0 },
-};
-
-void
-include_traditional (m4 *context, m4_module *module, m4_obstack *obs)
-{
- m4_install_macros (context, module, m4_macro_table);
-}
diff --git a/po/Makevars b/po/Makevars
deleted file mode 100644
index f1bf1501..00000000
--- a/po/Makevars
+++ /dev/null
@@ -1,44 +0,0 @@
-# Makefile variables for PO directory in any package using GNU gettext.
-
-# Usually the message domain is the same as the package name.
-DOMAIN = $(PACKAGE)
-
-# These two variables depend on the location of this directory.
-subdir = po
-top_builddir = ..
-
-# These options get passed to xgettext.
-XGETTEXT_OPTIONS = --keyword=_ --keyword=N_ \
- --flag=_:1:pass-c-format \
- --flag=N_:1:pass-c-format \
- $${end_of_xgettext_options+}
-
-# This is the copyright holder that gets inserted into the header of the
-# $(DOMAIN).pot file. Set this to the copyright holder of the surrounding
-# package. (Note that the msgstr strings, extracted from the package's
-# sources, belong to the copyright holder of the package.) Translators are
-# expected to transfer the copyright for their translations to this person
-# or entity, or to disclaim their copyright. The empty string stands for
-# the public domain; in this case the translators are expected to disclaim
-# their copyright.
-COPYRIGHT_HOLDER = Free Software Foundation, Inc.
-
-# This is the email address or URL to which the translators shall report
-# bugs in the untranslated strings:
-# - Strings which are not entire sentences, see the maintainer guidelines
-# in the GNU gettext documentation, section 'Preparing Strings'.
-# - Strings which use unclear terms or require additional context to be
-# understood.
-# - Strings which make invalid assumptions about notation of date, time or
-# money.
-# - Pluralisation problems.
-# - Incorrect English spelling.
-# - Incorrect formatting.
-# It can be your email address, or a mailing list address where translators
-# can write to without being subscribed, or the URL of a web page through
-# which the translators can contact you.
-MSGID_BUGS_ADDRESS = bug-m4@gnu.org
-
-# This is the list of locale categories, beyond LC_MESSAGES, for which the
-# message catalogs shall be used. It is usually empty.
-EXTRA_LOCALE_CATEGORIES =
diff --git a/po/POTFILES.in b/po/POTFILES.in
deleted file mode 100644
index cb3767f5..00000000
--- a/po/POTFILES.in
+++ /dev/null
@@ -1,31 +0,0 @@
-m4/builtin.c
-m4/debug.c
-m4/gnu/clean-temp.c
-m4/gnu/closein.c
-m4/gnu/closeout.c
-m4/gnu/error.c
-m4/gnu/obstack.c
-m4/gnu/quotearg.c
-m4/gnu/regcomp.c
-m4/gnu/verror.c
-m4/gnu/xalloc-die.c
-m4/gnu/xprintf.c
-m4/input.c
-m4/macro.c
-m4/module.c
-m4/output.c
-m4/path.c
-m4/symtab.c
-m4/utility.c
-modules/evalparse.c
-modules/format.c
-modules/gnu.c
-modules/m4.c
-modules/mpeval.c
-modules/traditional.c
-src/freeze.c
-src/getopt.c
-src/main.c
-src/stackovf.c
-src/version-etc.c
-src/xstrtol-error.c
diff --git a/src/freeze.c b/src/freeze.c
deleted file mode 100644
index 426e34b5..00000000
--- a/src/freeze.c
+++ /dev/null
@@ -1,1000 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2004-2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/* This module handles frozen files. */
-
-#include <config.h>
-
-#include "m4.h"
-
-#include "binary-io.h"
-#include "close-stream.h"
-#include "quotearg.h"
-#include "verify.h"
-#include "xmemdup0.h"
-
-static void produce_mem_dump (FILE *, const char *, size_t);
-static void produce_resyntax_dump (m4 *, FILE *);
-static void produce_syntax_dump (FILE *, m4_syntax_table *, char);
-static void produce_module_dump (m4 *, FILE *, m4_module *);
-static void produce_symbol_dump (m4 *, FILE *, m4_symbol_table *);
-static void *dump_symbol_CB (m4_symbol_table *, const char *,
- size_t, m4_symbol *, void *);
-static void issue_expect_message (m4 *, int);
-static int decode_char (m4 *, FILE *, bool *);
-
-
-/* Dump an ASCII-encoded representation of LEN bytes at MEM to FILE.
- MEM may contain embedded NUL characters. */
-static void
-produce_mem_dump (FILE *file, const char *mem, size_t len)
-{
- char *quoted = quotearg_style_mem (escape_quoting_style, mem, len);
- /* Any errors will be detected by ferror later. */
- fwrite (quoted, strlen (quoted), 1, file);
-}
-
-
-/* Produce the 'R14\nPOSIX_EXTENDED\n' frozen file dump of the current
- default regular expression syntax. Note that it would be a little
- faster to use the encoded syntax in this format as used by re_compile(),
- but the representation of RE_SYNTAX_POSIX_EXTENDED may change in
- future (or alternative) implementations of re_compile, so we use an
- unencoded representation here. */
-
-static void
-produce_resyntax_dump (m4 *context, FILE *file)
-{
- int code = m4_get_regexp_syntax_opt (context);
-
- /* Don't dump default syntax code (`0' for GNU_EMACS). */
- if (code)
- {
- const char *resyntax = m4_regexp_syntax_decode (code);
-
- if (!resyntax)
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("invalid regexp syntax code `%d'"), code);
-
- /* No need to use produce_mem_dump, since we know all resyntax
- names are already ASCII-encoded. */
- xfprintf (file, "R%zu\n%s\n", strlen (resyntax), resyntax);
- }
-}
-
-static void
-produce_syntax_dump (FILE *file, m4_syntax_table *syntax, char ch)
-{
- char buf[UCHAR_MAX + 1];
- int code = m4_syntax_code (ch);
- int count = 0;
- int i;
-
- for (i = 0; i < UCHAR_MAX + 1; ++i)
- if (m4_has_syntax (syntax, i, code) && code != syntax->orig[i])
- buf[count++] = i;
-
- /* If code falls in M4_SYNTAX_MASKS, then we must treat it
- specially, since it will not be found in syntax->orig. */
- if (count == 1
- && ((code == M4_SYNTAX_RQUOTE && *buf == *DEF_RQUOTE)
- || (code == M4_SYNTAX_ECOMM && *buf == *DEF_ECOMM)))
- return;
-
- if (count || (code & M4_SYNTAX_MASKS))
- {
- xfprintf (file, "S%c%d\n", ch, count);
- produce_mem_dump (file, buf, count);
- fputc ('\n', file);
- }
-}
-
-/* Store the debug mode in textual format. */
-static void
-produce_debugmode_state (FILE *file, int flags)
-{
- /* This code tracks the number of bits in M4_DEBUG_TRACE_VERBOSE. */
- char str[15];
- int offset = 0;
- verify ((1 << (sizeof str - 1)) - 1 == M4_DEBUG_TRACE_VERBOSE);
- if (flags & M4_DEBUG_TRACE_ARGS)
- str[offset++] = 'a';
- if (flags & M4_DEBUG_TRACE_EXPANSION)
- str[offset++] = 'e';
- if (flags & M4_DEBUG_TRACE_QUOTE)
- str[offset++] = 'q';
- if (flags & M4_DEBUG_TRACE_ALL)
- str[offset++] = 't';
- if (flags & M4_DEBUG_TRACE_LINE)
- str[offset++] = 'l';
- if (flags & M4_DEBUG_TRACE_FILE)
- str[offset++] = 'f';
- if (flags & M4_DEBUG_TRACE_PATH)
- str[offset++] = 'p';
- if (flags & M4_DEBUG_TRACE_CALL)
- str[offset++] = 'c';
- if (flags & M4_DEBUG_TRACE_INPUT)
- str[offset++] = 'i';
- if (flags & M4_DEBUG_TRACE_CALLID)
- str[offset++] = 'x';
- if (flags & M4_DEBUG_TRACE_MODULE)
- str[offset++] = 'm';
- if (flags & M4_DEBUG_TRACE_STACK)
- str[offset++] = 's';
- if (flags & M4_DEBUG_TRACE_DEREF)
- str[offset++] = 'd';
- if (flags & M4_DEBUG_TRACE_OUTPUT_DUMPDEF)
- str[offset++] = 'o';
- str[offset] = '\0';
- if (offset)
- xfprintf (file, "d%d\n%s\n", offset, str);
-}
-
-/* The modules must be dumped in the order in which they will be
- reloaded from the frozen file. We store handles in a push
- down stack, so we need to dump them in the reverse order to that. */
-static void
-produce_module_dump (m4 *context, FILE *file, m4_module *module)
-{
- const char *name = m4_get_module_name (module);
- size_t len = strlen (name);
-
- module = m4_module_next (context, module);
- if (module)
- produce_module_dump (context, file, module);
-
- xfprintf (file, "M%zu\n", len);
- produce_mem_dump (file, name, len);
- fputc ('\n', file);
-}
-
-/* Process all entries in one bucket, from the last to the first.
- This order ensures that, at reload time, pushdef's will be
- executed with the oldest definitions first. */
-static void
-produce_symbol_dump (m4 *context, FILE *file, m4_symbol_table *symtab)
-{
- if (m4_symtab_apply (symtab, true, dump_symbol_CB, file))
- assert (false);
-}
-
-/* Given a stack of symbol values starting with VALUE, destructively
- reverse the stack and return the pointer to what was previously the
- last value in the stack. VALUE may be NULL. The symbol table that
- owns the value stack should not be modified or consulted until this
- is called again to undo the effect. */
-static m4_symbol_value *
-reverse_symbol_value_stack (m4_symbol_value *value)
-{
- m4_symbol_value *result = NULL;
- m4_symbol_value *next;
- while (value)
- {
- next = VALUE_NEXT (value);
- VALUE_NEXT (value) = result;
- result = value;
- value = next;
- }
- return result;
-}
-
-/* Dump the stack of values for SYMBOL, with name SYMBOL_NAME and
- length LEN, located in SYMTAB. USERDATA is interpreted as the
- FILE* to dump to. */
-static void *
-dump_symbol_CB (m4_symbol_table *symtab, const char *symbol_name, size_t len,
- m4_symbol *symbol, void *userdata)
-{
- FILE *file = (FILE *) userdata;
- m4_symbol_value *value;
- m4_symbol_value *last;
-
- last = value = reverse_symbol_value_stack (m4_get_symbol_value (symbol));
- while (value)
- {
- m4_module *module = VALUE_MODULE (value);
- const char *module_name = module ? m4_get_module_name (module) : NULL;
- size_t module_len = module_name ? strlen (module_name) : 0;
-
- if (m4_is_symbol_value_text (value))
- {
- const char *text = m4_get_symbol_value_text (value);
- size_t text_len = m4_get_symbol_value_len (value);
- xfprintf (file, "T%zu,%zu", len, text_len);
- if (module)
- xfprintf (file, ",%zu", module_len);
- fputc ('\n', file);
-
- produce_mem_dump (file, symbol_name, len);
- fputc ('\n', file);
- produce_mem_dump (file, text, text_len);
- fputc ('\n', file);
- if (module)
- {
- produce_mem_dump (file, module_name, module_len);
- fputc ('\n', file);
- }
- }
- else if (m4_is_symbol_value_func (value))
- {
- const m4_builtin *bp = m4_get_symbol_value_builtin (value);
- size_t bp_len;
- if (bp == NULL)
- assert (!"INTERNAL ERROR: builtin not found in builtin table!");
- bp_len = strlen (bp->name);
-
- xfprintf (file, "F%zu,%zu", len, bp_len);
- if (module)
- xfprintf (file, ",%zu", module_len);
- fputc ('\n', file);
-
- produce_mem_dump (file, symbol_name, len);
- fputc ('\n', file);
- produce_mem_dump (file, bp->name, bp_len);
- fputc ('\n', file);
- if (module)
- {
- produce_mem_dump (file, module_name, module_len);
- fputc ('\n', file);
- }
- }
- else if (m4_is_symbol_value_placeholder (value))
- ; /* Nothing to do for a builtin we couldn't reload earlier. */
- else
- assert (!"dump_symbol_CB");
- value = VALUE_NEXT (value);
- }
- reverse_symbol_value_stack (last);
- if (m4_get_symbol_traced (symbol))
- xfprintf (file, "t%zu\n%s\n", len, symbol_name);
- return NULL;
-}
-
-/* Produce a frozen state to the given file NAME. */
-void
-produce_frozen_state (m4 *context, const char *name)
-{
- FILE *file = fopen (name, O_BINARY ? "wb" : "w");
- const char *str;
- const m4_string_pair *pair;
-
- if (!file)
- {
- m4_error (context, 0, errno, NULL, _("cannot open %s"),
- quotearg_style (locale_quoting_style, name));
- return;
- }
-
- /* Write a recognizable header. */
-
- xfprintf (file, "# This is a frozen state file generated by GNU %s %s\n",
- PACKAGE, VERSION);
- fputs ("V2\n", file);
-
- /* Dump quote delimiters. */
- pair = m4_get_syntax_quotes (M4SYNTAX);
- if (STRNEQ (pair->str1, DEF_LQUOTE) || STRNEQ (pair->str2, DEF_RQUOTE))
- {
- xfprintf (file, "Q%zu,%zu\n", pair->len1, pair->len2);
- produce_mem_dump (file, pair->str1, pair->len1);
- fputc ('\n', file);
- produce_mem_dump (file, pair->str2, pair->len2);
- fputc ('\n', file);
- }
-
- /* Dump comment delimiters. */
- pair = m4_get_syntax_comments (M4SYNTAX);
- if (STRNEQ (pair->str1, DEF_BCOMM) || STRNEQ (pair->str2, DEF_ECOMM))
- {
- xfprintf (file, "C%zu,%zu\n", pair->len1, pair->len2);
- produce_mem_dump (file, pair->str1, pair->len1);
- fputc ('\n', file);
- produce_mem_dump (file, pair->str2, pair->len2);
- fputc ('\n', file);
- }
-
- /* Dump regular expression syntax. */
- produce_resyntax_dump (context, file);
-
- /* Dump syntax table. */
- str = "I@WLBOD${}SA(),RE";
- while (*str)
- produce_syntax_dump (file, M4SYNTAX, *str++);
-
- /* Dump debugmode state. */
- produce_debugmode_state (file, m4_get_debug_level_opt (context));
-
- /* Dump all loaded modules. */
- produce_module_dump (context, file, m4_module_next (context, NULL));
-
- /* Dump all symbols. */
- produce_symbol_dump (context, file, M4SYMTAB);
-
- /* Let diversions be issued from output.c module, its cleaner to have this
- piece of code there. */
- m4_freeze_diversions (context, file);
-
- /* All done. */
-
- fputs ("# End of frozen state file\n", file);
- if (close_stream (file) != 0)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("unable to create frozen state"));
-}
-
-/* Issue a message saying that some character is an EXPECTED character. */
-static void
-issue_expect_message (m4 *context, int expected)
-{
- if (expected == '\n')
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("expecting line feed in frozen file"));
- else
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("expecting character `%c' in frozen file"), expected);
-}
-
-
-/* Reload frozen state. */
-
-/* Read the next character from the IN stream. Various escape
- sequences are converted, and returned. EOF is returned if the end
- of file is reached whilst reading the character, or on an
- unrecognized escape sequence. */
-
-static int
-decode_char (m4 *context, FILE *in, bool *advance_line)
-{
- int ch = getc (in);
- int next;
- int value = 0;
-
- if (*advance_line)
- {
- m4_set_current_line (context, m4_get_current_line (context) + 1);
- *advance_line = false;
- }
-
- while (ch == '\\')
- {
- ch = getc (in);
- switch (ch)
- {
- case 'a': return '\a';
- case 'b': return '\b';
- case 'f': return '\f';
- case 'n': return '\n';
- case 'r': return '\r';
- case 't': return '\t';
- case 'v': return '\v';
- case '\\': return '\\';
-
- case '\n':
- ch = getc (in);
- m4_set_current_line (context, m4_get_current_line (context) + 1);
- continue;
-
- case 'x': case 'X':
- next = getc (in);
- if (next >= '0' && next <= '9')
- ch = (next - '0') * 16;
- else if (next >= 'a' && next <= 'f')
- ch = (next - 'a' + 10) * 16;
- else if (next >= 'A' && next <= 'F')
- ch = (next - 'A' + 10) * 16;
- else
- return EOF;
- next = getc (in);
- if (next >= '0' && next <= '9')
- ch += next - '0';
- else if (next >= 'a' && next <= 'f')
- ch += next - 'a' + 10;
- else if (next >= 'A' && next <= 'F')
- ch += next - 'A' + 10;
- else
- return EOF;
- return ch;
- case '0': case '1': case '2': case '3':
- value = ch - '0';
- ch = getc (in);
- /* fall through */
- case '4': case '5': case '6': case '7':
- if (ch >= '0' && ch <= '7')
- {
- value = value * 8 + ch - '0';
- ch = getc (in);
- }
- else
- {
- ungetc (ch, in);
- return value;
- }
- if (ch >= '0' && ch <= '7')
- value = value * 8 + ch - '0';
- else
- ungetc (ch, in);
- return value;
-
- default:
- return EOF;
- }
- }
-
- if (ch == '\n')
- *advance_line = true;
- return ch;
-}
-
-
-/* Reload state from the given file NAME. We are seeking speed,
- here. */
-
-void
-reload_frozen_state (m4 *context, const char *name)
-{
- FILE *file = NULL;
- char *filepath;
- int version;
- int character;
- int operation;
- char syntax;
- char *string[3];
- size_t allocated[3];
- int number[3] = {0};
- bool advance_line = true;
-
-#define GET_CHARACTER \
- do \
- { \
- if (advance_line) \
- { \
- m4_set_current_line (context, \
- m4_get_current_line (context) + 1); \
- advance_line = false; \
- } \
- character = getc (file); \
- if (character == '\n') \
- advance_line = true; \
- } \
- while (0)
-
-#define GET_NUMBER(Number, AllowNeg) \
- do \
- { \
- unsigned int n = 0; \
- while (isdigit (character) && n <= INT_MAX / 10) \
- { \
- n = 10 * n + character - '0'; \
- GET_CHARACTER; \
- } \
- if (((AllowNeg) ? INT_MIN: INT_MAX) < n \
- || isdigit (character)) \
- m4_error (context, EXIT_FAILURE, 0, NULL, \
- _("integer overflow in frozen file")); \
- (Number) = n; \
- } \
- while (0)
-
-#define GET_STRING(File, Buf, BufSize, StrLen, UseChar) \
- do \
- { \
- size_t len = (StrLen); \
- char *p; \
- int ch; \
- if (UseChar) \
- { \
- ungetc (character, File); \
- if (advance_line) \
- { \
- assert (character == '\n'); \
- advance_line = false; \
- } \
- } \
- CHECK_ALLOCATION ((Buf), (BufSize), len); \
- p = (Buf); \
- while (len-- > 0) \
- { \
- ch = (version > 1 \
- ? decode_char (context, File, &advance_line) \
- : getc (File)); \
- if (ch == EOF) \
- m4_error (context, EXIT_FAILURE, 0, NULL, \
- _("premature end of frozen file")); \
- *p++ = ch; \
- } \
- *p = '\0'; \
- GET_CHARACTER; \
- while (version > 1 && character == '\\') \
- { \
- GET_CHARACTER; \
- VALIDATE ('\n'); \
- GET_CHARACTER; \
- } \
- } \
- while (0)
-
-#define VALIDATE(Expected) \
- do \
- { \
- if (character != (Expected)) \
- issue_expect_message (context, (Expected)); \
- } \
- while (0)
-
-#define CHECK_ALLOCATION(Where, Allocated, Needed) \
- do \
- { \
- if ((Needed) + 1 > (Allocated)) \
- { \
- free (Where); \
- (Allocated) = (Needed) + 1; \
- (Where) = xcharalloc (Allocated); \
- } \
- } \
- while (0)
-
- /* Skip comments (`#' at beginning of line) and blank lines, setting
- character to the next directive or to EOF. */
-
-#define GET_DIRECTIVE \
- do \
- { \
- GET_CHARACTER; \
- if (character == '#') \
- { \
- while (character != EOF && character != '\n') \
- GET_CHARACTER; \
- VALIDATE ('\n'); \
- } \
- } \
- while (character == '\n')
-
- filepath = m4_path_search (context, name, NULL);
- file = m4_fopen (context, filepath, "r");
- if (file == NULL)
- m4_error (context, EXIT_FAILURE, errno, NULL, _("cannot open %s"),
- quotearg_style (locale_quoting_style, name));
- m4_set_current_file (context, name);
-
- allocated[0] = 100;
- string[0] = xcharalloc (allocated[0]);
- allocated[1] = 100;
- string[1] = xcharalloc (allocated[1]);
- allocated[2] = 100;
- string[2] = xcharalloc (allocated[2]);
-
- /* Validate format version. Accept both `1' (m4 1.3 and 1.4.x) and
- `2' (m4 2.0). */
- GET_DIRECTIVE;
- VALIDATE ('V');
- GET_CHARACTER;
- GET_NUMBER (version, false);
- switch (version)
- {
- case 2:
- break;
- case 1:
- m4__module_open (context, "m4", NULL);
- if (m4_get_posixly_correct_opt (context))
- m4__module_open (context, "traditional", NULL);
- else
- m4__module_open (context, "gnu", NULL);
- /* Disable { and } categories, since ${11} was not supported in
- 1.4.x. */
- m4_set_syntax (M4SYNTAX, 'O', '+', "{}", 2);
- break;
- default:
- if (version > 2)
- m4_error (context, EXIT_MISMATCH, 0, NULL,
- _("frozen file version %d greater than max supported of 2"),
- version);
- else
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("ill-formed frozen file, version directive expected"));
- }
- VALIDATE ('\n');
-
- GET_DIRECTIVE;
- while (character != EOF)
- {
- switch (character)
- {
- default:
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("ill-formed frozen file, unknown directive %c"),
- character);
-
- case 'd':
- /* Set debugmode flags. */
- if (version < 2)
- {
- /* 'd' operator is not supported in format version 1. */
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, version 2 directive `%c' encountered"), 'd');
- }
-
- GET_CHARACTER;
- GET_NUMBER (number[0], false);
- VALIDATE ('\n');
- GET_STRING (file, string[0], allocated[0], number[0], false);
- VALIDATE ('\n');
-
- if (m4_debug_decode (context, string[0], number[0]) < 0)
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("unknown debug mode %s"),
- quotearg_style_mem (locale_quoting_style, string[0],
- number[0]));
- break;
-
- case 'F':
- GET_CHARACTER;
-
- /* Get string lengths. */
-
- GET_NUMBER (number[0], false);
- VALIDATE (',');
- GET_CHARACTER;
- GET_NUMBER (number[1], false);
-
- if (character == ',')
- {
- if (version > 1)
- {
- /* 'F' operator accepts an optional third argument for
- format versions 2 or later. */
- GET_CHARACTER;
- GET_NUMBER (number[2], false);
- }
- else
- /* 3 argument 'F' operations are invalid for format
- version 1. */
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, version 2 directive `%c' encountered"), 'F');
- }
- else
- {
- number[2] = 0;
- }
-
- VALIDATE ('\n');
-
-
- /* Get string contents. */
-
- GET_STRING (file, string[0], allocated[0], number[0], false);
- if (version > 1)
- {
- VALIDATE ('\n');
- GET_CHARACTER;
- }
- GET_STRING (file, string[1], allocated[1], number[1], true);
- if (version > 1 && number[2])
- {
- VALIDATE ('\n');
- GET_CHARACTER;
- }
- GET_STRING (file, string[2], allocated[2], number[2], true);
- VALIDATE ('\n');
-
- /* Enter a macro having a builtin function as a definition. */
- {
- m4_module *module = NULL;
- m4_symbol_value *token;
-
- // Builtins cannot contain a NUL byte.
- if (strlen (string[1]) < number[1])
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, invalid builtin %s encountered"),
- quotearg_style_mem (locale_quoting_style, string[1],
- number[1]));
- if (number[2] > 0)
- {
- if (strlen (string[2]) < number[2])
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, invalid module %s encountered"),
- quotearg_style_mem (locale_quoting_style,
- string[2], number[2]));
- module = m4__module_find (context, string[2]);
- }
- token = m4_builtin_find_by_name (context, module, string[1]);
-
- if (token == NULL)
- {
- token = (m4_symbol_value *) xzalloc (sizeof *token);
- m4_set_symbol_value_placeholder (token, xstrdup (string[1]));
- VALUE_MODULE (token) = module;
- VALUE_MIN_ARGS (token) = 0;
- VALUE_MAX_ARGS (token) = -1;
- }
- m4_symbol_pushdef (M4SYMTAB, string[0], number[0], token);
- }
- break;
-
- case 'M':
-
- /* Load a module, but *without* perturbing the symbol table.
- Note that any expansion from loading the module which would
- have been seen when loading it originally is discarded
- when loading it from a frozen file. */
-
- if (version < 2)
- {
- /* 'M' operator is not supported in format version 1. */
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, version 2 directive `%c' encountered"), 'M');
- }
-
- GET_CHARACTER;
- GET_NUMBER (number[0], false);
- VALIDATE ('\n');
- GET_STRING (file, string[0], allocated[0], number[0], false);
- VALIDATE ('\n');
-
- if (strlen (string[0]) < number[0])
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, invalid module %s encountered"),
- quotearg_style_mem (locale_quoting_style,
- string[0], number[0]));
- m4__module_open (context, string[0], NULL);
-
- break;
-
- case 'R':
-
- if (version < 2)
- {
- /* 'R' operator is not supported in format version 1. */
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, version 2 directive `%c' encountered"), 'R');
- }
-
- GET_CHARACTER;
- GET_NUMBER (number[0], false);
- VALIDATE ('\n');
- GET_STRING (file, string[0], allocated[0], number[0], false);
- VALIDATE ('\n');
-
- m4_set_regexp_syntax_opt (context,
- m4_regexp_syntax_encode (string[0]));
- if (m4_get_regexp_syntax_opt (context) < 0
- || strlen (string[0]) < number[0])
- {
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("bad syntax-spec %s"),
- quotearg_style_mem (locale_quoting_style, string[0],
- number[0]));
- }
-
- break;
-
- case 'S':
-
- if (version < 2)
- {
- /* 'S' operator is not supported in format version 1. */
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, version 2 directive `%c' encountered"), 'S');
- }
-
- GET_CHARACTER;
- syntax = character;
- GET_CHARACTER;
- GET_NUMBER (number[0], false);
- VALIDATE ('\n');
- GET_STRING (file, string[0], allocated[0], number[0], false);
-
- /* Syntax under M4_SYNTAX_MASKS is handled specially; all
- other characters are additive. */
- if ((m4_set_syntax (M4SYNTAX, syntax,
- (m4_syntax_code (syntax) & M4_SYNTAX_MASKS
- ? '=' : '+'), string[0], number[0]) < 0)
- && (syntax != '\0'))
- {
- m4_error (context, 0, 0, NULL,
- _("undefined syntax code %c"), syntax);
- }
- break;
-
- case 't':
- /* Trace a macro name. */
- if (version < 2)
- {
- /* 't' operator is not supported in format version 1. */
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, version 2 directive `%c' encountered"), 't');
- }
-
- GET_CHARACTER;
- GET_NUMBER (number[0], false);
- VALIDATE ('\n');
- GET_STRING (file, string[0], allocated[0], number[0], false);
- VALIDATE ('\n');
-
- m4_set_symbol_name_traced (M4SYMTAB, string[0], number[0], true);
-
- break;
-
- case 'C':
- case 'D':
- case 'Q':
- operation = character;
- GET_CHARACTER;
-
- /* Get string lengths. */
-
- if (operation == 'D' && character == '-')
- {
- /* Accept a negative diversion number. */
- GET_CHARACTER;
- GET_NUMBER (number[0], true);
- number[0] = -number[0];
- }
- else
- GET_NUMBER (number[0], false);
- VALIDATE (',');
- GET_CHARACTER;
- GET_NUMBER (number[1], false);
- VALIDATE ('\n');
-
- /* Get string contents. */
- if (operation != 'D')
- {
- GET_STRING (file, string[0], allocated[0], number[0], false);
- if (version > 1)
- {
- VALIDATE ('\n');
- GET_CHARACTER;
- }
- }
- else
- GET_CHARACTER;
- GET_STRING (file, string[1], allocated[1], number[1], true);
- VALIDATE ('\n');
-
- /* Act according to operation letter. */
-
- switch (operation)
- {
- case 'C':
-
- /* Change comment strings. */
-
- m4_set_comment (M4SYNTAX, string[0], number[0], string[1],
- number[1]);
- break;
-
- case 'D':
-
- /* Select a diversion and add a string to it. */
-
- m4_make_diversion (context, number[0]);
- if (number[1] > 0)
- m4_output_text (context, string[1], number[1]);
- break;
-
- case 'Q':
-
- /* Change quote strings. */
-
- m4_set_quotes (M4SYNTAX, string[0], number[0], string[1],
- number[1]);
- break;
-
- default:
-
- /* Cannot happen. */
-
- break;
- }
- break;
-
- case 'T':
- GET_CHARACTER;
-
- /* Get string lengths. */
-
- GET_NUMBER (number[0], false);
- VALIDATE (',');
- GET_CHARACTER;
- GET_NUMBER (number[1], false);
-
- if (character == ',')
- {
- if (version > 1)
- {
- /* 'T' operator accepts an optional third argument for
- format versions 2 or later. */
- GET_CHARACTER;
- GET_NUMBER (number[2], false);
- }
- else
- {
- /* 3 argument 'T' operations are invalid for format
- version 1. */
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, version 2 directive `%c' encountered"), 'T');
- }
- }
- else
- number[2] = 0;
-
- VALIDATE ('\n');
-
- /* Get string contents. */
- GET_STRING (file, string[0], allocated[0], number[0], false);
- if (version > 1)
- {
- VALIDATE ('\n');
- GET_CHARACTER;
- }
- GET_STRING (file, string[1], allocated[1], number[1], true);
- if (version > 1 && number[2])
- {
- VALIDATE ('\n');
- GET_CHARACTER;
- }
- GET_STRING (file, string[2], allocated[2], number[2], true);
- VALIDATE ('\n');
-
- /* Enter a macro having an expansion text as a definition. */
- {
- m4_symbol_value *token;
- m4_module *module = NULL;
-
- token = (m4_symbol_value *) xzalloc (sizeof *token);
- if (number[2] > 0)
- {
- if (strlen (string[2]) < number[2])
- m4_error (context, EXIT_FAILURE, 0, NULL, _("\
-ill-formed frozen file, invalid module %s encountered"),
- quotearg_style_mem (locale_quoting_style,
- string[2], number[2]));
- module = m4__module_find (context, string[2]);
- }
-
- m4_set_symbol_value_text (token, xmemdup0 (string[1], number[1]),
- number[1], 0);
- VALUE_MODULE (token) = module;
- VALUE_MAX_ARGS (token) = -1;
-
- m4_symbol_pushdef (M4SYMTAB, string[0], number[0], token);
- }
- break;
-
- }
- GET_DIRECTIVE;
- }
-
- free (string[0]);
- free (string[1]);
- free (string[2]);
- if (close_stream (file) != 0)
- m4_error (context, EXIT_FAILURE, errno, NULL,
- _("unable to read frozen state"));
- m4_set_current_file (context, NULL);
- m4_set_current_line (context, 0);
-
-#undef GET_STRING
-#undef GET_CHARACTER
-#undef GET_NUMBER
-#undef VALIDATE
-#undef CHECK_ALLOCATION
-#undef GET_DIRECTIVE
-}
diff --git a/src/m4.h b/src/m4.h
deleted file mode 100644
index acd8fa9b..00000000
--- a/src/m4.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1989-1994, 2006-2007, 2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef M4_H
-#define M4_H
-
-#include <signal.h>
-
-#include "m4private.h"
-
-#include "gettext.h"
-
-/* Error handling. */
-#ifdef USE_STACKOVF
-void setup_stackovf_trap (char *const *, char *const *,
- void (*handler) (void));
-void stackovf_exit (void);
-#endif
-
-
-/* File: freeze.c --- frozen state files. */
-
-void produce_frozen_state (m4 *context, const char *);
-void reload_frozen_state (m4 *context, const char *);
-
-#endif /* M4_H */
diff --git a/src/main.c b/src/main.c
deleted file mode 100644
index 4b897e34..00000000
--- a/src/main.c
+++ /dev/null
@@ -1,762 +0,0 @@
-/* GNU m4 -- A simple macro processor
-
- Copyright (C) 1989-1994, 1999-2000, 2003-2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-#include <locale.h>
-
-#include "m4.h"
-
-#include "closein.h"
-#include "configmake.h"
-#include "getopt.h"
-#include "propername.h"
-#include "quotearg.h"
-#include "version-etc.h"
-#include "xstrtol.h"
-
-#define AUTHORS \
- proper_name_utf8 ("Rene' Seindal", "Ren\xc3\xa9 Seindal"), \
- proper_name ("Gary V. Vaughan"), \
- proper_name ("Eric Blake")
-
-typedef struct deferred
-{
- struct deferred *next;
- int code; /* deferred optchar */
- const char *value;
-} deferred;
-
-
-/* Error handling functions. */
-
-#ifdef USE_STACKOVF
-
-/* Tell user stack overflowed and abort. */
-static void
-stackovf_handler (void)
-{
- /* FIXME - calling gettext and error inside a signal handler is dangerous,
- since these functions invoke functions that are not signal-safe. We
- are sort of justified by the fact that we will exit and never return,
- but this should really be fixed. */
- error (EXIT_FAILURE, 0, _("stack overflow (infinite define recursion?)"));
-}
-
-#endif /* USE_STACKOVF */
-
-
-
-/* Print a usage message and exit with STATUS. */
-static void
-usage (int status)
-{
- if (status != EXIT_SUCCESS)
- xfprintf (stderr, _("Try `%s --help' for more information.\n"),
- m4_get_program_name ());
- else
- {
- xprintf (_("Usage: %s [OPTION]... [FILE]...\n"), m4_get_program_name ());
- fputs (_("\
-Process macros in FILEs.\n\
-If no FILE or if FILE is `-', standard input is read. If no FILE, and both\n\
-standard input and standard error are terminals, -i is implied.\n\
-"), stdout);
- puts ("");
- fputs (_("\
-Mandatory or optional arguments to long options are mandatory or optional\n\
-for short options too.\n\
-\n\
-Operation modes:\n\
- --help display this help and exit\n\
- --version output version information and exit\n\
-"), stdout);
- fputs (_("\
- -b, --batch buffer output, process interrupts\n\
- -c, --discard-comments do not copy comments to the output\n\
- -E, --fatal-warnings once: warnings become errors, twice: stop\n\
- execution at first error\n\
- -i, --interactive unbuffer output, ignore interrupts\n\
- -P, --prefix-builtins force a `m4_' prefix to all builtins\n\
- -Q, --quiet, --silent suppress some warnings for builtins\n\
- -r, --regexp-syntax[=SPEC] set default regexp syntax to SPEC [GNU_M4]\n\
- --safer disable potentially unsafe builtins\n\
- -W, --warnings enable all warnings\n\
-"), stdout);
- puts ("");
- fputs (_("\
-SPEC is any one of:\n\
- AWK, BASIC, BSD_M4, ED, EMACS, EXTENDED, GNU_AWK, GNU_EGREP, GNU_M4,\n\
- GREP, POSIX_AWK, POSIX_EGREP, MINIMAL, MINIMAL_BASIC, SED.\n\
-"), stdout);
- puts ("");
- fputs (_("\
-Preprocessor features:\n\
- -B, --prepend-include=DIR add DIR to include path before `.'\n\
- -D, --define=NAME[=VALUE] define NAME as having VALUE, or empty\n\
- --import-environment import all environment variables as macros\n\
- -I, --include=DIR add DIR to include path after `.'\n\
-"), stdout);
- fputs (_("\
- --popdef=NAME popdef NAME\n\
- -p, --pushdef=NAME[=VALUE] pushdef NAME as having VALUE, or empty\n\
- -s, --synclines short for --syncoutput=1\n\
- --syncoutput[=STATE] set generation of `#line NUM \"FILE\"' lines\n\
- to STATE (0=off, 1=on, default 0)\n\
- -U, --undefine=NAME undefine NAME\n\
-"), stdout);
- puts ("");
- fputs (_("\
-Limits control:\n\
- -g, --gnu override -G to re-enable GNU extensions\n\
- -G, --traditional, --posix suppress all GNU extensions\n\
- -L, --nesting-limit=NUMBER change artificial nesting limit [1024]\n\
-"), stdout);
- puts ("");
- fputs (_("\
-Frozen state files:\n\
- -F, --freeze-state=FILE produce a frozen state on FILE at end\n\
- -R, --reload-state=FILE reload a frozen state from FILE at start\n\
-"), stdout);
- puts ("");
- fputs (_("\
-Debugging:\n\
- -d, --debug[=[-|+]FLAGS], --debugmode[=[-|+]FLAGS]\n\
- set debug level (no FLAGS implies `+adeq')\n\
- --debugfile[=FILE] redirect debug and trace output to FILE\n\
- (default stderr, discard if empty string)\n\
- -l, --debuglen=NUM restrict macro tracing size\n\
- -t, --trace=NAME, --traceon=NAME\n\
- trace NAME when it is defined\n\
- --traceoff=NAME no longer trace NAME\n\
-"), stdout);
- puts ("");
- fputs (_("\
-FLAGS is any of:\n\
- a show actual arguments in trace\n\
- c show collection line in trace\n\
- d warn when dereferencing undefined macros (default on unless -E)\n\
- e show expansion in trace\n\
- f include current input file name in trace and debug\n\
- i show changes in input files in debug\n\
- l include current input line number in trace and debug\n\
-"), stdout);
- fputs (_("\
- m show module information in trace, debug, and dumpdef\n\
- o output dumpdef to stderr rather than debug file\n\
- p show results of path searches in debug\n\
- q quote values in dumpdef and trace, useful with a or e\n\
- s show full stack of pushdef values in dumpdef\n\
- t trace all macro calls, regardless of per-macro traceon state\n\
- x include unique macro call id in trace, useful with c\n\
- V shorthand for all of the above flags\n\
-"), stdout);
- puts ("");
- fputs (_("\
-If defined, the environment variable `M4PATH' is a colon-separated list\n\
-of directories included after any specified by `-I' or `-B'. The\n\
-environment variable `POSIXLY_CORRECT' implies -G -Q; otherwise GNU\n\
-extensions are enabled by default.\n\
-"), stdout);
- puts ("");
- fputs (_("\
-Exit status is 0 for success, 1 for failure, 63 for frozen file version\n\
-mismatch, or whatever value was passed to the m4exit macro.\n\
-"), stdout);
- emit_bug_reporting_address ();
- }
- exit (status);
-}
-
-/* For long options that have no equivalent short option, use a
- non-character as a pseudo short option, starting with CHAR_MAX + 1. */
-enum
-{
- ARGLENGTH_OPTION = CHAR_MAX + 1, /* not quite -l, because of message */
- DEBUGFILE_OPTION, /* no short opt */
- ERROR_OUTPUT_OPTION, /* not quite -o, because of message */
- HASHSIZE_OPTION, /* not quite -H, because of message */
- IMPORT_ENVIRONMENT_OPTION, /* no short opt */
- POPDEF_OPTION, /* no short opt */
- PREPEND_INCLUDE_OPTION, /* not quite -B, because of message */
- SAFER_OPTION, /* -S still has old no-op semantics */
- SYNCOUTPUT_OPTION, /* not quite -s, because of opt arg */
- TRACEOFF_OPTION, /* no short opt */
- WORD_REGEXP_OPTION, /* deprecated, used to be -W */
-
- HELP_OPTION, /* no short opt */
- VERSION_OPTION /* no short opt */
-};
-
-/* Decode options and launch execution. */
-static const struct option long_options[] =
-{
- {"batch", no_argument, NULL, 'b'},
- {"debug", optional_argument, NULL, 'd'},
- {"debuglen", required_argument, NULL, 'l'},
- {"debugmode", optional_argument, NULL, 'd'},
- {"define", required_argument, NULL, 'D'},
- {"discard-comments", no_argument, NULL, 'c'},
- {"fatal-warnings", no_argument, NULL, 'E'},
- {"freeze-state", required_argument, NULL, 'F'},
- {"gnu", no_argument, NULL, 'g'},
- {"include", required_argument, NULL, 'I'},
- {"interactive", no_argument, NULL, 'i'},
- {"nesting-limit", required_argument, NULL, 'L'},
- {"posix", no_argument, NULL, 'G'},
- {"prefix-builtins", no_argument, NULL, 'P'},
- {"pushdef", required_argument, NULL, 'p'},
- {"quiet", no_argument, NULL, 'Q'},
- {"regexp-syntax", optional_argument, NULL, 'r'},
- {"reload-state", required_argument, NULL, 'R'},
- {"silent", no_argument, NULL, 'Q'},
- {"synclines", no_argument, NULL, 's'},
- {"trace", required_argument, NULL, 't'},
- {"traceon", required_argument, NULL, 't'},
- {"traditional", no_argument, NULL, 'G'},
- {"undefine", required_argument, NULL, 'U'},
- {"warnings", no_argument, NULL, 'W'},
-
- {"arglength", required_argument, NULL, ARGLENGTH_OPTION},
- {"debugfile", optional_argument, NULL, DEBUGFILE_OPTION},
- {"hashsize", required_argument, NULL, HASHSIZE_OPTION},
- {"error-output", required_argument, NULL, ERROR_OUTPUT_OPTION},
- {"import-environment", no_argument, NULL, IMPORT_ENVIRONMENT_OPTION},
- {"popdef", required_argument, NULL, POPDEF_OPTION},
- {"prepend-include", required_argument, NULL, PREPEND_INCLUDE_OPTION},
- {"safer", no_argument, NULL, SAFER_OPTION},
- {"syncoutput", optional_argument, NULL, SYNCOUTPUT_OPTION},
- {"traceoff", required_argument, NULL, TRACEOFF_OPTION},
- {"word-regexp", required_argument, NULL, WORD_REGEXP_OPTION},
-
- {"help", no_argument, NULL, HELP_OPTION},
- {"version", no_argument, NULL, VERSION_OPTION},
-
- { NULL, 0, NULL, 0 },
-};
-
-/* POSIX requires only -D, -U, and -s; and says that the first two
- must be recognized when interspersed with file names. Traditional
- behavior also handles -s between files. Starting OPTSTRING with
- '-' forces getopt_long to hand back file names as arguments to opt
- '\1', rather than reordering the command line. */
-#define OPTSTRING "-B:D:EF:GH:I:L:PQR:S:T:U:Wbcd::egil:o:p:r::st:"
-
-/* For determining whether to be interactive. */
-enum interactive_choice
-{
- INTERACTIVE_UNKNOWN, /* Still processing arguments, no -b or -i yet */
- INTERACTIVE_YES, /* -i specified last */
- INTERACTIVE_NO /* -b specified last */
-};
-
-/* Convert OPT to size_t, reporting an error using long option index
- OI or short option character OPTCHAR if it does not fit. */
-static size_t
-size_opt (char const *opt, int oi, int optchar)
-{
- unsigned long int size;
- strtol_error status = xstrtoul (opt, NULL, 10, &size, "kKmMgGtTPEZY0");
- if (SIZE_MAX < size && status == LONGINT_OK)
- status = LONGINT_OVERFLOW;
- if (status != LONGINT_OK)
- xstrtol_fatal (status, oi, optchar, long_options, opt);
- return size;
-}
-
-/* Process a command line file NAME. */
-static bool
-process_file (m4 *context, const char *name)
-{
- bool new_input = true;
-
- if (STREQ (name, "-"))
- /* TRANSLATORS: This is a short name for `standard input', used
- when a command line file was given as `-'. */
- m4_push_file (context, stdin, _("stdin"), false);
- else
- new_input = m4_load_filename (context, NULL, name, NULL, false);
-
- if (new_input)
- m4_macro_expand_input (context);
-
- return new_input;
-}
-
-
-/* Main entry point. Parse arguments, load modules, then parse input. */
-int
-main (int argc, char *const *argv, char *const *envp)
-{
- deferred *head = NULL; /* head of deferred argument list */
- deferred *tail = NULL;
- deferred *defn;
- size_t size; /* for parsing numeric option arguments */
-
- bool import_environment = false; /* true to import environment */
- bool seen_file = false;
- const char *debugfile = NULL;
- const char *frozen_file_to_read = NULL;
- const char *frozen_file_to_write = NULL;
- enum interactive_choice interactive = INTERACTIVE_UNKNOWN;
-
- m4 *context;
-
- int exit_status;
-
- /* Initialize gnulib error module. */
- m4_set_program_name (argv[0]);
- atexit (close_stdin);
-
- setlocale (LC_ALL, "");
-#ifdef ENABLE_NLS
- textdomain (PACKAGE);
-#endif
-
- context = m4_create ();
-
-#ifdef USE_STACKOVF
- setup_stackovf_trap (argv, envp, stackovf_handler);
-#endif
-
- if (getenv ("POSIXLY_CORRECT"))
- {
- m4_set_posixly_correct_opt (context, true);
- m4_set_suppress_warnings_opt (context, true);
- }
- set_quoting_style (NULL, escape_quoting_style);
- set_char_quoting (NULL, ':', 1);
-
- /* First, we decode the arguments, to size up tables and stuff.
- Avoid lasting side effects; for example 'm4 --debugfile=oops
- --help' must not create the file `oops'. */
- while (1)
- {
- int oi = -1;
- int optchar = getopt_long (argc, (char **) argv, OPTSTRING,
- long_options, &oi);
- if (optchar == -1)
- break;
-
- switch (optchar)
- {
- default:
- usage (EXIT_FAILURE);
-
- case 'H':
- case HASHSIZE_OPTION:
- /* -H was supported in 1.4.x, but is a no-op now. FIXME -
- remove support for -H after 2.0. */
- error (0, 0, _("warning: `%s' is deprecated"),
- optchar == 'H' ? "-H" : "--hashsize");
- break;
-
- case 'S':
- case 'T':
- /* Compatibility junk: options that other implementations
- support, but which we ignore as no-ops and don't list in
- --help. */
- error (0, 0, _("warning: `-%c' is deprecated"),
- optchar);
- break;
-
- case WORD_REGEXP_OPTION:
- /* Supported in 1.4.x as -W, but no longer present. */
- error (0, 0, _("warning: `%s' is deprecated"), "--word-regexp");
- break;
-
- case 's':
- optchar = SYNCOUTPUT_OPTION;
- optarg = "1";
- /* fall through */
- case 'D':
- case 'U':
- case 'p':
- case 'r':
- case 't':
- case POPDEF_OPTION:
- case SYNCOUTPUT_OPTION:
- case TRACEOFF_OPTION:
- defer:
- /* Arguments that cannot be handled until later are accumulated. */
-
- defn = (deferred *) xmalloc (sizeof *defn);
- defn->code = optchar;
- defn->value = optarg;
- defn->next = NULL;
-
- if (head == NULL)
- head = defn;
- else
- tail->next = defn;
- tail = defn;
- break;
-
- case '\1':
- seen_file = true;
- goto defer;
-
- case 'B':
- /* In 1.4.x, -B<num> was a no-op option for compatibility with
- Solaris m4. Warn if optarg is all numeric. FIXME -
- silence this warning after 2.0. */
- if (isdigit (to_uchar (*optarg)))
- {
- char *end;
- errno = 0;
- strtol (optarg, &end, 10);
- if (*end == '\0' && errno == 0)
- error (0, 0, _("warning: recommend using `-B ./%s' instead"),
- optarg);
- }
- /* fall through */
- case PREPEND_INCLUDE_OPTION:
- m4_add_include_directory (context, optarg, true);
- break;
-
- case 'E':
- m4_debug_decode (context, "-d", SIZE_MAX);
- if (m4_get_fatal_warnings_opt (context))
- m4_set_warnings_exit_opt (context, true);
- else
- m4_set_fatal_warnings_opt (context, true);
- break;
-
- case 'F':
- frozen_file_to_write = optarg;
- break;
-
- case 'G':
- m4_set_posixly_correct_opt (context, true);
- break;
-
- case 'I':
- m4_add_include_directory (context, optarg, false);
- break;
-
- case 'L':
- size = size_opt (optarg, oi, optchar);
- if (!size)
- size = SIZE_MAX;
- m4_set_nesting_limit_opt (context, size);
- break;
-
- case 'P':
- m4_set_prefix_builtins_opt (context, true);
- break;
-
- case 'Q':
- m4_set_suppress_warnings_opt (context, true);
- break;
-
- case 'R':
- frozen_file_to_read = optarg;
- break;
-
- case 'W':
- /* FIXME - should W take an optional argument, to allow -Wall,
- -Wnone, -Werror, -Wcategory, -Wno-category? If so, then have
- -W == -Wall. */
- m4_set_suppress_warnings_opt (context, false);
- break;
-
- case 'b':
- interactive = INTERACTIVE_NO;
- break;
-
- case 'c':
- m4_set_discard_comments_opt (context, true);
- break;
-
- case 'd':
- /* Staggered handling of 'd', since -dm is useful prior to
- first file and prior to reloading, but other -d must also
- have effect between files. */
- if (seen_file || frozen_file_to_read)
- goto defer;
- if (m4_debug_decode (context, optarg, SIZE_MAX) < 0)
- error (0, 0, _("bad debug flags: %s"),
- quotearg_style (locale_quoting_style, optarg));
- break;
-
- case 'e':
- error (0, 0, _("warning: `%s' is deprecated, use `%s' instead"),
- "-e", "-i");
- /* fall through */
- case 'i':
- interactive = INTERACTIVE_YES;
- break;
-
- case 'g':
- m4_set_posixly_correct_opt (context, false);
- break;
-
- case ARGLENGTH_OPTION:
- error (0, 0, _("warning: `%s' is deprecated, use `%s' instead"),
- "--arglength", "--debuglen");
- /* fall through */
- case 'l':
- size = size_opt (optarg, oi, optchar);
- if (!size)
- size = SIZE_MAX;
- m4_set_max_debug_arg_length_opt (context, size);
- break;
-
- case DEBUGFILE_OPTION:
- /* Staggered handling of '--debugfile', since it is useful
- prior to first file and prior to reloading, but other
- uses must also have effect between files. */
- if (seen_file || frozen_file_to_read)
- goto defer;
- debugfile = optarg;
- break;
-
- case 'o':
- case ERROR_OUTPUT_OPTION:
- /* FIXME: -o is inconsistent with other tools' use of
- -o/--output for creating an output file instead of using
- stdout, and --error-output is misnamed since it does not
- affect error messages to stderr. Change the meaning of -o
- after 2.1. */
- error (0, 0, _("warning: `%s' is deprecated, use `%s' instead"),
- optchar == 'o' ? "-o" : "--error-output", "--debugfile");
- /* Don't call m4_debug_set_output here, as it has side effects. */
- debugfile = optarg;
- break;
-
- case IMPORT_ENVIRONMENT_OPTION:
- import_environment = true;
- break;
-
- case SAFER_OPTION:
- m4_set_safer_opt (context, true);
- break;
-
- case VERSION_OPTION:
- version_etc (stdout, PACKAGE, PACKAGE_NAME, VERSION, AUTHORS, NULL);
- exit (EXIT_SUCCESS);
- break;
-
- case HELP_OPTION:
- usage (EXIT_SUCCESS);
- break;
- }
- }
-
- /* Do the basic initializations. */
- if (debugfile && !m4_debug_set_output (context, NULL, debugfile))
- m4_error (context, 0, errno, NULL, _("cannot set debug file %s"),
- quotearg_style (locale_quoting_style, debugfile));
- m4_input_init (context);
- m4_output_init (context);
-
- if (frozen_file_to_read)
- reload_frozen_state (context, frozen_file_to_read);
- else
- {
- m4_module_load (context, "m4", NULL);
- if (m4_get_posixly_correct_opt (context))
- m4_module_load (context, "traditional", NULL);
- else
- m4_module_load (context, "gnu", NULL);
- }
-
- /* Import environment variables as macros. The definition are
- prepended to the macro definition list, so -U can override
- environment variables. */
-
- if (import_environment)
- {
- char *const *env;
-
- for (env = envp; *env != NULL; env++)
- {
- defn = (deferred *) xmalloc (sizeof *defn);
- defn->code = 'D';
- defn->value = *env;
- defn->next = head;
- head = defn;
- }
- }
-
- /* Handle deferred command line macro definitions. Must come after
- initialization of the symbol table. */
- defn = head;
- while (defn != NULL)
- {
- deferred *next;
- const char *arg = defn->value;
-
- switch (defn->code)
- {
- case 'D':
- case 'p':
- {
- m4_symbol_value *value = m4_symbol_value_create ();
-
- const char *str = strchr (arg, '=');
- size_t len = str ? str - arg : strlen (arg);
-
- m4_set_symbol_value_text (value, xstrdup (str ? str + 1 : ""),
- str ? strlen (str + 1) : 0, 0);
-
- if (defn->code == 'D')
- m4_symbol_define (M4SYMTAB, arg, len, value);
- else
- m4_symbol_pushdef (M4SYMTAB, arg, len, value);
- }
- break;
-
- case 'U':
- m4_symbol_delete (M4SYMTAB, arg, strlen (arg));
- break;
-
- case 'd':
- if (m4_debug_decode (context, arg, SIZE_MAX) < 0)
- error (0, 0, _("bad debug flags: %s"),
- quotearg_style (locale_quoting_style, arg));
- break;
-
- case 'r':
- m4_set_regexp_syntax_opt (context, m4_regexp_syntax_encode (arg));
- if (m4_get_regexp_syntax_opt (context) < 0)
- m4_error (context, EXIT_FAILURE, 0, NULL,
- _("bad syntax-spec: %s"),
- quotearg_style (locale_quoting_style, arg));
- break;
-
- case 't':
- m4_set_symbol_name_traced (M4SYMTAB, arg, strlen (arg), true);
- break;
-
- case '\1':
- if (process_file (context, arg))
- seen_file = true;
- break;
-
- case DEBUGFILE_OPTION:
- if (!m4_debug_set_output (context, NULL, arg))
- m4_error (context, 0, errno, NULL, _("cannot set debug file %s"),
- quotearg_style (locale_quoting_style,
- arg ? arg : _("stderr")));
- break;
-
- case POPDEF_OPTION:
- {
- size_t len = strlen (arg);
- if (m4_symbol_lookup (M4SYMTAB, arg, len))
- m4_symbol_popdef (M4SYMTAB, arg, len);
- }
- break;
-
- case SYNCOUTPUT_OPTION:
- {
- bool previous = m4_get_syncoutput_opt (context);
- m4_call_info info = {0};
- info.name = "--syncoutput";
- info.name_len = strlen (info.name);
- m4_set_syncoutput_opt (context,
- m4_parse_truth_arg (context, &info, arg,
- SIZE_MAX, previous));
- }
- break;
-
- case TRACEOFF_OPTION:
- m4_set_symbol_name_traced (M4SYMTAB, arg, strlen (arg), false);
- break;
-
- default:
- assert (!"INTERNAL ERROR: bad code in deferred arguments");
- abort ();
- }
-
- next = defn->next;
- free (defn);
- defn = next;
- }
-
-
- /* Interactive if specified, or if no input files and stdin and
- stderr are terminals, to match sh behavior. Interactive mode
- means unbuffered output, and interrupts ignored. */
-
- m4_set_interactive_opt (context, (interactive == INTERACTIVE_YES
- || (interactive == INTERACTIVE_UNKNOWN
- && optind == argc && !seen_file
- && isatty (STDIN_FILENO)
- && isatty (STDERR_FILENO))));
- if (m4_get_interactive_opt (context))
- {
- signal (SIGINT, SIG_IGN);
- setbuf (stdout, NULL);
- }
- else
- signal (SIGPIPE, SIG_DFL);
-
-
- /* Handle remaining input files. Each file is pushed on the input,
- and the input read. */
-
- if (optind == argc && !seen_file)
- process_file (context, "-");
- else
- for (; optind < argc; optind++)
- process_file (context, argv[optind]);
-
- /* Now handle wrapup text.
- FIXME - when -F is in effect, should wrapped text be frozen? */
- while (m4_pop_wrapup (context))
- m4_macro_expand_input (context);
-
- if (frozen_file_to_write)
- produce_frozen_state (context, frozen_file_to_write);
- else
- {
- m4_make_diversion (context, 0);
- m4_undivert_all (context);
- }
-
- /* The remaining cleanup functions systematically free all of the
- memory we still have pointers to. By definition, if there is
- anything left when we're done: it was caused by a memory leak.
- Strictly, we don't need to do this, but it makes leak detection
- a whole lot easier! */
-
- m4_output_exit ();
- m4_input_exit ();
-
- /* Change debug stream back to stderr, to force flushing the debug
- stream and detect any errors it might have encountered. The
- three standard streams are closed by close_stdin. */
- m4_debug_set_output (context, NULL, NULL);
-
- exit_status = m4_get_exit_status (context);
- m4_delete (context);
-
- m4_hash_exit ();
- quotearg_free ();
-
-#ifdef USE_STACKOVF
- stackovf_exit ();
-#endif
-
- exit (exit_status);
-}
diff --git a/src/stackovf.c b/src/stackovf.c
deleted file mode 100644
index 3d0468ab..00000000
--- a/src/stackovf.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/* Detect stack overflow (when getrlimit and sigaction or sigvec are available)
- Copyright (C) 1993-1994, 2006-2007, 2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
- Jim Avera <jima@netcom.com>, October 1993.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/* Compiled only when USE_STACKOVF is defined, which itself requires
- getrlimit with the RLIMIT_STACK option, and support for alternate
- signal stacks using either SVR4 or BSD interfaces.
-
- This should compile on ANY system which supports either sigaltstack()
- or sigstack(), with or without <siginfo.h> or another way to determine
- the fault address.
-
- There is no completely portable way to determine if a SIGSEGV signal
- indicates a stack overflow. The fault address can be used to infer
- this. However, the fault address is passed to the signal handler in
- different ways on various systems. One of three methods are used to
- determine the fault address:
-
- 1. The siginfo parameter (with siginfo.h, i.e., SVR4).
-
- 2. 4th "addr" parameter (assumed if struct sigcontext is defined,
- i.e., SunOS 4.x/BSD).
-
- 3. None (if no method is available). This case just prints a
- message before aborting with a core dump. That way the user at
- least knows that it *might* be a recursion problem.
-
- Jim Avera <jima@netcom.com> writes, on Tue, 5 Oct 93 19:27 PDT:
-
- "I got interested finding out how a program could catch and
- diagnose its own stack overflow, and ended up modifying m4 to do
- this. Now it prints a nice error message and exits.
-
- How it works: SIGSEGV is caught using a separate signal stack. The
- signal handler declares a stack overflow if the fault address is
- near the end of the stack region, or if the maximum VM address
- space limit has been reached. Otherwise, it returns to re-execute
- the instruction with SIG_DFL set, so that any real bugs cause a
- core dump as usual."
-
- Jim Avera <jima@netcom.com> writes, on Fri, 24 Jun 94 12:14 PDT:
-
- "The stack-overflow detection code would still be needed to avoid a
- SIGSEGV abort if swap space was exhausted at the moment the stack
- tried to grow. This is probably unlikely to occur with the
- explicit nesting limit option of GNU m4."
-
- Jim Avera <jima@netcom.com> writes, on Wed, 6 Jul 1994 14:41 PDT:
-
- "When a stack overflow occurs, a SIGSEGV signal is sent, which by
- default aborts the process with a core dump.
-
- The code in stackovf.c catches SIGSEGV using a separate signal
- stack. The signal handler determines whether or not the SIGSEGV
- arose from a stack overflow. If it is a stack overflow, an
- external function is called (which, in m4, prints a message an
- exits). Otherwise the SIGSEGV represents an m4 bug, and the signal
- is re-raised with SIG_DFL set, which results in an abort and core
- dump in the usual way. It seems important (to me) that internal m4
- bugs not be reported as user recursion errors, or vice-versa." */
-
-/* Define this to see runtime debug info. Implied by DEBUG. */
-/*#define DEBUG_STKOVF */
-
-#include <config.h>
-
-#include "m4.h"
-
-#ifdef USE_STACKOVF
-
-#include <sys/time.h>
-#include <sys/resource.h>
-
-#if HAVE_SIGINFO_H
-# include <siginfo.h>
-#endif
-
-#ifndef SA_RESETHAND
-# define SA_RESETHAND 0
-#endif
-#ifndef SA_SIGINFO
-# define SA_SIGINFO 0
-#endif
-
-#ifndef SIGSTKSZ
-# define SIGSTKSZ 8192
-#endif
-
-/* If the trap address is within STACKOVF_DETECT bytes of the calculated
- stack limit, we diagnose a stack overflow. This must be large enough
- to cover errors in our estimatation of the limit address, and to
- account for the maximum size of local variables (the amount the
- trapping reference might exceed the stack limit). Also, some machines
- may report an arbitrary address within the same page frame.
- If the value is too large, we might call some other SIGSEGV a stack
- overflow, masking a bug. */
-
-#ifndef STACKOVF_DETECT
-# define STACKOVF_DETECT 16384
-#endif
-
-typedef void (*handler_t) (void);
-
-#if defined __ultrix && defined __vax
-extern char *sbrk (int);
-extern int getrlimit (int, struct rlimit *);
-extern int sigstack (struct sigstack *, struct sigstack *);
-extern int sigvec (int, struct sigvec *, struct sigvec *);
-#endif
-
-static void *stackbuf;
-static const char *stackbot;
-static const char *stackend;
-static const char *arg0;
-static handler_t stackovf_handler;
-
-/* The following OS-independent procedure is called from the SIGSEGV
- signal handler. The signal handler obtains information about the trap
- in an OS-dependent manner, and passes a parameter with the meanings as
- explained below.
-
- If the OS explicitly identifies a stack overflow trap, either pass
- PARAM_STACKOVF if a stack overflow, or pass PARAM_NOSTACKOVF if not
- (id est, it is a random bounds violation). Otherwise, if the fault
- address is available, pass the fault address. Otherwise (if no
- information is available), pass NULL.
-
- Not given an explicit indication, we compare the fault address with
- the estimated stack limit, and test to see if overall VM space is
- exhausted.
-
- If a stack overflow is identified, then the external *stackovf_handler
- function is called, which should print an error message and exit. If
- it is NOT a stack overflow, then we silently abort with a core dump by
- returning to re-raise the SIGSEGV with SIG_DFL set. If indeterminate,
- then we do not call *stackovf_handler, but instead print an ambiguous
- message and abort with a core dump. This only occurs on systems which
- provide no information, but is better than nothing. */
-
-#define PARAM_STACKOVF ((const char *) (1 + STACKOVF_DETECT))
-#define PARAM_NOSTACKOVF ((const char *) (2 + STACKOVF_DETECT))
-
-static void
-process_sigsegv (int signo, const char *p)
-{
- ptrdiff_t diff;
- diff = (p - stackend);
-
-#ifdef DEBUG_STKOVF
- {
- char buf[200];
-
- sprintf (buf,
- "process_sigsegv: p=%p stackend=%p diff=%" PRIdPTR "bot=%p\n",
- p, stackend, diff, stackbot);
- write (2, buf, strlen (buf));
- }
-#endif
-
- if (p != PARAM_NOSTACKOVF)
- {
- if ((long) sbrk (8192) == (long) -1)
- {
- const char *cp;
-
- /* sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
- if the stack limit has not been reached. */
-
- /* FIXME - calling gettext inside a signal handler is
- dangerous, since it can call malloc, which is not signal
- safe. We can sort of justify it by the fact that this
- handler is designed to exit() the program, but it could
- really use a better fix. */
- cp = _("VMEM limit exceeded?\n");
- write (2, cp, strlen (cp));
- p = PARAM_STACKOVF;
- }
- if (diff >= -STACKOVF_DETECT && diff <= STACKOVF_DETECT)
- {
-
- /* The fault address is "sufficiently close" to the stack lim. */
-
- p = PARAM_STACKOVF;
- }
- if (p == PARAM_STACKOVF)
- {
-
- /* We have determined that this is indeed a stack overflow. */
-
- (*stackovf_handler) (); /* should call exit() */
- }
- }
- if (p == NULL)
- {
- const char *cp;
-
- /* FIXME - calling gettext inside a signal handler is dangerous,
- since it can call malloc, which is not signal safe. */
- cp = _("\
-Memory bounds violation detected (SIGSEGV). Either a stack overflow\n\
-occurred, or there is a bug in ");
- write (2, cp, strlen (cp));
- write (2, arg0, strlen (arg0));
- cp = _(". Check for possible infinite recursion.\n");
- write (2, cp, strlen (cp));
- }
-
- /* Return to re-execute the instruction which caused the trap with
- SIGSEGV set to SIG_DFL. An abort with core dump should occur. */
-
- signal (signo, SIG_DFL);
-}
-
-#if HAVE_STRUCT_SIGACTION_SA_SIGACTION
-
-/* POSIX. */
-
-static void
-sigsegv_handler (int signo, siginfo_t *ip, void *context)
-{
- process_sigsegv
- (signo, (ip != NULL
- && ip->si_signo == SIGSEGV ? (char *) ip->si_addr : NULL));
-}
-
-#elif HAVE_SIGINFO_T
-
-/* SVR4. */
-
-static void
-sigsegv_handler (int signo, siginfo_t *ip)
-{
- process_sigsegv
- (signo, (ip != NULL
- && ip->si_signo == SIGSEGV ? (char *) ip->si_addr : NULL));
-}
-
-#elif HAVE_SIGCONTEXT
-
-/* SunOS 4.x (and BSD?). (not tested) */
-
-static void
-sigsegv_handler (int signo, int code, struct sigcontext *scp, char *addr)
-{
- process_sigsegv (signo, addr);
-}
-
-#else /* not HAVE_SIGCONTEXT */
-
-/* OS provides no information. */
-
-static void
-sigsegv_handler (int signo)
-{
- process_sigsegv (signo, NULL);
-}
-
-#endif /* not HAVE_SIGCONTEXT */
-
-/* Arrange to trap a stack-overflow and call a specified handler. The
- call is on a dedicated signal stack.
-
- argv and envp are as passed to main.
-
- If a stack overflow is not detected, then the SIGSEGV is re-raised
- with action set to SIG_DFL, causing an abort and coredump in the usual
- way.
-
- Detection of a stack overflow depends on the trap address being near
- the stack limit address. The stack limit cannot be directly
- determined in a portable way, but we make an estimate based on the
- address of the argv and environment vectors, their contents, and the
- maximum stack size obtained using getrlimit. */
-
-void
-setup_stackovf_trap (char *const *argv, char *const *envp, handler_t handler)
-{
- struct rlimit rl;
- rlim_t stack_len;
- int grows_upward;
- register char *const *v;
- register char *p;
-#if HAVE_SIGACTION && defined SA_ONSTACK
- struct sigaction act;
-#elif HAVE_SIGVEC && defined SV_ONSTACK
- struct sigvec vec;
-#else
-
-Error - Do not know how to set up stack-ovf trap handler...
-
-#endif
-
- arg0 = argv[0];
- stackovf_handler = handler;
-
- /* Calculate the approximate expected addr for a stack-ovf trap. */
-
- if (getrlimit (RLIMIT_STACK, &rl) < 0)
- error (EXIT_FAILURE, errno, _("getrlimit"));
- stack_len = (rl.rlim_cur < rl.rlim_max ? rl.rlim_cur : rl.rlim_max);
- stackbot = (char *) argv;
- grows_upward = ((char *) &stack_len > stackbot);
- if (grows_upward)
- {
-
- /* Grows toward increasing addresses. */
-
- for (v = argv; (p = (char *) *v) != NULL; v++)
- {
- if (p < stackbot)
- stackbot = p;
- }
- if ((char *) envp < stackbot)
- stackbot = (char *) envp;
- for (v = envp; (p = (char *) *v) != NULL; v++)
- {
- if (p < stackbot)
- stackbot = p;
- }
- stackend = stackbot + stack_len;
- }
- else
- {
-
- /* The stack grows "downward" (toward decreasing addresses). */
-
- for (v = argv; (p = (char *) *v) != NULL; v++)
- {
- if (p > stackbot)
- stackbot = p;
- }
- if ((char *) envp > stackbot)
- stackbot = (char *) envp;
- for (v = envp; (p = (char *) *v) != NULL; v++)
- {
- if (p > stackbot)
- stackbot = p;
- }
- stackend = stackbot - stack_len;
- }
-
- /* Allocate a separate signal-handler stack. */
-
-#if HAVE_SIGALTSTACK && (HAVE_SIGINFO_T || ! HAVE_SIGSTACK)
-
- /* Use sigaltstack only if siginfo_t is available, unless there is no
- choice. */
-
- {
- stack_t ss;
-# ifndef HAVE_STACK_T_SS_SP
- /* This workaround is for BSD/OS 4.0.1:
- http://lists.gnu.org/archive/html/bug-m4/2006-12/msg00004.html */
-# define ss_sp ss_base
-# endif /* ! HAVE_STACK_T_SS_SP */
-
- stackbuf = xmalloc (SIGSTKSZ);
-
- ss.ss_size = SIGSTKSZ;
- ss.ss_sp = stackbuf;
- ss.ss_flags = 0;
- if (sigaltstack (&ss, NULL) < 0)
- {
- /* Oops - sigstack exists but doesn't work. We can't install
- the overflow detector, but should gracefully treat it as
- though sigstack doesn't exist. For example, this happens
- when compiled with Linux 2.1 headers but run against Linux
- 2.0 kernel. */
- free (stackbuf);
- if (errno == ENOSYS)
- return;
- error (EXIT_FAILURE, errno, _("sigaltstack"));
- }
- }
-
-#elif HAVE_SIGSTACK
-
- {
- struct sigstack ss;
- stackbuf = xmalloc (2 * SIGSTKSZ);
-
- ss.ss_sp = stackbuf + SIGSTKSZ;
- ss.ss_onstack = 0;
- if (sigstack (&ss, NULL) < 0)
- {
- /* Oops - sigstack exists but doesn't work. We can't install
- the overflow detector, but should gracefully treat it as
- though sigstack doesn't exist. For example, this happens
- when compiled with Linux 2.1 headers but run against Linux
- 2.0 kernel. */
- free (stackbuf);
- if (errno == ENOSYS)
- return;
- error (EXIT_FAILURE, errno, _("sigstack"));
- }
- }
-
-#else /* not HAVE_SIGSTACK */
-
-Error - Do not know how to set up stack-ovf trap handler...
-
-#endif /* not HAVE_SIGSTACK */
-
- /* Arm the SIGSEGV signal handler. */
-
-#if HAVE_SIGACTION && defined SA_ONSTACK
-
- sigaction (SIGSEGV, NULL, &act);
-# if HAVE_STRUCT_SIGACTION_SA_SIGACTION
- act.sa_sigaction = sigsegv_handler;
-# else /* ! HAVE_STRUCT_SIGACTION_SA_SIGACTION */
- act.sa_handler = (RETSIGTYPE (*) (int)) sigsegv_handler;
-# endif /* ! HAVE_STRUCT_SIGACTION_SA_SIGACTION */
- sigemptyset (&act.sa_mask);
- act.sa_flags = (SA_ONSTACK | SA_RESETHAND | SA_SIGINFO);
- if (sigaction (SIGSEGV, &act, NULL) < 0)
- error (EXIT_FAILURE, errno, _("sigaction"));
-
-#else /* ! HAVE_SIGACTION */
-
- vec.sv_handler = (RETSIGTYPE (*) (int)) sigsegv_handler;
- vec.sv_mask = 0;
- vec.sv_flags = (SV_ONSTACK | SV_RESETHAND);
- if (sigvec (SIGSEGV, &vec, NULL) < 0)
- error (EXIT_FAILURE, errno, _("sigvec"));
-
-#endif /* ! HAVE_SIGACTION */
-
-}
-
-void
-stackovf_exit (void)
-{
- DELETE (stackbuf);
-}
-
-#endif /* USE_STACKOVF */
diff --git a/tests/atlocal.in b/tests/atlocal.in
deleted file mode 100644
index dd6f35ee..00000000
--- a/tests/atlocal.in
+++ /dev/null
@@ -1,27 +0,0 @@
-# -*- shell-script -*-
-# @configure_input@
-# Configurable variable values for M4 test suite.
-# Copyright (C) 2000-2001, 2006, 2008, 2010, 2013-2014, 2017 Free
-# Software Foundation, Inc.
-
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# Some tests cannot be performed with all the configurations.
-USE_GMP=@USE_GMP@
-
-# Prefer tools learned during configure.
-SED='@SED@'
-export SED
diff --git a/tests/builtins.at b/tests/builtins.at
deleted file mode 100644
index ab8fa9f6..00000000
--- a/tests/builtins.at
+++ /dev/null
@@ -1,1325 +0,0 @@
-# Hand crafted tests for GNU M4. -*- Autotest -*-
-# Copyright (C) 2001, 2006-2010, 2013-2014, 2017 Free Software
-# Foundation, Inc.
-
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-AT_BANNER([Torturing builtins.])
-
-
-## -------- ##
-## __file__ ##
-## -------- ##
-
-AT_SETUP([__@&t@file__])
-
-dnl Unfortunately, AT_DATA does not make it easy to create files without
-dnl a trailing newline.
-[echo $ECHO_N "__line"__:__"file__$ECHO_C"] > nested
-AT_DATA([outer],
-[[__file__:__line__
-include(`nested')
-__file__:__line__
-]])
-
-dnl Make sure line numbers are consistent, even if include file does not
-dnl end with a newline
-AT_CHECK_M4([outer], [0],
-[[outer:1
-1:nested
-outer:3
-]])
-
-AT_CLEANUP
-
-
-## -------- ##
-## __line__ ##
-## -------- ##
-
-AT_SETUP([__@&t@line__])
-
-dnl Unfortunately, AT_DATA does not make it easy to create files without
-dnl a trailing newline.
-[echo $ECHO_N "__file"__:__"line__$ECHO_C"] > nested
-AT_DATA([outer],
-[[__file__:__line__
-include(`nested')
-__file__:__line__
-]])
-
-dnl Make sure line numbers are consistent, even if include file does not
-dnl end with a newline
-AT_CHECK_M4([outer], [0],
-[[outer:1
-nested:1
-outer:3
-]])
-
-AT_CLEANUP
-
-
-## -------------- ##
-## __m4_version__ ##
-## -------------- ##
-
-AT_SETUP([__m4_@&t@version__])
-
-AT_DATA([in], [[defn(`__m4_version__')
-]])
-AT_CHECK_M4([--version], [0], [stdout])
-AT_CHECK([[$SED -e 's/.*(GNU M4\(.*\)) \([^ ]*\).*/\2\1/;q' < stdout]],
-[0], [stdout])
-mv stdout expout
-AT_CHECK_M4([in], [0], [expout])
-
-dnl Prove that __m4_version__ is unquoted, by making '.' an active character.
-AT_DATA([in], [[changesyntax(`A.')define(`.', `errprint(`hi
-')undefine(`.').')dnl
-__m4_version__
-]])
-AT_CHECK_M4([in], [0], [expout], [[hi
-]])
-
-AT_CLEANUP
-
-
-## ------- ##
-## builtin ##
-## ------- ##
-
-AT_SETUP([builtin])
-
-dnl This was a regression in 1.4.10b.
-AT_DATA([in.m4],
-[[define(`s', `builtin(`shift', $@)')dnl
-define(`loop', `ifelse(`$2', `', `-', `$1$2: $0(`$1', s(s($@)))')')dnl
-loop(`1')
-loop(`1', `2')
-loop(`1', `2', `3')
-loop(`1', `2', `3', `4')
-loop(`1', `2', `3', `4', `5')
-]])
-AT_CHECK_M4([in.m4], [0],
-[[-
-12: -
-12: 13: -
-12: 13: 14: -
-12: 13: 14: 15: -
-]])
-
-AT_CLEANUP
-
-
-## ----------- ##
-## changequote ##
-## ----------- ##
-
-AT_SETUP([changequote])
-
-AT_DATA([in.m4],
-[[define(`aaaaaaaaaaaaaaaaaaaa', `A')define(`q', `"$@"')
-changequote(`"', `"')
-q(q("aaaaaaaaaaaaaaaaaaaa", "a"))
-changequote`'define(`echo', `$@')dnl
-changequote(`<<<', `>>')dnl
-echo(<<<a<<<b>>>>)
-]])
-
-AT_CHECK_M4([in.m4], [0], [[
-
-A,a
-a<<<b>>
-]])
-
-AT_CLEANUP
-
-
-## ----- ##
-## debug ##
-## ----- ##
-
-AT_SETUP([debug])
-
-AT_DATA([[debug.m4]],
-[[define(`countdown', `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Liftoff')')
-debugmode(`aeqc')
-traceon(`countdown')
-countdown(2)
-]])
-
-AT_DATA([[expout]],
-[[
-
-
-2 1 0 Liftoff
-]])
-
-AT_DATA([[experr]],
-[[m4trace: -1- countdown ... = `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Liftoff')'
-m4trace: -1- countdown(`2') -> `2 ifelse(eval(2 > 0), 1, `countdown(decr(2))', `Liftoff')'
-m4trace: -1- countdown ... = `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Liftoff')'
-m4trace: -1- countdown(`1') -> `1 ifelse(eval(1 > 0), 1, `countdown(decr(1))', `Liftoff')'
-m4trace: -1- countdown ... = `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Liftoff')'
-m4trace: -1- countdown(`0') -> `0 ifelse(eval(0 > 0), 1, `countdown(decr(0))', `Liftoff')'
-]])
-
-AT_CHECK_M4([debug.m4], 0, expout, experr)
-
-dnl Test a regression introduced 2008-05-08, fixed 2008-07-30.
-AT_DATA([debug.m4], [[debugmode(`e')traceon(`ifelse')dnl
-define(`e', `ifelse(`$1', `$2', `ifelse(`$1', `$2', `e(shift($@))')', `$2')')
-e(`1', `1', `a')
-]])
-
-AT_CHECK_M4([debug.m4], [0], [[
-a
-]], [[m4trace: -1- ifelse -> ifelse(`1', `1', `e(shift(`1',`1',`a'))')
-m4trace: -1- ifelse -> e(shift(`1',`1',`a'))
-m4trace: -1- ifelse -> a
-]])
-
-AT_CLEANUP
-
-
-## ------ ##
-## define ##
-## ------ ##
-
-AT_SETUP([define])
-
-AT_DATA([[define.m4]],
-[[undefine(`macro')dnl
-pushdef(`macro', `base value')dnl
-pushdef(`macro', `hello, world')dnl
-pushdef(`macro', `top value')dnl
-define(`macro', `new value')dnl
-macro.
-popdef(`macro')dnl
-macro.
-popdef(`macro')dnl
-macro.
-]])
-
-AT_CHECK_M4([define.m4], 0,
-[[new value.
-hello, world.
-base value.
-]], [[m4:define.m4:1: warning: undefine: undefined macro 'macro'
-]])
-
-AT_CHECK_M4([--traditional define.m4], 0,
-[[new value.
-hello, world.
-base value.
-]], [[m4:define.m4:1: warning: undefine: undefined macro 'macro'
-]])
-
-dnl check regression present 2008-02-22 to 2008-04-30.
-AT_DATA([in.m4], [[define(`qq', ``$*;$@'')dnl
-define(`foo', qq(`a', `b'))dnl
-foo
-defn(`foo')
-]])
-AT_CHECK_M4([in.m4], [0], [[a,b;a,b
-a,b;`a',`b'
-]])
-
-dnl Check hashing performance.
-AT_DATA([in.m4], [[include(`forloop3.m4')dnl
-forloop(`i', `1', `10000', `define(`m'i, i)')m10000
-forloop(`i', `1', `10000', `undefine(`m'i)')m10000
-]])
-AT_CHECK_M4([-I "$abs_top_srcdir/doc/examples" in.m4], [0], [[10000
-m10000
-]])
-
-AT_CLEANUP
-
-
-
-## ---- ##
-## defn ##
-## ---- ##
-
-AT_SETUP([defn])
-
-AT_DATA([[in.m4]],
-[[define(`e', `$@')define(`q', ``$@'')define(`u', `$*')
-define(`cmp', `ifelse($1, $2, `yes', `no')')define(`d', defn(`defn'))
-cmp(`defn(`defn')', `defn(`d')')
-cmp(`defn(`defn')', ``<defn>'')
-cmp(`q(defn(`defn'))', `q(defn(`d'))')
-cmp(`q(defn(`defn'))', `q(`<defn>')')
-cmp(`q(defn(`defn'))', ``'')
-cmp(`q(`1', `2', defn(`defn'))', `q(`1', `2', defn(`d'))')
-cmp(`q(`1', `2', defn(`defn'))', `q(`1', `2', `<defn>')')
-cmp(`q(`1', `2', defn(`defn'))', ```1',`2',<defn>'')
-cmp(`q(`1', `2', defn(`defn'))', ```1',`2',`''')
-define(`cat', `$1`'ifelse(`$@%:@', `1', `', `$0(shift($@))')')
-cat(`define(`foo',', defn(`divnum'), `)foo')
-cat(e(`define(`bar',', defn(`divnum'), `)bar'))
-m4wrap(`u('q(`cat(`define(`baz','', defn(`divnum'), ``)baz')')`)
-')
-]])
-
-AT_CHECK_M4([in.m4], [0], [[
-
-yes
-no
-yes
-no
-no
-yes
-no
-no
-no
-
-0
-0
-
-0
-]])
-
-AT_CLEANUP
-
-
-## ------ ##
-## divert ##
-## ------ ##
-
-AT_SETUP([divert])
-
-AT_DATA([[divert.m4]],
-[[divert(1)Text diverted a first time.
-divert(0)undivert(1)dnl
-divert(1)Text diverted a second time.
-divert(0)undivert(1)dnl
-]])
-
-AT_CHECK_M4([divert.m4], 0,
-[[Text diverted a first time.
-Text diverted a second time.
-]])
-
-dnl Test second divert argument, added for m4 2.0
-AT_DATA([in.m4], [[define(`echo',`$1')dnl
-divert(`-1', `discarded without warning')
-divert`'dnl
-echo(` world'divert(divnum, `hello'))
-]])
-
-AT_CHECK_M4([-s in.m4], [0], [[#line 4 "in.m4"
-hello world
-]])
-
-dnl Test large diversions, which were broken in m4 1.4.8-1.4.10.
-dnl Hopefully $SED doesn't choke on the over-long second line.
-AT_CHECK([echo 'divert(1)hi
-format(%1000000d, 1)' | $M4 | $SED -n 1p], [0], [[hi
-]])
-
-AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(`2')f`'dnl
-divert(`1')hello
-divert(`3')goodbye
-]])
-
-dnl Rather than open-code the 1 megabyte expected output, we reduce the
-dnl size of testsuite by constructing it.
-AT_DATA([expout], [[
-]])
-cat expout expout > expout2
-cat expout2 expout2 > expout
-cat expout expout > expout2
-cat expout2 expout2 > expout
-cat expout expout > expout2
-cat expout2 expout2 > expout
-cat expout expout > expout2
-cat expout2 expout2 > expout
-cat expout expout > expout2
-cat expout2 expout2 > expout
-cat expout expout > expout2
-cat expout2 expout2 > expout
-cat expout expout > expout2
-cat expout2 expout2 > expout
-cat expout expout > expout2
-cat expout2 expout2 > expout
-cat expout expout > expout2
-cat expout2 expout2 > expout
-cat expout expout > expout2 # 512 kilobytes
-echo hello > expout
-cat expout2 expout2 >> expout # 1 megabyte
-echo goodbye >> expout
-rm expout2
-
-AT_CHECK_M4([in.m4], [0], [expout])
-
-dnl Avoid quadratic copying time when transferring diversions; test
-dnl both in-memory and diversions spilled to a file.
-AT_DATA([in.m4], [[include(`forloop2.m4')dnl
-divert(`1')format(`%10000s', `')dnl
-forloop(`i', `1', `10000',
- `divert(incr(i))undivert(i)')dnl
-divert(`9001')format(`%1000000s', `')dnl
-forloop(`i', `9001', `10000',
- `divert(incr(i))undivert(i)')dnl
-divert(`-1')undivert
-]])
-
-AT_CHECK_M4([-I "$abs_top_srcdir/doc/examples" in.m4])
-
-AT_CLEANUP
-
-
-## --- ##
-## dnl ##
-## --- ##
-
-AT_SETUP([d@&t@nl])
-
-dnl Unfortunately, AT_DATA does not make it easy to create files without
-dnl a trailing newline.
-[echo $ECHO_N "__file"__:__"line__ d""nl ignored$ECHO_C"] > nested
-AT_DATA([outer],
-[[__file__:__line__
-include(`nested') still ignored
-__file__:__line__
-define(`foo', `dnl
-__file__:__line__ include(`nested') ignored
-dnl')dnl
-foo ignored
-__file__:__line__
-]])
-
-dnl Make sure line numbers are consistent, even if include file does not
-dnl end with a newline
-AT_CHECK_M4([outer], [0],
-[[outer:1
-nested:1 outer:3
-outer:7 nested:1 outer:8
-]])
-
-AT_CLEANUP
-
-
-## ------- ##
-## dumpdef ##
-## ------- ##
-
-AT_SETUP([dumpdef])
-
-dnl Make sure that stderr and stdout are properly interleaved when directed
-dnl to the same file.
-AT_DATA([in], [[1dumpdef(`defn')3
-]])
-AT_CHECK_M4([in], [0], [[13
-]], [[defn: <defn>
-]])
-AT_CHECK_M4([in 2>&1], [0], [[1defn: <defn>
-3
-]])
-
-AT_CLEANUP
-
-
-## -------- ##
-## errprint ##
-## -------- ##
-
-AT_SETUP([errprint])
-
-dnl Make sure that stderr and stdout are properly interleaved when directed
-dnl to the same file.
-AT_DATA([in], [[1errprint(`2')3errprint(`
-')
-]])
-AT_CHECK_M4([in], [0], [[13
-]], [[2
-]])
-AT_CHECK_M4([in 2>&1], [0], [[123
-
-]])
-
-AT_CLEANUP
-
-
-## ------- ##
-## esyscmd ##
-## ------- ##
-
-AT_SETUP([esyscmd])
-
-AT_DATA([[esyscmd.m4]],
-[[# Cannot use real hostname program because test would fail
-define(`hostname', esyscmd(`echo www.gnu.org'))dnl
-`hostname = >>'hostname`<<'
-define(`hostname',
-pushdef(`_tmp', `$1')_tmp(translit(esyscmd(`echo www.gnu.org'), `.', `,'))`'popdef(`_tmp'))dnl
-`hostname = >>'hostname`<<'
-]])
-
-AT_CHECK_M4([esyscmd.m4], 0,
-[[# Cannot use real hostname program because test would fail
-hostname = >>www.gnu.org
-<<
-hostname = >>www<<
-]])
-
-dnl Ensure that esyscmd does not inherit any unnecessary fds from trace.
-AT_DATA([in.m4], [[esyscmd(`echo hi >&3')ifelse(sysval,
-`0', `skipping: sh cannot detect closed fds
-m4exit(`77')')dnl
-]])
-AT_CHECK_M4([3>&-], [0], [], [stderr], [in.m4])
-mv stderr experr
-AT_CHECK_M4([--debugfile=trace -tdnl 3>&-], [0], [], [experr], [in.m4])
-AT_CHECK([cat trace], [0], [[m4trace: -1- dnl -> `'
-]])
-
-dnl Ensure that esyscmd does not inherit any unnecessary fds from diversions.
-AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(`1')f
-world
-esyscmd(`echo hi >&3')divert
-hello
-]])
-AT_CHECK_M4([3>&-], [0], [stdout-nolog], [experr], [in.m4])
-AT_CHECK([$SED -ne '/./p' stdout], [0], [[hello
-world
-]])
-
-dnl Ensure that esyscmd does not inherit any unnecessary fds from input files.
-AT_DATA([in.m4], [[hello esyscmd(`cat <&3')dnl
-dnl this line should not be read by cat
-world
-]])
-AT_CHECK_M4([3>&-], [0], [[hello world
-]], [stderr], [in.m4])
-mv stderr experr
-AT_CHECK_M4([in.m4 3>&-], [0], [[hello world
-]], [experr])
-
-AT_CLEANUP
-
-
-## ------ ##
-## ifelse ##
-## ------ ##
-
-AT_TEST_M4([ifelse],
-dnl ensure that comparisons work regardless of reference chains in the middle
-[[define(`e', `$@')define(`long', `01234567890123456789')
-dnl in isolation
-ifelse(long, `01234567890123456789', `yes', `no')
-ifelse(`01234567890123456789', long, `yes', `no')
-ifelse(long, `01234567890123456789-', `yes', `no')
-ifelse(`01234567890123456789-', long, `yes', `no')
-dnl through macro expansion
-ifelse(e(long), `01234567890123456789', `yes', `no')
-ifelse(`01234567890123456789', e(long), `yes', `no')
-ifelse(e(long), `01234567890123456789-', `yes', `no')
-ifelse(`01234567890123456789-', e(long), `yes', `no')
-dnl concatenate macro expansion with unquoted characters
-ifelse(-e(long), `-01234567890123456789', `yes', `no')
-ifelse(-`01234567890123456789', -e(long), `yes', `no')
-ifelse(-e(long), `-01234567890123456789-', `yes', `no')
-ifelse(`-01234567890123456789-', -e(long), `yes', `no')
-ifelse(-e(long)-, `-01234567890123456789-', `yes', `no')
-ifelse(-`01234567890123456789-', -e(long)-, `yes', `no')
-ifelse(-e(long)-, `-01234567890123456789', `yes', `no')
-ifelse(`-01234567890123456789', -e(long)-, `yes', `no')
-dnl concatenate macro expansion with quoted characters
-ifelse(`-'e(long), `-01234567890123456789', `yes', `no')
-ifelse(-`01234567890123456789', `-'e(long), `yes', `no')
-ifelse(`-'e(long), `-01234567890123456789-', `yes', `no')
-ifelse(`-01234567890123456789-', `-'e(long), `yes', `no')
-ifelse(`-'e(long)`-', `-01234567890123456789-', `yes', `no')
-ifelse(-`01234567890123456789-', `-'e(long)`-', `yes', `no')
-ifelse(`-'e(long)`-', `-01234567890123456789', `yes', `no')
-ifelse(`-01234567890123456789', `-'e(long)`-', `yes', `no')
-]], [[
-yes
-yes
-no
-no
-yes
-yes
-no
-no
-yes
-yes
-no
-no
-yes
-yes
-no
-no
-yes
-yes
-no
-no
-yes
-yes
-no
-no
-]])
-
-
-## ------- ##
-## include ##
-## ------- ##
-
-AT_SETUP([include])
-
-AT_DATA([[include.m4]],
-[[Beginning.
-include(`NOFILE')
-Intermediate
-include(`incl-test.m4')
-After
-include(`NOFILE')
-very late
-]])
-
-AT_DATA([[incl-test.m4]],
-[[dnl noauto
-`include test file.'
-define()
-]])
-
-AT_DATA([[expout]],
-[[Beginning.
-
-Intermediate
-include test file.
-
-
-After
-
-very late
-]])
-
-AT_DATA([[experr]],
-[[m4:include.m4:2: include: cannot open file 'NOFILE': No such file or directory
-m4:include.m4:6: include: cannot open file 'NOFILE': No such file or directory
-]])
-
-AT_CHECK_M4([include.m4], 1, expout, experr)
-
-dnl make sure files are handled correctly even via builtin
-AT_DATA([foo], [[bar
-]])
-AT_DATA([in], [[builtin(`include', `foo')dnl
-]])
-
-AT_CHECK_M4([in], [0], [[bar
-]])
-
-AT_CLEANUP
-
-
-
-## ----- ##
-## index ##
-## ----- ##
-
-AT_SETUP([index])
-
-dnl This used to be quadratic, taking millions of comparisons,
-dnl but should now operate in linear time with only several thousand checks.
-AT_DATA([in], [M4_ONE_MEG_DEFN[dnl
-index(substr(f, `0', `500000')-, substr(f, `0', `100000')-)
-]])
-AT_CHECK_M4([in], [0], [[400000
-]])
-
-dnl This validates that index is 8-bit safe.
-AT_DATA([in], [[index(`1«2', `»')
-index(`1«2', `«')
-index(`1«2', `«1')
-index(`1«2', `«2')
-]])
-AT_CHECK_M4([in], [0], [[-1
-1
--1
-1
-]])
-
-AT_CLEANUP
-
-
-
-## ----- ##
-## indir ##
-## ----- ##
-
-AT_SETUP([indir])
-
-AT_DATA([[indir.m4]],
-[[define(`%%$$##', `>>>$0<<< cnt $#')
-
-# indir(`%%$$##', nonsense, nonsense)
-indir(`%%$$##', nonsense, nonsense)
-
-# indir(`indir', `%%$$##', nonsense)
-indir(`indir', `%%$$##', nonsense)
-
-# indir(`indir', `indir', `indir', `indir', `%%$$##')
-indir(`indir', `indir', `indir', `indir', `%%$$##')
-]])
-
-AT_DATA([[expout]],
-[[
-
-# indir(`%%$$##', nonsense, nonsense)
->>>%%$$##<<< cnt 2
-
-# indir(`indir', `%%$$##', nonsense)
->>>%%$$##<<< cnt 1
-
-# indir(`indir', `indir', `indir', `indir', `%%$$##')
->>>%%$$##<<< cnt 0
-]])
-
-AT_CHECK_M4([indir.m4], 0, expout)
-
-AT_CLEANUP
-
-
-## ------ ##
-## m4exit ##
-## ------ ##
-
-AT_SETUP([m4exit])
-
-dnl Ensure that spilled diversions are gracefully cleaned up
-AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(`1')f
-m4exit
-]])
-AT_CHECK([rm -Rf tmpdir && mkdir tmpdir && test -d tmpdir])
-TMPDIR=tmpdir
-export TMPDIR
-AT_CHECK_M4([in.m4], [0])
-AT_CHECK([rmdir tmpdir])
-
-AT_CLEANUP
-
-
-## ------- ##
-## mkdtemp ##
-## ------- ##
-
-AT_SETUP([mkdtemp])
-
-dnl Check that on error, the expansion is void
-AT_DATA([[in]],
-[[mkdtemp(`no_such_dir/m4-fooXXXXXX')
-]])
-AT_CHECK_M4([in], [0], [[
-]], [[m4:in:1: warning: mkdtemp: cannot create directory from template 'no_such_dir/m4-fooXXXXXX': No such file or directory
-]])
-
-dnl Check that umask has an effect. drws--S--T is okay.
-AT_DATA([[in]],
-[[translit(substr(esyscmd(`ls -ld 'mkdtemp(`m4-fooXXXXXX')), `0', `10'),
- `SsT', `-x-')
-]])
-AT_CHECK([$M4 < in], [0], [[drwx------
-]])
-AT_CHECK([umask 700; $M4 < in], [0], [[d---------
-]])
-
-AT_CLEANUP
-
-
-## -------- ##
-## maketemp ##
-## -------- ##
-
-AT_SETUP([mkstemp])
-
-AT_KEYWORDS([maketemp])
-
-dnl Check that on error, the expansion is void
-AT_DATA([[in]],
-[[mkstemp(`no_such_dir/m4-fooXXXXXX')
-]])
-AT_CHECK_M4([in], [0], [[
-]], [[m4:in:1: warning: mkstemp: cannot create file from template 'no_such_dir/m4-fooXXXXXX': No such file or directory
-]])
-
-dnl Check that extra X are appended, but not trailing NUL
-AT_DATA([[in]], [[len(mkstemp(`m4-fooXXXXX'))
-]])
-AT_CHECK_M4([in], [0], [[12
-]])
-
-dnl Check that umask has an effect
-AT_DATA([[in]],
-[[substr(esyscmd(`ls -ld 'mkstemp(`m4-fooXXXXXX')), `0', `10')
-]])
-AT_CHECK([$M4 < in], [0], [[-rw-------
-]])
-AT_CHECK([umask 700; $M4 < in], [0], [[----------
-]])
-
-dnl Check for Solaris compatibility of maketemp. Hopefully the pid is
-dnl less than 20 decimal digits. Also check that --safer does not affect
-dnl traditional behavior of maketemp, which is textual only.
-AT_DATA([[in]],
-[[maketemp()
-maketemp(X)
-maketemp(XX)
-maketemp(XXXXXXXXXXXXXXXXXXXXX)
-maketemp(no_such_dir/XXXXXX)
-]])
-dnl Abuse our knowledge of AT_CHECK_M4 so that we can get stderr filtering...
-AT_CHECK_M4([-G -Q --safer], [0], [stdout], [],
-[in& echo $! > pid; wait $!])
-pid=`cat pid`
-cat >expout <<EOF
-
-X
-X`$SED -e 's/.*\(.\)$/\1/' pid`
-X`echo "$pid" | $SED -e "s/.*/00000000000000000000&/" -e 's/.*\(.\{20\}$\)/\1/'`
-no_such_dir/`echo "$pid" | $SED -e "s/.*/000000&/" -e 's/.*\(.\{6\}$\)/\1/'`
-EOF
-AT_CHECK([cat stdout], [0], [expout])
-
-AT_CLEANUP
-
-
-## ------ ##
-## mpeval ##
-## ------ ##
-
-AT_SETUP([mpeval])
-AT_CHECK_GMP
-
-AT_DATA([[in]],
-[[divert(-1)
-# forloop(i, from, to, stmt)
-
-define(`forloop', `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
-define(`_forloop',
- `$4`'ifelse($1, `$3', ,
- `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
-divert
-forloop(`x', 1, 100, `2**x = mpeval(2**x)
-')
-]])
-
-AT_DATA([[expout]],
-[[
-2**1 = 2
-2**2 = 4
-2**3 = 8
-2**4 = 16
-2**5 = 32
-2**6 = 64
-2**7 = 128
-2**8 = 256
-2**9 = 512
-2**10 = 1024
-2**11 = 2048
-2**12 = 4096
-2**13 = 8192
-2**14 = 16384
-2**15 = 32768
-2**16 = 65536
-2**17 = 131072
-2**18 = 262144
-2**19 = 524288
-2**20 = 1048576
-2**21 = 2097152
-2**22 = 4194304
-2**23 = 8388608
-2**24 = 16777216
-2**25 = 33554432
-2**26 = 67108864
-2**27 = 134217728
-2**28 = 268435456
-2**29 = 536870912
-2**30 = 1073741824
-2**31 = 2147483648
-2**32 = 4294967296
-2**33 = 8589934592
-2**34 = 17179869184
-2**35 = 34359738368
-2**36 = 68719476736
-2**37 = 137438953472
-2**38 = 274877906944
-2**39 = 549755813888
-2**40 = 1099511627776
-2**41 = 2199023255552
-2**42 = 4398046511104
-2**43 = 8796093022208
-2**44 = 17592186044416
-2**45 = 35184372088832
-2**46 = 70368744177664
-2**47 = 140737488355328
-2**48 = 281474976710656
-2**49 = 562949953421312
-2**50 = 1125899906842624
-2**51 = 2251799813685248
-2**52 = 4503599627370496
-2**53 = 9007199254740992
-2**54 = 18014398509481984
-2**55 = 36028797018963968
-2**56 = 72057594037927936
-2**57 = 144115188075855872
-2**58 = 288230376151711744
-2**59 = 576460752303423488
-2**60 = 1152921504606846976
-2**61 = 2305843009213693952
-2**62 = 4611686018427387904
-2**63 = 9223372036854775808
-2**64 = 18446744073709551616
-2**65 = 36893488147419103232
-2**66 = 73786976294838206464
-2**67 = 147573952589676412928
-2**68 = 295147905179352825856
-2**69 = 590295810358705651712
-2**70 = 1180591620717411303424
-2**71 = 2361183241434822606848
-2**72 = 4722366482869645213696
-2**73 = 9444732965739290427392
-2**74 = 18889465931478580854784
-2**75 = 37778931862957161709568
-2**76 = 75557863725914323419136
-2**77 = 151115727451828646838272
-2**78 = 302231454903657293676544
-2**79 = 604462909807314587353088
-2**80 = 1208925819614629174706176
-2**81 = 2417851639229258349412352
-2**82 = 4835703278458516698824704
-2**83 = 9671406556917033397649408
-2**84 = 19342813113834066795298816
-2**85 = 38685626227668133590597632
-2**86 = 77371252455336267181195264
-2**87 = 154742504910672534362390528
-2**88 = 309485009821345068724781056
-2**89 = 618970019642690137449562112
-2**90 = 1237940039285380274899124224
-2**91 = 2475880078570760549798248448
-2**92 = 4951760157141521099596496896
-2**93 = 9903520314283042199192993792
-2**94 = 19807040628566084398385987584
-2**95 = 39614081257132168796771975168
-2**96 = 79228162514264337593543950336
-2**97 = 158456325028528675187087900672
-2**98 = 316912650057057350374175801344
-2**99 = 633825300114114700748351602688
-2**100 = 1267650600228229401496703205376
-
-]])
-
-AT_CHECK_M4([mpeval in], 0, expout)
-
-AT_CLEANUP
-
-
-
-## ----------- ##
-## multiquotes ##
-## ----------- ##
-
-AT_SETUP([multiquotes])
-
-AT_DATA([[multiquotes.m4]],
-[[traceon
-changequote([,])dnl
-changequote([``], [''])dnl
-````traceon''''
-define(``foo'', ````FOO'''')dnl
-dumpdef(``foo'')dnl
-changequote(``!'', ``!'')dnl
-!foo!
-foo
-dumpdef(!foo!)dnl
-define(!bar!, !BAR!)
-bar
-changequote(!>*>*>*>*>!, !<*<*<*<*<!)dnl five of each
->*>*>*>*>foo bar<*<*<*<*<
-foo bar
->*>*>*>*>*>*><*<*<*<*<*<*<
-dumpdef(>*>*>*>*>foo<*<*<*<*<, >*>*>*>*>bar<*<*<*<*<)dnl
-]])
-
-AT_DATA([[expout]],
-[[
-``traceon''
-foo
-``FOO''
-
-BAR
-foo bar
-``FOO'' BAR
-*>*>*<*<
-]])
-
-AT_DATA([[experr]],
-[[m4trace: -1- changequote(`[', `]') -> []
-m4trace: -1- dnl -> []
-m4trace: -1- changequote([``], ['']) -> ``''
-m4trace: -1- dnl -> ``''
-m4trace: -1- define(``foo'', ````FOO'''') -> ``''
-m4trace: -1- dnl -> ``''
-foo: ````FOO''''
-m4trace: -1- dumpdef(``foo'') -> ``''
-m4trace: -1- dnl -> ``''
-m4trace: -1- changequote(``!'', ``!'') -> !!
-m4trace: -1- dnl -> !!
-m4trace: -1- foo -> !``FOO''!
-foo: !``FOO''!
-m4trace: -1- dumpdef(!foo!) -> !!
-m4trace: -1- dnl -> !!
-m4trace: -1- define(!bar!, !BAR!) -> !!
-m4trace: -1- bar -> !BAR!
-m4trace: -1- changequote(!>*>*>*>*>!, !<*<*<*<*<!) -> >*>*>*>*><*<*<*<*<
-m4trace: -1- dnl -> >*>*>*>*><*<*<*<*<
-m4trace: -1- foo -> >*>*>*>*>``FOO''<*<*<*<*<
-m4trace: -1- bar -> >*>*>*>*>BAR<*<*<*<*<
-bar: >*>*>*>*>BAR<*<*<*<*<
-foo: >*>*>*>*>``FOO''<*<*<*<*<
-m4trace: -1- dumpdef(>*>*>*>*>foo<*<*<*<*<, >*>*>*>*>bar<*<*<*<*<) -> >*>*>*>*><*<*<*<*<
-m4trace: -1- dnl -> >*>*>*>*><*<*<*<*<
-]])
-
-AT_CHECK_M4([multiquotes.m4], 0, expout, experr)
-
-AT_CLEANUP
-
-
-
-## -------- ##
-## patsubst ##
-## -------- ##
-
-AT_SETUP([patsubst])
-
-AT_DATA([[patsubst.m4]],
-[[# traceon(`patsubst')
-patsubst(`GNUs not Unix.', `^', `OBS: ')
-patsubst(`GNUs not Unix.', `\<', `OBS: ')
-patsubst(`GNUs not Unix.', `\<\w', `\&=')
-patsubst(`GNUs not Unix.', `\w*', `(\&)')
-patsubst(`GNUs not Unix.', `\w+', `(\&)')
-patsubst(`GNUs not Unix.', `\w+')
-patsubst(`GNUs not '` Unix.', `[ ]+', ` ')
-]])
-
-AT_DATA([[expout]],
-[[# traceon(`patsubst')
-OBS: GNUs not Unix.
-OBS: GNUs OBS: not OBS: Unix.
-G=NUs n=ot U=nix.
-(GNUs)() (not)() (Unix)().()
-(GNUs) (not) (Unix).
- .
-GNUs not Unix.
-]])
-
-AT_CHECK_M4([patsubst.m4], 0, expout)
-
-AT_CLEANUP
-
-
-
-## ------ ##
-## regexp ##
-## ------ ##
-
-AT_SETUP([regexp])
-
-AT_DATA([[regexp.m4]],
-[[traceon(`regexp')dnl
-regexp(`hej med dig', `.*', `>>\&<<')
-regexp(`hej med dig', `\w*', `>>\&<<')
-regexp(`hej med dig', `.+', `>>\&<<')
-regexp(`hej med dig', `m\w+', `>>\&<<')
-regexp(`hej med dig', `m\(.*\)', `>>\&<< >>\1<<')
-
-regexp(`hej med dig', `.*')
-regexp(`hej med dig', `\w*')
-regexp(`hej med dig', `.+')
-regexp(`hej med dig', `m\w+')
-regexp(`hej med dig', `m\(.*\)')
-]])
-
-AT_DATA([[expout]],
-[[>>hej med dig<<
->>hej<<
->>hej med dig<<
->>med<<
->>med dig<< >>ed dig<<
-
-0
-0
-0
-4
-4
-]])
-
-AT_DATA([[experr]],
-[[m4trace: -1- regexp(`hej med dig', `.*', `>>\&<<') -> `>>hej med dig<<'
-m4trace: -1- regexp(`hej med dig', `\w*', `>>\&<<') -> `>>hej<<'
-m4trace: -1- regexp(`hej med dig', `.+', `>>\&<<') -> `>>hej med dig<<'
-m4trace: -1- regexp(`hej med dig', `m\w+', `>>\&<<') -> `>>med<<'
-m4trace: -1- regexp(`hej med dig', `m\(.*\)', `>>\&<< >>\1<<') -> `>>med dig<< >>ed dig<<'
-m4trace: -1- regexp(`hej med dig', `.*') -> `0'
-m4trace: -1- regexp(`hej med dig', `\w*') -> `0'
-m4trace: -1- regexp(`hej med dig', `.+') -> `0'
-m4trace: -1- regexp(`hej med dig', `m\w+') -> `4'
-m4trace: -1- regexp(`hej med dig', `m\(.*\)') -> `4'
-]])
-
-AT_CHECK_M4([regexp.m4], 0, expout, experr)
-
-AT_CLEANUP
-
-
-
-## ------------ ##
-## sync-lines. ##
-## ------------ ##
-
-AT_SETUP([sync-lines])
-
-AT_DATA([[in]],
-[[syncoutput(on)dnl
-# Several input lines, expanding to one
-define(`foo', ``foo' line one.
-`foo' line two.
-`foo' line three.') xyz
-foo
-# Several input lines, expanding to none
-define(`foo', ``foo' line one.
-`foo' line two.
-`foo' line three.')dnl
-# one input line, expanding to several output lines
-foo foo
-]])
-
-AT_CHECK_M4([[in]], 0,
-[[#line 2 "in"
-# Several input lines, expanding to one
-#line 5
- xyz
-foo line one.
-#line 6
-foo line two.
-#line 6
-foo line three.
-# Several input lines, expanding to none
-#line 11
-# one input line, expanding to several output lines
-foo line one.
-#line 12
-foo line two.
-#line 12
-foo line three. foo line one.
-#line 12
-foo line two.
-#line 12
-foo line three.
-]])
-
-AT_CLEANUP
-
-
-## ------ ##
-## syscmd ##
-## ------ ##
-
-AT_SETUP([syscmd])
-
-dnl Ensure that syscmd does not inherit any unnecessary fds from trace.
-AT_DATA([in.m4], [[syscmd(`echo hi >&3')ifelse(sysval,
-`0', `skipping: sh cannot detect closed fds
-m4exit(`77')')dnl
-]])
-AT_CHECK_M4([3>&-], [0], [], [stderr], [in.m4])
-mv stderr experr
-AT_CHECK_M4([--debugfile=trace -tdnl 3>&-], [0], [], [experr], [in.m4])
-AT_CHECK([cat trace], [0], [[m4trace: -1- dnl -> `'
-]])
-
-dnl Ensure that syscmd does not inherit any unnecessary fds from diversions.
-AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(`1')f
-world
-syscmd(`echo hi >&3')divert
-hello
-]])
-AT_CHECK_M4([3>&-], [0], [stdout-nolog], [experr], [in.m4])
-AT_CHECK([$SED -ne '/./p' stdout], [0], [[hello
-world
-]])
-
-dnl Ensure that syscmd does not inherit any unnecessary fds from input files.
-AT_DATA([in.m4], [[hello syscmd(`cat <&3')dnl
-dnl this line should not be read by cat
-world
-]])
-AT_CHECK_M4([3>&-], [0], [[hello world
-]], [stderr], [in.m4])
-mv stderr experr
-AT_CHECK_M4([in.m4 3>&-], [0], [[hello world
-]], [experr])
-
-AT_CLEANUP
-
-
-## -------- ##
-## translit ##
-## -------- ##
-
-AT_SETUP([translit])
-
-AT_DATA([[translit.m4]],
-[[# traceon(`translit')dnl
-translit(`GNUs not Unix', `a-z')
-translit(`GNUs not Unix', `a-z', `A-Z')
-translit(`GNUs not Unix', `A-Z', `a-z')
-translit(`GNUs not Unix', `A-Z')
-translit(`a-z', `a-')
-translit(`A-Z', `A-Z-', `-A-Z')
-translit(`GNUs not Unix', `Z-A', `a-z')
-]])
-
-AT_CHECK_M4([translit.m4], 0,
-[[# traceon(`translit')dnl
-GNU U
-GNUS NOT UNIX
-gnus not unix
-s not nix
-z
--ZY
-tmfs not fnix
-]])
-
-dnl This used to be quadratic, taking millions of comparisons,
-dnl but should now operate in linear time with only several thousand checks.
-AT_DATA([in], [M4_ONE_MEG_DEFN[dnl
-define(`a_', translit(substr(f, `0', `50000'), `
-', `a'))dnl
-define(`b_', translit(substr(f, `0', `50000'), `
-', `b'))dnl
-define(`d_', translit(substr(f, `0', `50000'), `
-', `d'))dnl
-define(`c'd_, `pass')dnl
-translit(`a'b_, a_`b', `c'd_)
-]])
-AT_CHECK_M4([in], [0], [[pass
-]])
-
-dnl This validates that ranges are built using unsigned chars.
-AT_DATA([in], [[translit(`«abc~', `~-»')
-]])
-AT_CHECK_M4([in], [0], [[abc
-]])
-
-dnl Validate short strings, which take a different code path.
-AT_DATA([in], [[dnl
-translit(`abcdeabcde', `a')
-translit(`abcdeabcde', `ab')
-translit(`abcdeabcde', `a', `f')
-translit(`abcdeabcde', `aa', `fg')
-translit(`abcdeabcde', `a', `fg')
-translit(`abcdeabcde', `ab', `f')
-translit(`abcdeabcde', `ab', `fg')
-translit(`abcdeabcde', `ab', `ba')
-translit(`abcdeabcde', `e', `f')
-translit(`abc', `', `cde')
-translit(`', `a', `bc')
-]])
-AT_CHECK_M4([in], [0], [[bcdebcde
-cdecde
-fbcdefbcde
-fbcdefbcde
-fbcdefbcde
-fcdefcde
-fgcdefgcde
-bacdebacde
-abcdfabcdf
-abc
-
-]])
-
-AT_CLEANUP
-
-
-
-## -------- ##
-## undivert ##
-## -------- ##
-
-AT_SETUP([undivert])
-
-AT_DATA([[undivert.m4]],
-[[define(`undiverted', `UNDIVERTED')
-# undiverted file.
-undivert(`undivert.incl')
-# included file.
-include(`undivert.incl')
-]])
-
-AT_DATA([[undivert.incl]],
-[[This is to be undiverted soon.
-]])
-
-AT_CHECK_M4([undivert.m4], 0,
-[[
-# undiverted file.
-This is to be undiverted soon.
-
-# included file.
-This is to be UNDIVERTED soon.
-
-]])
-
-AT_CLEANUP
-
-
-
-## ---- ##
-## wrap ##
-## ---- ##
-
-AT_SETUP([wrap])
-
-AT_DATA([[wrap.m4]],
-[[divert(-1)
-m4wrap(`Wrapper no. 1
-')
-
-m4wrap(`Wrapper no. 2
-m4wrap(`Wrapper no. 3
-m4wrap(`Wrapper no. 4
-')')')
-divert
-No. 33: The End.
-]])
-
-AT_CHECK_M4([wrap.m4], 0,
-[[
-No. 33: The End.
-Wrapper no. 1
-Wrapper no. 2
-Wrapper no. 3
-Wrapper no. 4
-]])
-
-AT_CLEANUP
diff --git a/tests/freeze.at b/tests/freeze.at
deleted file mode 100644
index 438bcc32..00000000
--- a/tests/freeze.at
+++ /dev/null
@@ -1,539 +0,0 @@
-# Hand crafted tests for GNU M4. -*- Autotest -*-
-# Copyright (C) 2006-2010, 2013-2014, 2017 Free Software Foundation,
-# Inc.
-
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# AT_TEST_FREEZE([title], [text1], [text2])
-# -----------------------------------------
-# Create a test TITLE, which checks that freezing TEXT1, then reloading
-# it with TEXT2, produces the same results as running TEXT1 and TEXT2 in
-# a single run.
-m4_define([AT_TEST_FREEZE],
-[AT_SETUP([$1])
-AT_KEYWORDS([frozen])
-
-AT_DATA([frozen.m4], [$2])
-AT_DATA([unfrozen.m4], [$3])
-
-# First generate the `expout' output by running over the sources before
-# freezing.
-AT_CHECK_M4([frozen.m4 unfrozen.m4], [0], [stdout-nolog], [stderr])
-
-mv stdout expout
-mv stderr experr
-
-# Now freeze the first source file.
-AT_CHECK_M4([-F frozen.m4f frozen.m4], [0], [stdout-nolog])
-
-mv stdout out1
-
-# Now rerun the original sequence, but using the frozen file.
-AT_CHECK_M4([-R frozen.m4f unfrozen.m4],
- [0], [stdout-nolog], [experr], [], [ ])
-
-AT_CHECK([cat out1 stdout], [0], [expout])
-
-AT_CLEANUP
-])
-
-
-AT_BANNER([Freezing state.])
-
-## ---------------- ##
-## freezing failure ##
-## ---------------- ##
-
-AT_SETUP([freezing failure])
-AT_KEYWORDS([frozen])
-
-AT_CHECK_M4([-F /none/such], [1], [],
-[[m4: cannot open '/none/such': No such file or directory
-]])
-
-if test -w /dev/full && test -c /dev/full ; then
- AT_CHECK_M4([-F /dev/full], [1], [],
-[[m4: unable to create frozen state: No space left on device
-]])
-fi
-AT_CLEANUP
-
-
-## --------------- ##
-## large diversion ##
-## --------------- ##
-
-# Check that large diversions are handled across freeze boundaries.
-# Also check for escape character handling.
-AT_TEST_FREEZE([large diversion],
-[M4_ONE_MEG_DEFN[divert(2)f
-divert(1)hi
-a\nb
-]],
-[[divert(3)bye
-]])
-
-## ---------------- ##
-## loading format 1 ##
-## ---------------- ##
-
-AT_SETUP([loading format 1])
-AT_KEYWORDS([frozen])
-
-m4_if([
-Note: frozen.m4f was obtained by deleting unneeded lines from the output of
-a version of m4 1.4.5 with changeword support. Deleting lines is in effect
-equivalent to using undefine(name) in the input. This test ensures we
-behave well with the old format, including \ parsing, disappearing builtins
-(okay so long as the input does not try to use them), and restoring sane
-defaults for features that were only added in version 2 frozen format.
-
-$ m4 --version | head -n1
-GNU M4 1.4.5
-$ cat frozen.m4
-divert(`-1')
-define(`foo', `\n\
-FOO')
-pushdef(`foo', `bar${1}')
-define(`my_define', defn(`define'))
-define(`my_changeword', defn(`changeword'))
-pushdef(`my_define', `define')
-pushdef(`my_define', defn(`define'))
-divert(`1')dnl
-foo
-divert`'dnl
-changequote([,])dnl
-changecom([/*], [*/])dnl
-dnl Implied sequence of undefine(`name') due to hand-edits
-$ m4 -F frozen.m4f frozen.m4
-$
-])
-AT_DATA([frozen.m4f],
-[[# This is a frozen state file generated by GNU M4 1.4.5
-V1
-Q1,1
-[]
-C2,2
-/**/
-F6,6
-popdefpopdef
-F13,10
-my_changewordchangeword
-F9,6
-my_definedefine
-T9,6
-my_definedefine
-F9,6
-my_definedefine
-T3,7
-foo\n\
-FOO
-T3,7
-foobar${1}
-F3,3
-dnldnl
-D1,8
-bar${1}
-
-D0,0
-
-# End of frozen state file
-]])
-
-AT_DATA([input.m4],
-[[foo([2]) /* foo */ popdef([foo])foo
-my_define([bar], [1])[]popdef([my_define]) bar
-my_define([bar], [2])[]popdef([my_define]) bar
-my_define([bar], [3])[]popdef([my_define]) bar
-my_define([bar], [4])[]popdef([my_define]) bar
-]])
-
-AT_CHECK_M4([-R frozen.m4f input.m4], [0],
-[[bar${1} /* foo */ \n\
-FOO
- 1
-define 1
- 3
-my_define(bar, 4) 3
-bar${1}
-]],
-[[m4:input.m4:5: warning: popdef: undefined macro 'my_define'
-]])
-
-dnl Test rejection of v2 features in a v1 frozen file
-AT_DATA([bogus.m4f], [[V1
-M2
-m4
-]])
-AT_CHECK_M4([-R bogus.m4f], [1], [],
-[[m4:bogus.m4f:2: ill-formed frozen file, version 2 directive `M' encountered
-]])
-
-AT_CLEANUP
-
-
-## ---------------- ##
-## loading format 2 ##
-## ---------------- ##
-
-AT_SETUP([loading format 2])
-AT_KEYWORDS([frozen])
-
-AT_DATA([frozen.m4f],
-[[# Handcrafted file, obeying the version 2 spec
-V2
-# missing close quote should be supplied
-Q1,0
->
-
-# missing close comment should be supplied
-C1,0
-<
-
-M2
-m4
-M3
-gnu
-F7,7,3
-builtin
-builtin
-gnu
-# Text to negative diversion must not crash. Catches a regression
-# introduced 2007-05-28 and fixed 2007-05-31.
-D-1,5
-12345
-# Check line continuations.
-D1,3
-a\n\
-b
-# Zero can be implied
-D,
-
-# Testing escape sequences
-T4,6
-blah
--\t\477\040\X5C
-# Long macro definition. Catches a regression introduced on 2007-01-20
-# and patched 2007-02-25.
-T4,122
-long
-01234567890123456789012345678901234567890123456789
-01234567890123456789012345678901234567890123456789
-01234567890123456789
-]])
-
-AT_DATA([input.m4],
-[[< comment: builtin()
-builtin(>define', foo, bar)
-foo
-blah
-]])
-
-AT_CHECK_M4([-R frozen.m4f input.m4], [0],
-[[< comment: builtin()
-
-bar
-- '7 \
-a
-b]])
-
-dnl We don't support anything larger than format 2; make sure of that...
-AT_DATA([bogus.m4f], [[# comments aren't continued\
-V3
-]])
-AT_CHECK_M4([-R bogus.m4f], [63], [],
-[[m4:bogus.m4f:2: frozen file version 3 greater than max supported of 2
-]])
-
-dnl Check that V appears.
-AT_DATA([bogus.m4f], [[# not really a frozen file
-oops
-]])
-AT_CHECK_M4([-R bogus.m4f], [1], [],
-[[m4:bogus.m4f:2: expecting character `V' in frozen file
-]])
-
-dnl M4_DIVNUM_TEST(number, [out-of-bounds])
-dnl Check for diversion number corner case handling. Simulate freezing with
-dnl number as the active diversion, then reload and check that number. If
-dnl OUT-OF-BOUNDS, expect reloading to reject the frozen file.
-m4_define([M4_DIVNUM_TEST], [
-AT_DATA([frozen.m4f], [[V2
-M2
-m4
-M3
-gnu
-T1,5
-a
-\n\n\n\n\n
-F6,6,2
-divnum\
-
-divnum
-\
-m4\
-
-F6,6,2
-divert
-divert
-m4
-F6,6,2
-define
-define
-m4
-D]$1[,3
-hi
-
-]])
-AT_CHECK_M4([-R frozen.m4f in.m4], m4_ifval([$2], [1], [0]),
-m4_ifval([$2], [], [m4_bpatsubst([$1], [^0*])
-m4_if(m4_substr([$1], [0], [1]), [-], [], [[hi
-]])]), m4_ifval([$2], [[m4:frozen.m4f:24: integer overflow in frozen file
-]]))
-])
-
-AT_DATA([in.m4], [[define(d,divnum)divert(0)d
-]])
-M4_DIVNUM_TEST([02147483647])
-M4_DIVNUM_TEST([02147483648], [:])
-M4_DIVNUM_TEST([-2147483648])
-M4_DIVNUM_TEST([-2147483649], [:])
-
-AT_CLEANUP
-
-
-## --------- ##
-## changecom ##
-## --------- ##
-
-# Check that changecom/changequote are maintained across freeze boundaries.
-AT_TEST_FREEZE([reloading changecom],
-[[changecom`'changequote(<,>)dnl
-]],
-[[define(<foo>, <bar>)
-foo # foo
-]])
-
-## ------------ ##
-## changesyntax ##
-## ------------ ##
-
-# Check that changesyntax is maintained across freeze boundaries.
-AT_TEST_FREEZE([reloading changesyntax],
-[[changesyntax(`W+.', `({', `)}')dnl
-define{`a.b', `hello $1'}dnl
-]],
-[[a.b{world}
-]])
-
-## --------- ##
-## debugmode ##
-## --------- ##
-
-# Check that debugmode can be preserved, and how it interacts with -d
-AT_SETUP([reloading debugmode])
-AT_KEYWORDS([frozen])
-
-AT_DATA([frozen.m4],
-[[debugmode(`fl')dnl
-]])
-AT_DATA([unfrozen.m4],
-[[traceon(`len')len(`a')
-]])
-
-AT_CHECK_M4([-F frozen.m4f -d-V frozen.m4], [0])
-
-dnl With no -d option, use the frozen file
-AT_CHECK_M4([-R frozen.m4f unfrozen.m4], [0], [[1
-]], [[m4trace:unfrozen.m4:1: -1- len
-]], [], [ ])
-
-dnl With plain -d before -R, use the frozen file
-AT_CHECK_M4([-R frozen.m4f unfrozen.m4], [0], [[1
-]], [[m4trace:unfrozen.m4:1: -1- len
-]])
-
-dnl With plain -d after -R, add +adeq to the frozen file
-AT_CHECK_M4([-R frozen.m4f -d unfrozen.m4], [0], [[1
-]], [[m4trace:unfrozen.m4:1: -1- len(`a') -> `1'
-]], [], [ ])
-
-dnl With explicit -d option, override frozen file
-AT_CHECK_M4([-R frozen.m4f -de unfrozen.m4], [0], [[1
-]], [[m4trace: -1- len -> 1
-]])
-
-AT_CLEANUP
-
-## --------- ##
-## nul bytes ##
-## --------- ##
-
-# Check that NUL can be transparently preserved over freezing.
-AT_SETUP([reloading nul])
-AT_KEYWORDS([frozen])
-
-dnl AT_DATA can't generate NUL bytes (at least, not in all shells).
-# Skip the test if printf(1) is insufficient.
-AT_CHECK([printf 'define(-\0-,\0-\0)changequote([,\0])changecom(--\0)dnl
-divert(1)undivert(null.out)' || exit 77],
- [0], [stdout], [ignore])
-mv stdout frozen.m4
-printf 'divert(0)[divnum\0] @%:@-- len(indir(-\0-))\n' > unfrozen.m4
-
-# First generate the `expout' output by running over the sources before
-# freezing.
-AT_CHECK_M4([-I "$abs_srcdir" frozen.m4 unfrozen.m4], [0], [stdout], [stderr])
-
-mv stdout expout
-mv stderr experr
-
-# Now freeze the first source file.
-AT_CHECK_M4([-F frozen.m4f -I "$abs_srcdir" frozen.m4], [0], [stdout])
-
-mv stdout out1
-
-# Now rerun the original sequence, but using the frozen file.
-AT_CHECK_M4([-R frozen.m4f unfrozen.m4], [0], [stdout], [experr], [], [ ])
-
-AT_CHECK([cat out1 stdout], [0], [expout])
-
-dnl Check that unexpected embedded NULs are recognized.
-printf '# bogus frozen file\nV2\nR4\ngnu\0\n' > bogus.m4f
-AT_CHECK_M4([-R bogus.m4f], [1], [],
-[[m4:bogus.m4f:4: bad syntax-spec 'gnu\0'
-]])
-
-dnl Reject escape sequences that expand to unexpected NUL
-AT_DATA([bogus.m4f],
-[[# bogus frozen file
-V2
-F3,4
-len
-len\0
-]])
-AT_CHECK_M4([-R bogus.m4f], [1], [],
-[[m4:bogus.m4f:5: ill-formed frozen file, invalid builtin 'len\0' encountered
-]])
-
-AT_CLEANUP
-])
-
-## ------- ##
-## pushdef ##
-## ------- ##
-
-# Check for pushdef stacks; broken 2001-09-01, fixed 2008-05-15.
-AT_TEST_FREEZE([reloading pushdef stack],
-[[pushdef(`foo', `1')
-pushdef(`foo', defn(`len'))
-pushdef(`foo', `3')
-]],
-[[foo(`abc')popdef(`foo')
-foo(`ab')popdef(`foo')
-foo(`a')popdef(`foo')
-foo
-]])
-
-## ------------- ##
-## regexp syntax ##
-## ------------- ##
-
-# Check that regular expression syntax is maintained across freeze boundaries.
-AT_TEST_FREEZE([reloading regexp syntax],
-[[changeresyntax(`POSIX_EXTENDED')dnl
-]],
-[[regexp(`GNUs not Unix', `\w(\w*)$')
-regexp(`GNUs not Unix', `\w\(\w*\)$', `GNU_M4')
-]])
-
-## ----- ##
-## trace ##
-## ----- ##
-
-# Check for macro tracing, both single and global.
-AT_TEST_FREEZE([reloading traced macros],
-[[define(`text', `hello world')dnl
-define(`foo', `bar')dnl
-traceon(`blah', `divnum', `text')dnl
-traceon
-]],
-[[foo
-traceoff
-foo
-text
-divnum
-ifdef(`blah', `', `define(`blah', `finally')')dnl
-blah
-]])
-
-## ---------------- ##
-## unknown builtins ##
-## ---------------- ##
-
-AT_SETUP([reloading unknown builtin])
-AT_KEYWORDS([frozen])
-
-AT_DATA([[empty.m4]])
-
-# Freeze default state. Also check for bug fixed 18 Oct, 2007.
-AT_CHECK_M4([-F frozen.m4f -t undefined empty.m4])
-
-# Add an unknown builtin.
-echo 'F1,1' >> frozen.m4f
-echo 'a' >> frozen.m4f
-echo 'b' >> frozen.m4f
-
-AT_DATA([[input.m4]],
-[[dnl The macro is defined; checking this is safe
-ifdef(`a', `yes', `no')
-dnl Grabbing the definition must warn; and the copy is the empty string
-define(`c', defn(`a'))
-dnl Invoking the macro directly must warn
-a
-dnl Invoking it indirectly must warn
-indir(`a')
-dnl Since it is a placeholder, builtin must reject it
-builtin(`b')
-dnl The copy is a text string, not a placeholder
-c
-dnl Since it is defined, it must have a definition
-dumpdef(`a', `c')
-dnl Deleting it is safe
-popdef(`a')
-a
-]])
-
-AT_CHECK_M4([-R frozen.m4f input.m4], 0,
-[[yes
-
-
-
-
-
-
-
-a
-]],
-[[m4:input.m4:4: warning: defn: a: builtin 'b' requested by frozen file not found
-m4:input.m4:6: warning: a: builtin 'b' requested by frozen file not found
-m4:input.m4:8: warning: a: builtin 'b' requested by frozen file not found
-m4:input.m4:10: warning: builtin: undefined builtin 'b'
-a: <<b>>
-c: `'
-]], [], [ ])
-
-AT_CLEANUP
diff --git a/tests/generate.awk b/tests/generate.awk
deleted file mode 100755
index f373d7f3..00000000
--- a/tests/generate.awk
+++ /dev/null
@@ -1,216 +0,0 @@
-# Extract all examples from the manual source. -*- AWK -*-
-
-# Copyright (C) 1992, 2000-2001, 2006-2010, 2013-2014, 2017 Free
-# Software Foundation, Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# This script is for use with any New AWK.
-
-BEGIN {
- seq = -1;
- status = xfail = examples = 0;
- file = options = "";
- print "# This file is part of the GNU m4 test suite. -*- Autotest -*-";
- # I don't know how to get this file's name, so it's hard coded :(
- print "# Do not edit by hand, it was generated by generate.awk.";
- print "#";
- print "# Copyright (C) 1992, 2000, 2001, 2006, 2007, 2008, 2009 Free";
- print "# Software Foundation, Inc.";
- print ;
- print "AT_BANNER([Documentation examples.])";
- print ;
- print ;
-}
-
-/^@node / { # Start a new test group.
- if (seq > 0)
- print "AT_CLEANUP";
-
- split ($0, tmp, ",");
- node = substr(tmp[1], 7);
- seq = 0;
-}
-
-/^@comment file: / { # Produce a data file instead of a test.
- file = $3;
-}
-
-/^@comment options: / { # Pass additional options to m4.
- options = $0;
- gsub ("@comment options:", "", options);
-}
-
-/^@comment xfail$/ { # Expect the test to fail.
- xfail = 1;
-}
-
-/^@comment examples$/ { # The test uses files from the examples dir.
- examples = 1;
-}
-
-/^@comment ignore$/ { # This is just formatted doc text, not an actual test.
- getline;
- status = xfail = examples = 0;
- options = file = "";
- next;
-}
-
-/^@comment status: / { # Expected exit status of a test.
- status = $3;
-}
-
-/^@example$/, /^@end example$/ { # The body of the test.
- if (seq < 0)
- next;
-
- if ($0 ~ /^@example$/)
- {
- if (seq == 0)
- new_group(node);
- seq++;
- printf ("echo \"$at_srcdir/%s:%d:\"\n", FILENAME, NR)
- next;
- }
-
- if ($0 ~ /^@end example$/)
- {
- if (file != "")
- {
- if (output || error)
- {
- fatal("while getting file " file \
- " found output = " output "," \
- " found error = " error);
- }
- input = normalize(input);
- printf ("AT_DATA([[%s]],\n[[%s]])\n\n", file, input);
- }
- else
- {
- new_test(input, status, output, error, options, xfail, examples);
- }
- status = xfail = examples = 0;
- file = input = output = error = options = "";
- next;
- }
-
- if ($0 ~ /^\^D$/)
- next;
- if ($0 ~ /^\$ @kbd/)
- next;
-
- if ($0 ~ /^@result\{\}/)
- output = output $0 "\n";
- else if ($0 ~ /^@error\{\}/)
- error = error $0 "\n";
- else
- input = input $0 "\n";
-}
-
-END {
- if (seq > 0)
- print "AT_CLEANUP";
-}
-
-# We have to handle CONTENTS line per line, since anchors in AWK are
-# referring to the whole string, not the lines.
-function normalize(contents, i, lines, n, line, res) {
- # Remove the Texinfo tags.
- n = split (contents, lines, "\n");
- # We don't want the last field which empty: it's behind the last \n.
- for (i = 1; i < n; ++i)
- {
- line = lines[i];
- gsub ("^@result[{]}", "", line);
- gsub ("^@error[{]}", "", line);
- gsub ("@[{]", "{", line);
- gsub ("@}", "}", line);
- gsub ("@@", "@", line);
- gsub ("@tabchar[{]}", "\t", line);
- gsub ("@w[{] }", " @\\&t@", line);
- gsub ("m4_", "m@\\&t@4_", line);
-
- # Some of the examples have improperly balanced square brackets.
- gsub ("[[]", "@<:@", line);
- gsub ("[]]", "@:>@", line);
-
- res = res line "\n";
- }
- return res;
-}
-
-function new_group(node) {
- banner = node ". ";
- gsub (".", "-", banner);
- printf ("\n\n");
- printf ("## %s ##\n", banner);
- printf ("## %s. ##\n", node);
- printf ("## %s ##\n", banner);
- printf ("\n");
- printf ("AT_SETUP([%s])\n", node);
- printf ("AT_KEYWORDS([[documentation]])\n\n");
-}
-
-function new_test(input, status, output, error, options, xfail, examples) {
- input = normalize(input);
- output = normalize(output);
- error = normalize(error);
-
- if (error == "ignore\n")
- error = "ignore";
-
- if (options ~ / mpeval/)
- printf ("AT_CHECK_GMP\n");
- if (xfail == 1)
- printf ("AT_XFAIL_IF([:])\n");
-
- if (examples == 1)
- {
- printf ("AT_DATA([expout1],\n[[%s]])\n", output);
- printf ("$SED -e \"s|doc/examples|$abs_top_srcdir/doc/examples|g\" \\\n");
- printf (" < expout1 > expout\n\n");
- if (error)
- {
- printf ("AT_DATA([experr1],\n[[%s]])\n", error);
- printf ("$SED \"s|doc/examples|$abs_top_srcdir/doc/examples|g\" \\\n");
- printf (" < experr1 > experr\n\n");
- }
- options = options " -I\"$abs_top_srcdir/doc/examples\"";
- }
-
- printf ("AT_DATA([[input.m4]],\n[[%s]])\n\n", input);
- # Some of these tests `include' files from tests/.
- printf ("AT_CHECK_M4([[%s]], %s,", options, status);
- if (examples == 1)
- printf ("\n[expout]");
- else if (output)
- printf ("\n[[%s]]", output);
- else
- printf (" []");
- if (examples == 1 && error)
- printf (",\n[experr]");
- else if (error)
- printf (",\n[[%s]]", error);
- else
- printf (", []");
- printf (", [[input.m4]])\n\n");
-}
-
-function fatal(msg) {
- print "generate.awk: " FILENAME ":" NR ": " msg > "/dev/stderr"
- exit 1
-}
diff --git a/tests/import.c b/tests/import.c
deleted file mode 100644
index cdd1176c..00000000
--- a/tests/import.c
+++ /dev/null
@@ -1,110 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 2003, 2006-2008, 2010, 2013-2014, 2017 Free Software
- Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-/* Build using only the exported interfaces, unless NDEBUG is set, in
- which case use private symbols to speed things up as much as possible. */
-#ifndef NDEBUG
-# include <m4/m4module.h>
-#else
-# include "m4private.h"
-#endif
-
-/* function macros blind side minargs maxargs */
-#define builtin_functions \
- BUILTIN (import, false, false, false, 0, 1) \
- BUILTIN (symbol_fail, false, false, false, 0, 1) \
- BUILTIN (module_fail, false, false, false, 0, 1) \
-
-#define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler)
- builtin_functions
-#undef BUILTIN
-
-static const m4_builtin m4_builtin_table[] =
-{
-#define BUILTIN(handler, macros, blind, side, min, max) \
- M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
-
- builtin_functions
-#undef BUILTIN
-
- { NULL, NULL, 0, 0, 0 },
-};
-
-
-void
-include_import (m4 *context, m4_module *module, m4_obstack *obs)
-{
- m4_install_builtins (context, module, m4_builtin_table);
-}
-
-
-
-typedef bool export_test_func (const char *);
-typedef bool no_such_func (const char *);
-
-/**
- * import()
- **/
-M4BUILTIN_HANDLER (import)
-{
- M4_MODULE_IMPORT (modtest, export_test);
-
- const char *s = "`import'::`import' called.";
-
- assert (obs != 0);
- obstack_grow (obs, s, strlen(s));
-
- if (export_test && export_test (M4ARG (1)))
- fputs ("TRUE\n", stderr);
-}
-
-/**
- * symbol_fail()
- **/
-M4BUILTIN_HANDLER (symbol_fail)
-{
- M4_MODULE_IMPORT (modtest, no_such);
-
- const char *s = "`import'::`symbol_fail' called.";
-
- assert (obs != 0);
- obstack_grow (obs, s, strlen(s));
-
- if (no_such && no_such (M4ARG (1)))
- fputs ("TRUE\n", stderr);
-}
-
-/**
- * module_fail()
- **/
-M4BUILTIN_HANDLER (module_fail)
-{
- M4_MODULE_IMPORT (no_such, no_such);
-
- const char *s = "`import'::`module_fail' called.";
-
- assert (obs != 0);
- obstack_grow (obs, s, strlen(s));
-
- if (no_such && no_such (M4ARG (1)))
- fputs ("TRUE\n", stderr);
-}
diff --git a/tests/iso8859.m4 b/tests/iso8859.m4
deleted file mode 100644
index 8ffb7532..00000000
--- a/tests/iso8859.m4
+++ /dev/null
Binary files differ
diff --git a/tests/m4.in b/tests/m4.in
deleted file mode 100644
index 49d456c2..00000000
--- a/tests/m4.in
+++ /dev/null
@@ -1,46 +0,0 @@
-#! /bin/sh
-# @configure_input@
-# Wrapper around a non installed m4 to make it work as an installed one.
-#
-# Copyright (C) 2001-2002, 2006-2008, 2010, 2013-2014, 2017 Free
-# Software Foundation, Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-# Written by Gary V. Vaughan <gary@gnu.org>
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
- emulate sh
- NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
- # is contrary to our usage. Disable this feature.
- alias -g '${1+"$@"}'='"$@"'
- setopt NO_GLOB_SUBST
-else
- case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac
-fi
-
-M4PATH="\
-@abs_top_builddir@/modules/.libs:\
-@abs_top_builddir@/tests/.libs:\
-${M4PATH+$M4PATH:}\
-:"
-export M4PATH
-
-exec "@abs_top_builddir@/src/m4" \
- ${1+"$@"}
-exit 1
diff --git a/tests/macros.at b/tests/macros.at
deleted file mode 100644
index 2f8d5ba6..00000000
--- a/tests/macros.at
+++ /dev/null
@@ -1,589 +0,0 @@
-# Hand crafted tests for GNU M4. -*- Autotest -*-
-# Copyright (C) 2001, 2006-2008, 2010, 2013-2014, 2017 Free Software
-# Foundation, Inc.
-
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-AT_BANNER([Macro definitions.])
-
-# Checking everything related to macro definitions: the expansion of
-# user macros, the propagation of various bits (tracing, number of
-# arguments and so on).
-
-## ---------------- ##
-## Arity and defn. ##
-## ---------------- ##
-
-AT_SETUP([Arity and defn])
-
-# Check that the arity checking of define is correctly propagated.
-
-AT_DATA([[input.m4]],
-[[define(`defun', defn(`define'))
-define
-define(`foo')
-define(`foo', `bar')
-define(`foo', `bar', `baz')
-
-defun
-defun(`foo')
-defun(`foo', `bar')
-defun(`foo', `bar', `baz')
-]])
-
-AT_DATA([[expout]],
-[[
-define
-
-
-
-
-defun
-
-
-
-]])
-
-AT_CHECK_M4([input.m4], 0, [expout],
-[[m4:input.m4:5: warning: define: extra arguments ignored: 3 > 2
-m4:input.m4:10: warning: defun: extra arguments ignored: 3 > 2
-]])
-
-AT_CLEANUP
-
-
-## ------------------------- ##
-## Arity, defn, and freeze. ##
-## ------------------------- ##
-
-AT_SETUP([Arity, defn, and freeze])
-AT_KEYWORDS([frozen])
-
-AT_DATA([[freezeme.m4]],
-[[define(`defun', defn(`define'))dnl
-undefine(`define')dnl
-]])
-
-AT_CHECK_M4([--freeze-state=frozen.m4f freezeme.m4], 0)
-
-AT_DATA([[input.m4]],
-[[defun
-defun(`foo')
-defun(`foo', `bar')
-defun(`foo', `bar', `baz')
-]])
-
-AT_DATA([[expout]],
-[[defun
-
-
-
-]])
-
-AT_CHECK_M4([--reload-state=frozen.m4f input.m4], 0, expout,
-[[m4:input.m4:4: warning: defun: extra arguments ignored: 3 > 2
-]])
-
-AT_CLEANUP(freezeme.m4 frozen.m4f)
-
-
-## ------------------- ##
-## Command line define ##
-## ------------------- ##
-
-AT_SETUP([Command line define])
-
-dnl Test that -D after last file still affects m4wrap'd text.
-AT_DATA([in1], [[m4wrap(`foo
-')foo
-]])
-AT_DATA([in2], [[foo
-]])
-AT_CHECK_M4([-Dfoo=1 in1 -Dfoo=2 in2 -Dfoo=3], [0],
-[[1
-2
-3
-]])
-
-dnl Test that -D only affects top-most definition.
-AT_DATA([in1], [[define(`foo', `1')pushdef(`foo', `2')dnl
-]])
-AT_DATA([in2], [[foo
-popdef(`foo')foo
-popdef(`foo')foo
-]])
-AT_CHECK_M4([in1 -Dfoo=3 in2], [0],
-[[3
-1
-foo
-]])
-
-dnl Test that -D and -U interact in correct order
-AT_DATA([in], [[foo
-]])
-AT_CHECK_M4([-Dfoo=bar in -Ufoo in], [0], [[bar
-foo
-]])
-AT_CHECK_M4([-Ufoo in -Dfoo=bar in], [0], [[foo
-bar
-]])
-
-dnl Test macro arguments defined via -D
-AT_DATA([in], [[-foo-foo(1)-foo(1,2)-
--bar-bar(1)-bar(1,2)-
-]])
-AT_CHECK_M4([-Dfoo -Dbar='$@' in], [0],
-[[----
---1-1,2-
-]])
-
-AT_CLEANUP
-
-
-
-## -------------------- ##
-## Command line pushdef ##
-## -------------------- ##
-
-AT_SETUP([Command line pushdef])
-
-dnl Test that -p after last file still affects m4wrap'd text.
-AT_DATA([in1], [[m4wrap(`foo
-')foo
-]])
-AT_DATA([in2], [[foo
-]])
-AT_CHECK_M4([-pfoo=1 in1 -pfoo=2 in2 -pfoo=3], [0],
-[[1
-2
-3
-]])
-
-dnl Test that -p adds a definition.
-AT_DATA([in1], [[define(`foo', `1')pushdef(`foo', `2')dnl
-]])
-AT_DATA([in2], [[foo
-popdef(`foo')foo
-popdef(`foo')foo
-]])
-AT_CHECK_M4([in1 -pfoo=3 in2], [0],
-[[3
-2
-1
-]])
-
-dnl Test that --pushdef and --popdef interact in correct order
-AT_DATA([in], [[foo
-]])
-AT_CHECK_M4([-Dfoo=1 --pushdef=foo=2 in --popdef=foo in], [0],
-[[2
-1
-]])
-AT_CHECK_M4([--popdef=foo in --pushdef=foo=1 in], [0],
-[[foo
-1
-]])
-
-AT_CLEANUP
-
-
-
-## ---------------- ##
-## pushdef/popdef. ##
-## ---------------- ##
-
-AT_SETUP([pushdef/popdef])
-
-AT_DATA([[pushpop.m4]],
-[[divert(-1)
-pushdef(`hej', `def 1.')
-dumpdef(`hej')
-pushdef(`hej', `def 2.')
-dumpdef(`hej')
-pushdef(`hej', `def 3.')
-dumpdef(`hej')
-pushdef(`hej', `def 4.')
-dumpdef(`hej')
-
-popdef(`hej')
-dumpdef(`hej')
-popdef(`hej')
-dumpdef(`hej')
-popdef(`hej')
-dumpdef(`hej')
-popdef(`hej')
-dumpdef(`hej')
-
-dumpdef(`mac2')
-popdef(`mac2')
-]])
-
-AT_CHECK_M4([pushpop.m4], 0, [],
-[[hej: `def 1.'
-hej: `def 2.'
-hej: `def 3.'
-hej: `def 4.'
-hej: `def 3.'
-hej: `def 2.'
-hej: `def 1.'
-m4:pushpop.m4:18: warning: dumpdef: undefined macro 'hej'
-m4:pushpop.m4:20: warning: dumpdef: undefined macro 'mac2'
-m4:pushpop.m4:21: warning: popdef: undefined macro 'mac2'
-]])
-
-AT_CLEANUP
-
-
-
-## ---------------------- ##
-## Tracing Hanoi Towers. ##
-## ---------------------- ##
-
-AT_SETUP([Tracing Hanoi Towers])
-
-AT_DATA([[trace.m4]],
-[[divert(-1)
-
-# move(from, to)
-define(`move', `Move one disk from `$1' to `$2'.
-')
-
-# _hanoi (cnt, from, to, aux)
-define(`_hanoi', `ifelse(eval(`$1'<=1), 1, `move($2, $3)',
-`_hanoi(decr($1), $2, $4, $3)move($2, $3)_hanoi(decr($1), $4, $3, $2)')')
-
-# hanoi (cnt)
-define(`hanoi', `_hanoi(`$1', source, destination, auxilliary)')
-divert`'dnl
-
-# Debugmode t
-debugmode(`t')
-hanoi(2)
-
-# Debugmode taeq
-debugmode(`taeq')
-hanoi(2)
-
-# Debugmode OFF
-debugmode
-hanoi(2)
-
-# Debugmode ae
-debugmode(`ae')
-traceon(`move', `_hanoi')
-hanoi(2)
-]])
-
-AT_DATA([[expout]],
-[[
-# Debugmode t
-
-Move one disk from source to auxilliary.
-Move one disk from source to destination.
-Move one disk from auxilliary to destination.
-
-
-# Debugmode taeq
-
-Move one disk from source to auxilliary.
-Move one disk from source to destination.
-Move one disk from auxilliary to destination.
-
-
-# Debugmode OFF
-
-Move one disk from source to auxilliary.
-Move one disk from source to destination.
-Move one disk from auxilliary to destination.
-
-
-# Debugmode ae
-
-
-Move one disk from source to auxilliary.
-Move one disk from source to destination.
-Move one disk from auxilliary to destination.
-
-]])
-
-AT_DATA([[experr]],
-[[m4trace: -1- hanoi
-m4trace: -1- _hanoi
-m4trace: -2- eval
-m4trace: -1- ifelse
-m4trace: -2- decr
-m4trace: -1- _hanoi
-m4trace: -2- eval
-m4trace: -1- ifelse
-m4trace: -1- move
-m4trace: -1- move
-m4trace: -2- decr
-m4trace: -1- _hanoi
-m4trace: -2- eval
-m4trace: -1- ifelse
-m4trace: -1- move
-m4trace: -1- debugmode
-m4trace: -1- hanoi(`2') -> `_hanoi(`2', source, destination, auxilliary)'
-m4trace: -1- _hanoi(`2', `source', `destination', `auxilliary') -> `ifelse(eval(`2'<=1), 1, `move(source, destination)',
-`_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)')'
-m4trace: -2- eval(`2<=1') -> `0'
-m4trace: -1- ifelse(`0', `1', `move(source, destination)', `_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)') -> `_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)'
-m4trace: -2- decr(`2') -> `1'
-m4trace: -1- _hanoi(`1', `source', `auxilliary', `destination') -> `ifelse(eval(`1'<=1), 1, `move(source, auxilliary)',
-`_hanoi(decr(1), source, destination, auxilliary)move(source, auxilliary)_hanoi(decr(1), destination, auxilliary, source)')'
-m4trace: -2- eval(`1<=1') -> `1'
-m4trace: -1- ifelse(`1', `1', `move(source, auxilliary)', `_hanoi(decr(1), source, destination, auxilliary)move(source, auxilliary)_hanoi(decr(1), destination, auxilliary, source)') -> `move(source, auxilliary)'
-m4trace: -1- move(`source', `auxilliary') -> `Move one disk from `source' to `auxilliary'.
-'
-m4trace: -1- move(`source', `destination') -> `Move one disk from `source' to `destination'.
-'
-m4trace: -2- decr(`2') -> `1'
-m4trace: -1- _hanoi(`1', `auxilliary', `destination', `source') -> `ifelse(eval(`1'<=1), 1, `move(auxilliary, destination)',
-`_hanoi(decr(1), auxilliary, source, destination)move(auxilliary, destination)_hanoi(decr(1), source, destination, auxilliary)')'
-m4trace: -2- eval(`1<=1') -> `1'
-m4trace: -1- ifelse(`1', `1', `move(auxilliary, destination)', `_hanoi(decr(1), auxilliary, source, destination)move(auxilliary, destination)_hanoi(decr(1), source, destination, auxilliary)') -> `move(auxilliary, destination)'
-m4trace: -1- move(`auxilliary', `destination') -> `Move one disk from `auxilliary' to `destination'.
-'
-m4trace: -1- debugmode -> `'
-m4trace: -1- _hanoi(2, source, destination, auxilliary) -> ifelse(eval(`2'<=1), 1, `move(source, destination)',
-`_hanoi(decr(2), source, auxilliary, destination)move(source, destination)_hanoi(decr(2), auxilliary, destination, source)')
-m4trace: -1- _hanoi(1, source, auxilliary, destination) -> ifelse(eval(`1'<=1), 1, `move(source, auxilliary)',
-`_hanoi(decr(1), source, destination, auxilliary)move(source, auxilliary)_hanoi(decr(1), destination, auxilliary, source)')
-m4trace: -1- move(source, auxilliary) -> Move one disk from `source' to `auxilliary'.
-
-m4trace: -1- move(source, destination) -> Move one disk from `source' to `destination'.
-
-m4trace: -1- _hanoi(1, auxilliary, destination, source) -> ifelse(eval(`1'<=1), 1, `move(auxilliary, destination)',
-`_hanoi(decr(1), auxilliary, source, destination)move(auxilliary, destination)_hanoi(decr(1), source, destination, auxilliary)')
-m4trace: -1- move(auxilliary, destination) -> Move one disk from `auxilliary' to `destination'.
-
-]])
-
-AT_CHECK_M4([trace.m4], 0, expout, experr)
-
-AT_CLEANUP
-
-
-
-## ------------------------------- ##
-## Propagation of trace requests. ##
-## ------------------------------- ##
-
-AT_SETUP([Propagation of traceon])
-
-AT_DATA([[trace2.m4]],
-[[traceon(`define')
-debugmode(`aeq')
-
-# copy the `define' builtin definition to another symbol
-define(`my_define', defn(`define'))
-
-# delete the original
-undefine(`define')
-
-# Does it work?
-my_define(`foo', `bar')
-
-# Use the new definition to redefine the original symbol
-my_define(`define', defn(`my_define'))
-
-# Torture the flag propogation
-undefine(`my_define')
-define(`my_define', defn(`define'))
-
-# There are now 2 symbols pointing to the same builtin function
-my_define(`foo', `bar')
-define(`foo', `bar')
-]])
-
-AT_DATA([[expout]],
-[[
-
-
-# copy the `define' builtin definition to another symbol
-
-
-# delete the original
-
-
-# Does it work?
-
-
-# Use the new definition to redefine the original symbol
-
-
-# Torture the flag propogation
-
-
-
-# There are now 2 symbols pointing to the same builtin function
-
-
-]])
-
-AT_DATA([[experr]],
-[[m4trace: -1- define(`my_define', <define>) -> `'
-m4trace: -1- define(`my_define', <define>) -> `'
-m4trace: -1- define(`foo', `bar') -> `'
-]])
-
-AT_CHECK_M4([trace2.m4], 0, expout, experr)
-
-AT_CLEANUP
-
-
-
-## ------------------------ ##
-## Propagation of --trace. ##
-## ------------------------ ##
-
-AT_SETUP([Propagation of --trace])
-
-AT_DATA([[trace3.m4]],
-[[# copy the `define' builtin definition to another symbol
-define(`my_define', defn(`define'))
-
-# delete the original
-undefine(`define')
-
-# Does it work?
-my_define(`foo', `bar')
-
-# Use the new definition to redefine the original symbol
-my_define(`define', defn(`my_define'))
-
-# Torture the flag propogation
-undefine(`my_define')
-define(`my_define', defn(`define'))
-
-# There are now 2 symbols pointing to the same builtin function
-my_define(`foo', `bar')
-define(`foo', `bar')
-]])
-
-AT_DATA([[expout]],
-[[# copy the `define' builtin definition to another symbol
-
-
-# delete the original
-
-
-# Does it work?
-
-
-# Use the new definition to redefine the original symbol
-
-
-# Torture the flag propogation
-
-
-
-# There are now 2 symbols pointing to the same builtin function
-
-
-]])
-
-AT_DATA([[experr]],
-[[m4trace: -1- define(`my_define', <define>) -> `'
-m4trace: -1- define(`my_define', <define>) -> `'
-m4trace: -1- define(`foo', `bar') -> `'
-]])
-
-AT_CHECK_M4([-t define -daeq trace3.m4], 0, expout, experr)
-
-AT_CLEANUP
-
-
-## --------------------- ##
-## Renamesyms collisions ##
-## --------------------- ##
-
-AT_SETUP([Renamesyms collisions])
-
-dnl FIXME - We should gracefully detect rename collisions, rather than
-dnl violating the invariants of the symbol table.
-AT_XFAIL_IF([:])
-
-AT_DATA([in], [[define(`bar', `1')define(`baz', `2')dnl
-renamesyms(`^ba.$', `baa')
-]])
-
-AT_CHECK_M4([in], [0], [[
-]], [ignore])
-
-AT_CLEANUP
-
-
-## ----------------- ##
-## Rescanning macros ##
-## ----------------- ##
-
-AT_SETUP([Rescanning macros])
-
-dnl This is a series of tests that used to be included as undocumented tests
-dnl in the branch m4.texinfo. They exercise rescanning issues not stressed
-dnl anywhere else in the suite, but which are used by autoconf.
-AT_DATA([in], [[define(`x1', `len(`$1'')dnl
-define(`y1', ``$1')')dnl
-x1(`01234567890123456789')y1(`98765432109876543210')
-]])
-
-AT_CHECK_M4([in], [0], [[40
-]])
-
-AT_DATA([in], [[define(`echo', `$@')dnl
-define(`foo', echo(`01234567890123456789')echo(`98765432109876543210'))dnl
-foo
-]])
-
-AT_CHECK_M4([in], [0], [[0123456789012345678998765432109876543210
-]])
-
-AT_DATA([in], [[define(`a', `A')define(`echo', `$@')define(`join', `$1$2')dnl
-define(`abcdefghijklmnopqrstuvwxyz', `Z')dnl
-join(`a', `bcdefghijklmnopqrstuvwxyz')
-join(`a', echo(`bcdefghijklmnopqrstuvwxyz'))
-]])
-
-AT_CHECK_M4([in], [0], [[Z
-Z
-]])
-
-AT_DATA([in], [[define(`echo', `$@')dnl
-echo(echo(`01234567890123456789', `01234567890123456789')
-echo(`98765432109876543210', `98765432109876543210'))
-len((echo(`01234567890123456789',
- `01234567890123456789')echo(`98765432109876543210',
- `98765432109876543210')))
-indir(`echo', indir(`echo', `01234567890123456789',
- `01234567890123456789')
-indir(`echo', `98765432109876543210', `98765432109876543210'))
-define(`argn', `$#')dnl
-define(`echo1', `-$@-')define(`echo2', `,$@,')dnl
-echo1(`1', `2', `3') argn(echo1(`1', `2', `3'))
-echo2(`1', `2', `3') argn(echo2(`1', `2', `3'))
-]])
-
-AT_CHECK_M4([in], [0], [[01234567890123456789,01234567890123456789
-98765432109876543210,98765432109876543210
-84
-01234567890123456789,01234567890123456789
-98765432109876543210,98765432109876543210
--1,2,3- 3
-,1,2,3, 5
-]])
-
-AT_CLEANUP
diff --git a/tests/modtest.c b/tests/modtest.c
deleted file mode 100644
index ad6d91b2..00000000
--- a/tests/modtest.c
+++ /dev/null
@@ -1,101 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1999-2001, 2003-2004, 2006-2008, 2010, 2013-2014, 2017
- Free Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-/* Build using only the exported interfaces, unless NDEBUG is set, in
- which case use private symbols to speed things up as much as possible. */
-#ifndef NDEBUG
-# include <m4/m4module.h>
-#else
-# include "m4private.h"
-#endif
-
-extern bool export_test (const char *foo);
-
-/* function macros blind side minargs maxargs */
-#define builtin_functions \
- BUILTIN (test, false, false, false, 0, 0)
-
-#define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler)
- builtin_functions
-#undef BUILTIN
-
-static const m4_builtin m4_builtin_table[] =
-{
-#define BUILTIN(handler, macros, blind, side, min, max) \
- M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
-
- builtin_functions
-#undef BUILTIN
-
- { NULL, NULL, 0, 0, 0 },
-};
-
-static const m4_macro m4_macro_table[] =
-{
- /* name text min max */
- { "__test__", "`modtest'", 0, 0 },
- { "onearg", "$1", 1, 1 },
- { "manyargs", "$@", 0, SIZE_MAX },
- { NULL, NULL, 0, 0 },
-};
-
-
-
-/**
- * modtest()
- **/
-void
-include_modtest (m4 *context, m4_module *module, m4_obstack *obs)
-{
- const char *s = "Test module loaded.\n";
-
- m4_install_builtins (context, module, m4_builtin_table);
- m4_install_macros (context, module, m4_macro_table);
-
- /* Don't depend on OBS so that the traces are the same when used
- directly, or via a frozen file. */
- fputs (s, stderr);
-}
-
-
-/**
- * test()
- **/
-M4BUILTIN_HANDLER (test)
-{
- const char *s = "Test module called.";
-
- assert (obs != 0);
- obstack_grow (obs, s, strlen(s));
-}
-
-
-/**
- * export_test()
- **/
-bool
-export_test (const char *foo)
-{
- if (foo)
- xfprintf (stderr, "%s\n", foo);
- return (bool) (foo != 0);
-}
diff --git a/tests/modules.at b/tests/modules.at
deleted file mode 100644
index f4e5485b..00000000
--- a/tests/modules.at
+++ /dev/null
@@ -1,344 +0,0 @@
-# Hand crafted tests for GNU M4. -*- Autotest -*-
-# Copyright (C) 2001, 2006-2008, 2010, 2013-2014, 2017 Free Software
-# Foundation, Inc.
-
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-AT_BANNER([Module support.])
-
-
-## --------- ##
-## modfreeze ##
-## --------- ##
-
-AT_SETUP([Freezing modules])
-AT_KEYWORDS([frozen])
-
-AT_DATA([[frozen.m4]],
-[[divert(1)dnl
-define(`test', `local::`test'')dnl
-define(`test1', defn(`test'))dnl
-->test
-include(`modtest')
-define(`test2', defn(`test'))dnl
-->test
-include(`shadow')
-define(`test3', defn(`test'))dnl
-->test
-]])
-
-AT_DATA([[unfrozen.m4]],
-[[undivert(1)dnl
-test1
-test2
-test3
-]])
-
-# First generate the `expout' ouput by running over the sources before
-# freezing.
-AT_CHECK_M4([-I "$abs_builddir" frozen.m4 unfrozen.m4],
- [0], [stdout], [stderr])
-
-mv stdout expout
-mv stderr experr
-
-# Now freeze the first source file.
-AT_CHECK_M4([-I "$abs_builddir" -F frozen.m4f frozen.m4],
- [0], [], [ignore])
-
-# Now rerun the original sequence, but using the frozen file.
-AT_CHECK_M4([-I "$abs_builddir" -R frozen.m4f unfrozen.m4],
- [0], [expout], [experr])
-
-AT_CLEANUP([frozen.m4f])
-
-
-## ---------------------------- ##
-## Exercising the test module. ##
-## ---------------------------- ##
-
-# AT_CHECK_M4_MODTEST(TITLE, ENV-VARS, M4-OPTIONS)
-# ------------------------------------------------
-# Add a test named TITLE, running m4 with either ENV-VARS in the environment
-# or M4-OPTIONS set to pick up test modules.
-m4_define([AT_CHECK_M4_MODTEST],
-[AT_SETUP([$1])
-
-AT_DATA([input.m4],
-[[test
-Dumpdef: dumpdef(`test').
-include(`modtest')
-test
-Dumpdef: dumpdef(`test').
-]])
-
-dnl Fortunately, all tests within AT_SETUP are in the same subshell, so
-dnl setting the environment now will impact the AT_CHECK_M4, but not
-dnl carry over to the next AT_SETUP.
-m4_ifval([$2], [$2
-export m4_substr([$2], [0], m4_index([$2], [=]))])
-
-AT_CHECK_M4([$3 input.m4], [0],
-[[test
-Dumpdef: .
-
-Test module called.
-Dumpdef: .
-]],
-[[m4:input.m4:2: warning: dumpdef: undefined macro 'test'
-Test module loaded.
-test: <test>
-]])
-
-AT_CLEANUP
-])
-
-
-
-AT_CHECK_M4_MODTEST([--include: absolute path],
- [], [-I "$abs_builddir"])
-
-AT_CHECK_M4_MODTEST([--include: relative path],
- [], [-I "$top_build_prefix/tests"])
-
-AT_CHECK_M4_MODTEST([M4PATH: absolute path],
- [M4PATH="$abs_builddir:"], [])
-
-AT_CHECK_M4_MODTEST([M4PATH: relative path],
- [M4PATH="$top_build_prefix/tests:"], [])
-
-
-
-## ------ ##
-## shadow ##
-## ------ ##
-
-AT_SETUP([modules: shadow])
-
-AT_DATA([[input.m4]],
-[[# no modules loaded yet
-test
-shadow
-
-# define our own macros for `test' and `shadow'
-define(`test', `local::`test'')
-define(`shadow', `local::`shadow'')
-test
-shadow
-
-# module Shadow defines `shadow' and `test' macros
-include(`shadow')
-dumpdef(`test')
-dumpdef(`shadow')
-test
-shadow
-
-# save the definition of `test' from the Shadow module
-define(`Shadow::test', defn(`test'))
-
-# module Modtest also defines a `test' macro
-include(`modtest')
-dumpdef(`test')
-dumpdef(`shadow')
-test
-shadow
-
-# Reloading Shadow shouldn't affect anything
-include(`shadow')
-dumpdef(`test')
-dumpdef(`shadow')
-test
-shadow
-]])
-
-AT_DATA([[expout]],
-[[# no modules loaded yet
-test
-shadow
-
-# define our own macros for `test' and `shadow'
-
-
-local::test
-local::shadow
-
-# module Shadow defines `shadow' and `test' macros
-Shadow module loaded.
-
-
-Shadow::test called.
-Shadow::shadow called.
-
-# save the definition of `test' from the Shadow module
-
-
-# module Modtest also defines a `test' macro
-
-
-
-Test module called.
-Shadow::shadow called.
-
-# Reloading Shadow shouldn't affect anything
-
-
-
-Test module called.
-Shadow::shadow called.
-]])
-
-AT_DATA([[experr]],
-[[test: <test>
-shadow: <shadow>
-Test module loaded.
-test: <test>
-shadow: <shadow>
-test: <test>
-shadow: <shadow>
-]])
-
-AT_CHECK_M4([-I "$abs_builddir" input.m4], [0],
- [expout], [experr])
-
-AT_CLEANUP
-
-
-
-## ----------------------- ##
-## module symbol importing ##
-## ----------------------- ##
-
-# Importing a symbol from a not yet loaded module
-
-# This test is ugly, because we need to canonicalize strerror strings
-# to match our test. So we save STDERR to a file, and run another check
-# which edits that file and compares it to the canonical STDERR output
-# from the first command:
-
-AT_SETUP([modules: importing])
-
-AT_DATA([[input.m4]],
-[[import
-include(`import')
-import
-import
-symbol_fail
-module_fail
-]])
-
-AT_DATA([[expout]],
-[[import
-
-import::import called.
-import::import called.
-import::symbol_fail called.
-]])
-
-AT_DATA([[experr]],
-[[Test module loaded.
-
-TRUE
-
-TRUE
-m4:input.m4:5: cannot load symbol `no_such' from module `modtest'
-m4:input.m4:6: cannot open module `no_such'
-]])
-
-ls "$abs_builddir"
-
-AT_CHECK_M4([-I "$abs_builddir" input.m4],
- [1], [expout], [experr])
-
-AT_CLEANUP
-
-
-
-## ------------------- ##
-## text module symbols ##
-## ------------------- ##
-
-# Support text macros with requested numbers of parameters.
-
-AT_SETUP([modules: text])
-
-AT_DATA([input.m4],
-[[__test__
-__test__(1)
-__test__(1,2)
-onearg
-onearg(1)
-onearg(1,2)
-manyargs
-manyargs(1)
-manyargs(1,2)
-]])
-
-AT_CHECK_M4([-I "$abs_builddir" modtest input.m4], [0],
-[[modtest
-modtest
-modtest
-
-1
-1
-
-1
-1,2
-]], [[Test module loaded.
-m4:input.m4:2: warning: __test__: extra arguments ignored: 1 > 0
-m4:input.m4:3: warning: __test__: extra arguments ignored: 2 > 0
-m4:input.m4:4: warning: onearg: too few arguments: 0 < 1
-m4:input.m4:6: warning: onearg: extra arguments ignored: 2 > 1
-]])
-
-AT_CLEANUP
-
-
-## -------------------- ##
-## trace module symbols ##
-## -------------------- ##
-
-# The trace bit should not be lost if a builtin is unloaded from
-# memory and then redefined by a subsequent load.
-
-AT_SETUP([modules: trace])
-
-AT_DATA([[input.m4]],
-[[test
-include(`shadow')
-test
-include(`shadow')
-test
-]])
-
-AT_DATA([[expout]],
-[[test
-Shadow module loaded.
-Shadow::test called.
-
-Shadow::test called.
-]])
-
-AT_DATA([[experr]],
-[[m4trace: -1- test -> `Shadow::`test' called.'
-m4trace: -1- test -> `Shadow::`test' called.'
-]])
-
-
-AT_CHECK_M4([-I "$abs_builddir" -t test input.m4],
- [0], [expout], [experr])
-
-AT_CLEANUP
diff --git a/tests/null.err b/tests/null.err
deleted file mode 100644
index 50ae6272..00000000
--- a/tests/null.err
+++ /dev/null
Binary files differ
diff --git a/tests/null.m4 b/tests/null.m4
deleted file mode 100644
index 92fb6a11..00000000
--- a/tests/null.m4
+++ /dev/null
Binary files differ
diff --git a/tests/null.out b/tests/null.out
deleted file mode 100644
index 784ab7ab..00000000
--- a/tests/null.out
+++ /dev/null
Binary files differ
diff --git a/tests/options.at b/tests/options.at
deleted file mode 100644
index 29f41c07..00000000
--- a/tests/options.at
+++ /dev/null
@@ -1,863 +0,0 @@
-# Hand crafted tests for GNU M4. -*- Autotest -*-
-# Copyright (C) 2001, 2006-2010, 2013-2014, 2017 Free Software
-# Foundation, Inc.
-
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-AT_BANNER([Options.])
-
-
-## ------------------ ##
-## deprecated options ##
-## ------------------ ##
-
-AT_SETUP([deprecated options])
-
-dnl -N/--diversions was removed after 1.4.x
-AT_CHECK_M4([--diversions=1], [1], [], [stderr])
-AT_CHECK([$SED 's/Try.*help/Try `m4 --help/' stderr], [0],
-[[m4: bad option
-Try `m4 --help' for more information.
-]])
-
-dnl -H/--hashsize are no-ops since 2.0
-AT_CHECK_M4([-H1 --hashsize=1], [0], [],
-[[m4: warning: `-H' is deprecated
-m4: warning: `--hashsize' is deprecated
-]])
-
-dnl -S/-T are no-ops for compatibility
-AT_CHECK_M4([-S1 -T1], [0], [],
-[[m4: warning: `-S' is deprecated
-m4: warning: `-T' is deprecated
-]])
-
-dnl -Bint can be confused with its no-op meaning in 1.4.x, but all other
-dnl uses of -B or its long option are okay
-AT_CHECK_M4([-B1], [0], [],
-[[m4: warning: recommend using `-B ./1' instead
-]])
-AT_CHECK_M4([-B./1 --prepend-include=1], [0], [],
-[[]])
-
-dnl --error-output is a misleading name
-AT_CHECK_M4([--error-output=trace], [0], [],
-[[m4: warning: `--error-output' is deprecated, use `--debugfile' instead
-]])
-AT_CHECK([rm trace])
-
-dnl -o will change meaning in the future
-AT_CHECK_M4([-otrace], [0], [],
-[[m4: warning: `-o' is deprecated, use `--debugfile' instead
-]])
-AT_CHECK([rm trace])
-
-dnl -e is an odd spelling for --interactive
-AT_CHECK_M4([-e], [0], [],
-[[m4: warning: `-e' is deprecated, use `-i' instead
-]])
-
-dnl --arglength is an older spelling for --debuglen
-AT_CHECK_M4([--arglength=10], [0], [],
-[[m4: warning: `--arglength' is deprecated, use `--debuglen' instead
-]])
-
-AT_CHECK_M4([--arglength=x], [1], [],
-[[m4: warning: `--arglength' is deprecated, use `--debuglen' instead
-m4: invalid --arglength argument 'x'
-]])
-
-dnl --word-regexp from 1.4.x is no longer supported. Can't test for its
-dnl alternate spelling -W, as that now means --warnings.
-AT_CHECK_M4([[--word-regexp='[a-zA-Z0-9_]+']], [0], [],
-[[m4: warning: `--word-regexp' is deprecated
-]])
-
-AT_CLEANUP
-
-
-## ---------- ##
-## file names ##
-## ---------- ##
-
-AT_SETUP([file names])
-
-dnl Check that all files are processed even after missing file
-AT_DATA([in], [[hello world
-]])
-AT_CHECK_M4([oops in], [1], [[hello world
-]], [[m4: cannot open file 'oops': No such file or directory
-]])
-
-dnl Check that '-' means stdin, even if ./- exists.
-AT_DATA([-], [[hi
-]])
-AT_CHECK_M4([-], [0])
-AT_CHECK_M4([- --], [0])
-AT_CHECK_M4([-- -], [0])
-AT_CHECK_M4([./-], [0], [[hi
-]])
-AT_CHECK_M4([./- --], [0], [[hi
-]])
-AT_CHECK_M4([-- ./-], [0], [[hi
-]])
-
-AT_CLEANUP
-
-
-## --------------- ##
-## option grouping ##
-## --------------- ##
-
-AT_SETUP([option grouping])
-
-dnl this test group depends on correct settings of POSIXLY_CORRECT
-if test -n "${POSIXLY_CORRECT+set}" ; then
- (unset POSIXLY_CORRECT) >/dev/null 2>&1 || {
- echo "Problem unsetting POSIXLY_CORRECT"
- AT_CHECK([exit 77])
- }
- unset POSIXLY_CORRECT
-fi
-
-dnl This comes from the "Invoking m4" node; it was easier to write the
-dnl test separately than to let generate.awk fiddle with it.
-AT_DATA([a], [[foo 1
-m@&t@4_dnl()
-]])
-
-AT_DATA([-d+f], [[hi
-]])
-
-dnl First, run with GNU semantics
-AT_CHECK_M4([-QPDfoo -d a -d+f], [0], [[ 1
-]])
-
-AT_CHECK_M4([-Q -P -D foo -d -d+f -- a], [0], [[ 1
-]])
-
-AT_CHECK_M4([-QPDfoo -d -- a -d+f], [0], [[ 1
-hi
-]])
-
-AT_CHECK_M4([-Q -P -D foo -d ./a ./-d+f], [0], [[ 1
-hi
-]])
-
-AT_CHECK_M4([--def foo --debug a], [0], [[ 1
-m@&t@4_dnl()
-]])
-
-AT_CHECK_M4([--define=foo --debug= -- a], [0], [[ 1
-m@&t@4_dnl()
-]])
-
-dnl Next, run with POSIX semantics
-POSIXLY_CORRECT=1
-export POSIXLY_CORRECT
-
-AT_CHECK_M4([-QPDfoo -d a -d+f], [0], [[ 1
-]])
-
-AT_CHECK_M4([-Q -P -D foo -d -d+f -- ./a], [0], [[ 1
-]])
-
-AT_CHECK_M4([-QPDfoo -d -- a -d+f], [0], [[ 1
-hi
-]])
-
-AT_CHECK_M4([-Q -P -D foo -d ./a ./-d+f], [0], [[ 1
-hi
-]])
-
-AT_CHECK_M4([--def foo --debug a], [0], [[ 1
-m@&t@4_dnl()
-]])
-
-AT_CHECK_M4([--define=foo --debug= -- a], [0], [[ 1
-m@&t@4_dnl()
-]])
-
-AT_CLEANUP
-
-
-## --------------- ##
-## POSIXLY_CORRECT ##
-## --------------- ##
-
-AT_SETUP([POSIXLY_CORRECT])
-
-dnl this test group depends on correct settings of POSIXLY_CORRECT
-if test -n "${POSIXLY_CORRECT+set}" ; then
- (unset POSIXLY_CORRECT) >/dev/null 2>&1 || {
- echo "Problem unsetting POSIXLY_CORRECT"
- AT_CHECK([exit 77])
- }
- unset POSIXLY_CORRECT
-fi
-
-dnl By default, GNU extensions and warnings are enabled
-AT_DATA([in], [[__line__
-dnl()
-]])
-AT_CHECK_M4([in], [0], [[1
-]], [[m4:in:2: warning: dnl: extra arguments ignored: 1 > 0
-]])
-AT_CHECK_M4([in -g], [0], [[1
-]], [[m4:in:2: warning: dnl: extra arguments ignored: 1 > 0
-]])
-AT_CHECK_M4([in -G], [0], [[__line__
-]], [[m4:in:2: warning: dnl: extra arguments ignored: 1 > 0
-]])
-AT_CHECK_M4([in -W], [0], [[1
-]], [[m4:in:2: warning: dnl: extra arguments ignored: 1 > 0
-]])
-AT_CHECK_M4([in -Q], [0], [[1
-]])
-
-dnl Next, run with POSIX semantics
-POSIXLY_CORRECT=1
-export POSIXLY_CORRECT
-
-dnl POSIXLY_CORRECT implies -G -Q
-AT_DATA([in], [[__line__
-dnl()
-]])
-AT_CHECK_M4([in], [0], [[__line__
-]])
-AT_CHECK_M4([in -g], [0], [[1
-]])
-AT_CHECK_M4([in -G], [0], [[__line__
-]])
-AT_CHECK_M4([in -W], [0], [[__line__
-]], [[m4:in:2: warning: dnl: extra arguments ignored: 1 > 0
-]])
-AT_CHECK_M4([in -Q], [0], [[__line__
-]])
-
-AT_CLEANUP
-
-## -------------- ##
-## unknown option ##
-## -------------- ##
-
-AT_SETUP([unknown option])
-
-AT_CHECK_M4([--unknown], [1], [], [stderr])
-AT_CHECK([$SED 's/Try.*help/Try `m4 --help/' stderr], [0],
-[[m4: bad option
-Try `m4 --help' for more information.
-]])
-
-AT_CLEANUP
-
-
-## --------- ##
-## debugfile ##
-## --------- ##
-
-AT_SETUP([--debugfile])
-
-dnl For a while, CVS m4 mistakenly sent debug output to stdout
-dnl when stdout and stderr were the same file.
-
-AT_DATA([[in]], [[foo
-]])
-
-AT_CHECK_M4([--debugfile=trace1 -tfoo -Dfoo=bar in 2>&1], [0], [[bar
-]])
-
-AT_CHECK_M4([--debugfile=trace2 -tfoo -Dfoo=bar in], [0], [[bar
-]])
-
-AT_CHECK([cmp trace1 trace2])
-
-dnl m4 1.4.x mistakenly created the trace file. --help and --version
-dnl should always override, even if they come later in the command line
-AT_CHECK_M4([--debugfile=trace3 --help], [0], [ignore])
-AT_CHECK_M4([--debugfile=trace3 --version], [0], [ignore])
-AT_CHECK([test -f trace3], [1])
-
-dnl check that trace file failure causes an error, but allows processing
-AT_CHECK_M4([--debugfile=no_such_dir/trace -tfoo -Dfoo=bar in], [1],
-[[bar
-]], [[m4: cannot set debug file 'no_such_dir/trace': No such file or directory
-m4trace: -1- foo -> `bar'
-]])
-
-dnl check that empty trace file discards trace data
-AT_CHECK_M4([--debugfile= -tfoo -Dfoo=bar in], [0],
-[[bar
-]])
-
-dnl check that all tracing gets diverted to the trace file. Don't use
-dnl AT_CHECK_M4 on the first run, because sanitizing stderr breaks the
-dnl comparison with the raw data in the trace file of the second run.
-AT_CHECK([$M4 -dV in], [0], [[foo
-]], [stderr])
-mv stderr expout
-AT_CHECK_M4([--debugfile=trace4 -dV in], [0], [[foo
-]])
-AT_CHECK([cat trace4], [0], [expout])
-
-dnl check that order matters
-AT_DATA([in1], [[bar
-]])
-AT_DATA([in2], [[errprint(`hi
-')dnl
-bar
-]])
-AT_CHECK_M4([-Dbar=hello -tbar --debugfile= in1 --debugfile in2], [0],
-[[hello
-hello
-]], [[hi
-m4trace: -1- bar -> `hello'
-]])
-
-AT_CLEANUP
-
-
-## -------- ##
-## debuglen ##
-## -------- ##
-
-AT_SETUP([--debuglen])
-
-dnl Check for argument validation.
-
-AT_DATA([in],
-[[define(`echo', `$@')dnl
-traceon(`echo')dnl
-echo(`long string')
-]])
-
-AT_CHECK_M4([--debuglen=-1 in], [1], [],
-[[m4: invalid --debuglen argument '-1'
-]])
-
-AT_CHECK_M4([--debuglen oops in], [1], [],
-[[m4: invalid --debuglen argument 'oops'
-]])
-
-AT_CHECK_M4([-l 10oops in], [1], [],
-[[m4: invalid suffix in -l argument '10oops'
-]])
-
-dnl MiB is the suffix to implict 1, resulting in 1048576
-AT_CHECK_M4([-lMiB in], [0], [[long string
-]], [[m4trace: -1- echo(`long string') -> ``long string''
-]])
-
-dnl this assumes size_t is no bigger than 64 bits
-AT_CHECK_M4([-l 123456789012345678901234567890 in], [1], [],
-[[m4: -l argument '123456789012345678901234567890' too large
-]])
-AT_CHECK_M4([--debugl 123456789012345678901234567890 in], [1], [],
-[[m4: --debuglen argument '123456789012345678901234567890' too large
-]])
-
-dnl per POSIX guidelines, this is a decimal number 10, not octal 8
-AT_CHECK_M4([-l 010 in], [0], [[long string
-]], [[m4trace: -1- echo(`long strin...') -> ``long stri...'
-]])
-
-AT_CHECK_M4([-l 3 in], [0], [[long string
-]], [[m4trace: -1- echo(`lon...') -> ``lo...'
-]])
-
-AT_CHECK_M4([--debuglen=3 -l0 in], [0], [[long string
-]], [[m4trace: -1- echo(`long string') -> ``long string''
-]])
-
-AT_CLEANUP
-
-
-## --------- ##
-## debugmode ##
-## --------- ##
-
-AT_SETUP([--debugmode])
-
-AT_DATA([[in]],
-[[include(`nested')dnl
-len(`abc')
-]])
-
-AT_DATA([[nested]],
-[[m4wrap(`divnum
-')dnl
-]])
-
-dnl AT_CHECK_M4 starts life with -d. Make sure it looks like -d+adeq.
-AT_CHECK_M4([-tlen in], [0], [[3
-0
-]], [[m4trace: -1- len(`abc') -> `3'
-]])
-
-AT_CHECK_M4([-tlen -dfl -d in], [0], [[3
-0
-]], [[m4trace:in:2: -1- len(`abc') -> `3'
-]])
-
-dnl -d after file is deferred (but this is still useful for some flags).
-AT_CHECK_M4([-tlen in -dfli], [0], [[3
-0
-]], [[m4trace: -1- len(`abc') -> `3'
-m4debug: input from m4wrap recursion level 1
-m4debug: input from m4wrap exhausted
-]])
-
-dnl Test all flags.
-AT_CHECK_M4([-dV in], [0], [[3
-0
-]], [[m4debug: module m4: opening file
-m4debug: module m4: init hook called
-m4debug: module m4: opened
-m4debug: module m4: builtins loaded
-m4debug: module gnu: opening file
-m4debug: module gnu: init hook called
-m4debug: module gnu: opened
-m4debug: module gnu: builtins loaded
-m4debug: module gnu: macros loaded
-m4debug: path search for 'in' found 'in'
-m4debug: input read from 'in'
-m4trace:in:1: -1- id 1: include ... = <include>{m4}
-m4debug:in:1: path search for 'nested' found 'nested'
-m4debug:in:1: input read from 'nested'
-m4trace:in:1: -1- id 1: include(`nested') -> <file: nested>
-m4trace:nested:1: -1- id 2: m4wrap ... = <m4wrap>{m4}
-m4trace:nested:1: -1- id 2: m4wrap(`divnum
-') -> `'
-m4trace:nested:2: -1- id 3: dnl ... = <dnl>{m4}
-m4trace:nested:2: -1- id 3: dnl -> `'
-m4debug:nested:3: input reverted to in, line 1
-m4trace:in:1: -1- id 4: dnl ... = <dnl>{m4}
-m4trace:in:1: -1- id 4: dnl -> `'
-m4trace:in:2: -1- id 5: len ... = <len>{m4}
-m4trace:in:2: -1- id 5: len(`abc') -> `3'
-m4debug:in:3: input exhausted
-m4debug: input from m4wrap recursion level 1
-m4trace:nested:1: -1- id 6: divnum ... = <divnum>{m4}
-m4trace:nested:1: -1- id 6: divnum -> `0'
-m4debug: input from m4wrap exhausted
-]])
-
-dnl Test addition and subtraction of flags.
-AT_CHECK_M4([--debug=-e --debugmode=+xt in], [0], [[3
-0
-]], [[m4trace: -1- id 1: include(`nested')
-m4trace: -1- id 2: m4wrap(`divnum
-')
-m4trace: -1- id 3: dnl
-m4trace: -1- id 4: dnl
-m4trace: -1- id 5: len(`abc')
-m4trace: -1- id 6: divnum
-]])
-
-dnl Test that shorter prefix is ambiguous.
-AT_CHECK_M4([--debu], [1], [], [stderr])
-AT_CHECK([$SED -e 's/Try.*--help/Try `m4 --help/' stderr], [0],
-[[m4: bad option
-Try `m4 --help' for more information.
-]])
-
-AT_CLEANUP
-
-
-## ---------------- ##
-## discard comments ##
-## ---------------- ##
-
-AT_SETUP([--discard-comments])
-
-AT_DATA([[in]],
-[[This is not a comment # but this is.
-# This line should disappear completely.
-This should not disappear.
-changecom(`<!--', `-->')
-html <!--
-comment
- --> ends.
-]])
-
-AT_CHECK_M4([-c in], [0],
-[[This is not a comment This should not disappear.
-
-html ends.
-]])
-
-dnl check that even when discarding, a comment must be terminated by EOF
-AT_DATA([in], [[changecom(`/*', `*/')dnl
-/* unterminated comment
-]])
-AT_CHECK_M4([--discard-comments in], [1], [],
-[[m4:in:2: end of file in comment
-]])
-
-AT_CLEANUP
-
-
-## -------------- ##
-## fatal warnings ##
-## -------------- ##
-
-AT_SETUP([--fatal-warnings])
-
-AT_DATA([[in]],
-[[dnl()
-dnl()
-dnl()
-]])
-
-dnl By default, warnings don't affect exit status
-AT_CHECK_M4([in], [0], [],
-[[m4:in:1: warning: dnl: extra arguments ignored: 1 > 0
-m4:in:2: warning: dnl: extra arguments ignored: 1 > 0
-m4:in:3: warning: dnl: extra arguments ignored: 1 > 0
-]])
-
-dnl With one -E, exit status changes, but execution continues
-AT_CHECK_M4([-E in], [1], [],
-[[m4:in:1: warning: dnl: extra arguments ignored: 1 > 0
-m4:in:2: warning: dnl: extra arguments ignored: 1 > 0
-m4:in:3: warning: dnl: extra arguments ignored: 1 > 0
-]])
-
-dnl With two -E, execution halts immediately
-AT_CHECK_M4([--fatal-warnings --fatal-warnings in], [1], [],
-[[m4:in:1: warning: dnl: extra arguments ignored: 1 > 0
-]])
-
-dnl Exit status can't be affected if there were no warnings
-AT_CHECK_M4([-EEQ in], [0])
-
-AT_CLEANUP
-
-
-## ---------------- ##
-## help and version ##
-## ---------------- ##
-
-AT_SETUP([--help and --version])
-
-AT_CHECK_M4([--help], [0], [stdout])
-AT_CHECK([[$SED -n -e 's|Usage:.*\[OPTION\]... \[FILE\]...|success|p' stdout]],
-[0], [success
-])
-
-AT_CHECK_M4([--version], [0], [stdout])
-AT_CHECK([[$SED -n -e 's|There is NO WARRANTY.*|success|p' stdout]],
-[0], [success
-])
-
-dnl make sure option specified first takes precedence
-AT_CHECK_M4([--help --version], [0], [stdout])
-AT_CHECK([[$SED -n -e 's|Usage:.*\[OPTION\]... \[FILE\]...|success|p' stdout]],
-[0], [success
-])
-
-AT_CHECK_M4([--version --help], [0], [stdout])
-AT_CHECK([[$SED -n -e 's|There is NO WARRANTY.*|success|p' stdout]],
-[0], [success
-])
-
-AT_CLEANUP
-
-
-## ------------------ ##
-## import-environment ##
-## ------------------ ##
-
-AT_SETUP([--import-environment])
-
-AT_DATA([[in]],
-[[`TEST'=TEST
-`ZAPPED'=ZAPPED
-`OVERRIDE'=OVERRIDE
-]])
-
-TEST='This is an environment variable'
-export TEST
-
-ZAPPED='This is an environment variable which we will delete'
-export ZAPPED
-
-OVERRIDE='This is an environment variable which we will change'
-export OVERRIDE
-
-AT_CHECK_M4([--import-environment -UZAPPED -DOVERRIDE='It is changed.' in],
-[0], [[TEST=This is an environment variable
-ZAPPED=ZAPPED
-OVERRIDE=It is changed.
-]])
-
-AT_CLEANUP
-
-
-## ------------- ##
-## nesting-limit ##
-## ------------- ##
-
-AT_SETUP([--nesting-limit])
-
-dnl Check for argument validation.
-
-AT_DATA([in],
-[[define(`echo', `$@')dnl
-echo(echo(echo(echo(`nested string'))))
-echo(echo(echo(echo(echo(echo(echo(echo(echo(`nested string')))))))))
-]])
-
-AT_CHECK_M4([--nesting-limit=-1 in], [1], [],
-[[m4: invalid --nesting-limit argument '-1'
-]])
-
-AT_CHECK_M4([--nesting-limit oops in], [1], [],
-[[m4: invalid --nesting-limit argument 'oops'
-]])
-
-AT_CHECK_M4([-L 10oops in], [1], [],
-[[m4: invalid suffix in -L argument '10oops'
-]])
-
-dnl MiB is the suffix to implict 1, resulting in 1048576
-AT_CHECK_M4([-LMiB in], [0], [[nested string
-nested string
-]])
-
-dnl this assumes size_t is no bigger than 64 bits
-AT_CHECK_M4([-L 123456789012345678901234567890 in], [1], [],
-[[m4: -L argument '123456789012345678901234567890' too large
-]])
-AT_CHECK_M4([--nest 123456789012345678901234567890 in], [1], [],
-[[m4: --nesting-limit argument '123456789012345678901234567890' too large
-]])
-
-AT_CHECK_M4([-L 5 in], [1], [[nested string
-]],
-[[m4:in:3: recursion limit of 5 exceeded, use -L<N> to change it
-]])
-
-dnl per POSIX guidelines, this is a decimal number 10, not octal 8
-AT_CHECK_M4([-L 010 in], [0], [[nested string
-nested string
-]])
-
-AT_CHECK_M4([--nesting-limit=3 -L0 in], [0], [[nested string
-nested string
-]])
-
-AT_CLEANUP
-
-
-## --------------- ##
-## prepend-include ##
-## --------------- ##
-
-AT_SETUP([--prepend-include])
-
-dnl Lots of data to set up.
-AT_DATA([[in]],
-[[include(`foo')dnl
-include(`bar')dnl
-include(`bad')dnl
-include(`blah')dnl
-]])
-
-AT_CHECK([mkdir pre post])
-
-AT_DATA([[pre/foo]], [[in pre/foo
-]])
-AT_DATA([[foo]], [[in ./foo
-]])
-AT_DATA([[bar]], [[in ./bar
-]])
-AT_DATA([[post/bar]], [[in post/bar
-]])
-AT_DATA([[post/blah]], [[in post/blah
-]])
-
-dnl Make circular links in the subdirectories, to ensure that the error
-dnl message when bad cannot be opened comes from the search in ., regardless
-dnl of what else was searched.
-AT_CHECK([ln -s bad pre/bad])
-AT_CHECK([ln -s bad post/bad])
-
-dnl Finally, see that it all works.
-AT_CHECK_M4([-I post -B pre in], [1],
-[[in pre/foo
-in ./bar
-in post/blah
-]], [[m4:in:3: include: cannot open file 'bad': No such file or directory
-]])
-
-AT_CLEANUP
-
-
-## ------------- ##
-## regexp-syntax ##
-## ------------- ##
-
-AT_SETUP([--regexp-syntax])
-
-dnl test argument validation
-
-AT_DATA([[in]], [[regexp(`(', `(')
-]])
-
-AT_CHECK_M4([--regexp-syntax=unknown in], [1], [],
-[[m4: bad syntax-spec: 'unknown'
-]])
-
-AT_CHECK_M4([--regexp-syntax= in], [0], [[0
-]])
-
-AT_CHECK_M4([-rEXTENDED in], [0], [[
-]], [[m4:in:1: warning: regexp: bad regular expression '(': Unmatched ( or \(
-]])
-
-AT_CHECK_M4([-rgnu-m4 in], [0], [[0
-]])
-
-AT_CHECK_M4([-r"gnu M4" in], [0], [[0
-]])
-
-dnl Test behavior of -r intermixed with files
-AT_CHECK_M4([-rEXTENDED in --regexp-syntax in], [0], [[
-0
-]], [[m4:in:1: warning: regexp: bad regular expression '(': Unmatched ( or \(
-]])
-
-AT_CLEANUP
-
-
-## ----- ##
-## safer ##
-## ----- ##
-
-AT_SETUP([--safer])
-
-dnl with --safer, the debugfile macro is crippled, but --debugfile is not
-AT_DATA([[in]],
-[[define(`foo', `1')foo
-debugfile(`trace2')
-define(`foo', `2')foo
-]])
-
-AT_CHECK_M4([--safer --debugfile=trace1 -t foo in], [1],
-[[1
-
-2
-]], [[m4:in:2: debugfile: disabled by --safer
-]])
-
-AT_CHECK([test -f trace2], [1])
-AT_CHECK([cat trace1], [0],
-[[m4trace: -1- foo -> `1'
-m4trace: -1- foo -> `2'
-]])
-
-dnl make sure builtin cannot bypass --safer, and that mkstemp does not
-dnl create file
-AT_DATA([[in]], [[builtin(`mkstemp', `./fooXXXXXX')
-]])
-
-AT_CHECK([echo foo*], [0], [foo*
-])
-
-AT_CHECK_M4([--safer in], [1], [[
-]], [[m4:in:1: mkstemp: disabled by --safer
-]])
-
-AT_CHECK([echo foo*], [0], [foo*
-])
-
-AT_CLEANUP
-
-
-## ---------- ##
-## syncoutput ##
-## ---------- ##
-
-AT_SETUP([--syncoutput])
-
-dnl -s/--synclines implies --syncoutput=1
-AT_DATA([in], [[hi
-]])
-AT_CHECK_M4([-s in], [0],
-[[#line 1 "in"
-hi
-]])
-AT_CHECK_M4([--synclines in], [0],
-[[#line 1 "in"
-hi
-]])
-
-dnl test intermixing option and files
-AT_CHECK_M4([in --syncoutput=1 in --syncoutput in], [0],
-[[hi
-#line 1 "in"
-hi
-hi
-]])
-
-dnl test parse error
-AT_CHECK_M4([--syncoutput=huh in], [0],
-[[hi
-]], [[m4: warning: --syncoutput: unknown directive 'huh'
-]])
-
-AT_CLEANUP
-
-AT_SETUP([--syncoutput and diversions])
-
-dnl synclines should always start at the beginning of a line.
-dnl this does not (yet) happen reliably when diversions do not
-dnl always end in newline
-AT_XFAIL_IF([:])
-AT_DATA([in.m4], [[divert(2)2divert(1)1
-dnl
-undivert
-]])
-
-AT_CHECK_M4([-s in.m4], [0], [[1
-#line 1 "stdin"
-2
-]])
-
-AT_CLEANUP
-
-
-## -------------------- ##
-## traceon and traceoff ##
-## -------------------- ##
-
-AT_SETUP([--traceon and --traceoff])
-
-dnl test intermixing with files
-AT_DATA([[in]], [[divnum
-]])
-AT_CHECK_M4([-d+x in --traceon=divnum in --traceoff=divnum in], [0],
-[[0
-0
-0
-]], [[m4trace: -1- id 2: divnum -> `0'
-]])
-
-dnl test that --traceoff does not warn on untraced name
-AT_CHECK_M4([--traceoff=unknown], [0])
-
-AT_CLEANUP
diff --git a/tests/others.at b/tests/others.at
deleted file mode 100644
index 1b035eb4..00000000
--- a/tests/others.at
+++ /dev/null
@@ -1,980 +0,0 @@
-# Hand crafted tests for GNU M4. -*- Autotest -*-
-# Copyright (C) 2001, 2006-2010, 2013-2014, 2017 Free Software
-# Foundation, Inc.
-
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-AT_BANNER([Composite macros and other tests.])
-
-
-## ---------- ##
-## capitalize ##
-## ---------- ##
-
-AT_TEST_M4([Capitalize],
-[[dnl
-dnl convert to upper- resp. lowercase
-define(`upcase', `translit(`$*', `a-z', `A-Z')')
-define(`downcase', `translit(`$*', `A-Z', `a-z')')
-upcase(`Convert to upper case')
-downcase(`Convert To LOWER Case')
-dnl
-dnl capitalize a single word
-define(`capitalize1', `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')
-define(`capitalize', `patsubst(`$1', `\w+', ``'capitalize1(`\&')')')
-capitalize(`This sentence should be capitalized')
-]],
-[[
-
-CONVERT TO UPPER CASE
-convert to lower case
-
-
-This Sentence Should Be Capitalized
-]])
-
-
-
-## -------- ##
-## comments ##
-## -------- ##
-
-AT_SETUP([Comments])
-
-AT_DATA([input.m4],
-[[# An ordinary comment
-define(`foo', # A comment in a macro
-`Macro `foo' expansion')
-foo
-define(`comment', `*** Macro `comment' expansion ***')
-changecom(`@', `@')
-foo
-]])
-
-AT_CHECK_M4([input.m4], [0],
-[[# An ordinary comment
-
-# A comment in a macro
-Macro foo expansion
-
-
-# A *** Macro comment expansion *** in a macro
-Macro foo expansion
-]])
-
-dnl Detect regression in 1.4.10b in regards to reparsing comments.
-AT_DATA([input.m4],
-[[define(`e', `$@')define(`q', ``$@'')define(`foo', `bar')
-q(e(`one
-',#two ' foo
-))
-changecom(`<', `>')define(`n', `$#')
-n(e(<`>, <'>))
-len(e(<`>, ,<'>))
-]])
-
-AT_CHECK_M4([input.m4], [0],
-[[
-`one
-',`#two bar
-''
-
-1
-12
-]])
-
-AT_CLEANUP
-
-## --------- ##
-## countdown ##
-## --------- ##
-
-AT_SETUP([countdown])
-
-AT_DATA([[exp.m4]],
-[[define(`countdown', `$1
-ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Done')')dnl
-countdown(7)
-]])
-
-AT_CHECK_M4([exp.m4], 0,
-[[7
-6
-5
-4
-3
-2
-1
-0
-Done
-]])
-
-AT_CLEANUP
-
-
-## --------- ##
-## directory ##
-## --------- ##
-
-AT_SETUP([directory])
-
-AT_DATA([in1.m4],
-[[include(`in2.m4/')
-]])
-AT_DATA([in2.m4],
-[[sinclude(`in2.m4/')
-sinclude(`.')
-]])
-AT_DATA([in3.m4],
-[[include(`.')
-]])
-
-AT_CHECK_M4([in1.m4/], [1], [], [stderr])
-dnl mingw fails with EINVAL rather than the expected ENOTDIR
-AT_CHECK([$SED 's/Invalid argument/Not a directory/' stderr], [0],
-[[m4: cannot open file 'in1.m4/': Not a directory
-]])
-
-AT_CHECK_M4([in1.m4], [1], [[
-]], [stderr])
-dnl mingw fails with EINVAL rather than the expected ENOTDIR
-AT_CHECK([$SED 's/Invalid argument/Not a directory/' stderr], [0],
-[[m4:in1.m4:1: include: cannot open file 'in2.m4/': Not a directory
-]])
-
-AT_CHECK_M4([in2.m4], [0], [[
-
-]])
-
-AT_CHECK_M4([in3.m4], [1], [[
-]], [stderr])
-dnl mingw fails with EACCES rather than the expected EISDIR
-AT_CHECK([$SED 's/Permission denied/Is a directory/' stderr], [0],
-[[m4:in3.m4:1: include: cannot open file '.': Is a directory
-]])
-
-AT_CLEANUP
-
-
-## ------- ##
-## foreach ##
-## ------- ##
-
-AT_SETUP([foreach])
-
-AT_DATA([[foreach.m4]],
-[[divert(-1)
-# foreach(x, (item_1, item_2, ..., item_n), stmt)
-define(`foreach', `pushdef(`$1', `')_foreach($@)popdef(`$1')')
-define(`_arg1', ``$1'')
-define(`_foreach',
- `ifelse($2, `()', ,
- `define(`$1', `_arg1$2')$3`'_foreach(`$1', `(shift$2)', `$3')')')
-
-# traceon(`define', `foreach', `_foreach', `ifelse')
-
-define(a, 1)
-define(b, 2)
-define(c, 3)
-divert
-foreach(`x', `(foo, bar, foobar)', `Word was: x
-')
-
-# Quote torture from Akim Demaille <akim@epita.fr>
-foreach(`x', `(`a', `(b', `c)')', `Word was: x
-')
-
-# Something more complex, from Pierre Gaumond <gaumondp@ere.umontreal.ca>.
-define(`case', ` $1)
- $2=" -$1";;
-')dnl
-define(`_cat', `$1$2')dnl
-`case' "$1" in
-foreach(`x', ((a, vara), (b, varb), (c, varc)), `_cat(`case', x)')dnl
-esac
-]])
-
-AT_CHECK_M4([foreach.m4], 0,
-[[
-Word was: foo
-Word was: bar
-Word was: foobar
-
-
-# Quote torture from Akim Demaille <akim@epita.fr>
-Word was: a
-Word was: (b
-Word was: c)
-
-
-# Something more complex, from Pierre Gaumond <gaumondp@ere.umontreal.ca>.
-case "$1" in
- 1)
- vara=" -1";;
- 2)
- varb=" -2";;
- 3)
- varc=" -3";;
-esac
-]])
-
-AT_CLEANUP
-
-
-
-## ------- ##
-## forloop ##
-## ------- ##
-
-AT_SETUP([forloop])
-
-AT_DATA([[forloop.m4]],
-[[divert(-1)
-# forloop(i, from, to, stmt)
-
-define(`forloop', `pushdef(`$1', `$2')_forloop(`$1', `$2', `$3', `$4')popdef(`$1')')
-define(`_forloop',
- `$4`'ifelse($1, `$3', ,
- `define(`$1', incr($1))_forloop(`$1', `$2', `$3', `$4')')')
-divert
-forloop(`x', 1, 10, `2**x = eval(2**x)
-')
-]])
-
-AT_CHECK_M4([forloop.m4], 0,
-[[
-2**1 = 2
-2**2 = 4
-2**3 = 8
-2**4 = 16
-2**5 = 32
-2**6 = 64
-2**7 = 128
-2**8 = 256
-2**9 = 512
-2**10 = 1024
-
-]])
-
-AT_CLEANUP
-
-
-
-## ----- ##
-## fstab ##
-## ----- ##
-
-AT_SETUP([fstab])
-
-AT_DATA([[fstab.m4]],
-[[define(`concat', `translit(``$*'', ` ')')
-define(`fsent', `format(`%-25s %-16s nfs %-16s 0 0', `$1:$2', `$3', concat$4)')
-
-fsent(freja, /home/gevn, /home/gevn, (rw, soft, bg, grpid))
-fsent(freja, /home/freja, /home/freja, (rw, soft, grpid))
-fsent(rimfaxe, /home/rimfaxe, /home/rimfaxe, (rw, soft, bg))
-
-]])
-
-AT_CHECK_M4([fstab.m4], 0,
-[[
-
-
-freja:/home/gevn /home/gevn nfs rw,soft,bg,grpid 0 0
-freja:/home/freja /home/freja nfs rw,soft,grpid 0 0
-rimfaxe:/home/rimfaxe /home/rimfaxe nfs rw,soft,bg 0 0
-
-]])
-
-AT_CLEANUP
-
-
-
-## ----- ##
-## hanoi ##
-## ----- ##
-
-AT_SETUP([hanoi])
-
-AT_DATA([[hanoi.m4]],
-[[divert(-1)
-
-# move(from, to)
-define(`move', `Move one disk from `$1' to `$2'.
-')
-
-# _hanoi (cnt, from, to, aux)
-define(`_hanoi', `ifelse(eval(`$1'<=1), 1, `move($2, $3)',
-`_hanoi(decr($1), $2, $4, $3)move($2, $3)_hanoi(decr($1), $4, $3, $2)')')
-
-# hanoi (cnt)
-define(`hanoi', `_hanoi(`$1', source, destination, auxilliary)')
-
-# traceon(`move', `_hanoi', `decr')
-divert`'dnl
-
-hanoi(3)
-]])
-
-AT_CHECK_M4([hanoi.m4], 0,
-[[
-Move one disk from source to destination.
-Move one disk from source to auxilliary.
-Move one disk from destination to auxilliary.
-Move one disk from source to destination.
-Move one disk from auxilliary to source.
-Move one disk from auxilliary to destination.
-Move one disk from source to destination.
-
-]])
-
-AT_CLEANUP
-
-
-## ------ ##
-## ifndef ##
-## ------ ##
-
-AT_SETUP([ifndef])
-
-dnl This catches a bug added 2008-03-13, fixed 2008-04-10.
-AT_DATA([in.m4],
-[[define(`ifndef', `ifdef(`$1', `$3', `$2')')dnl
-define(`a_really_long_name', `1')dnl
-ifdef(`divnum', `yes', `no')
-ifndef(`divnum', `yes', `no')
-ifdef(`ifndef', `yes', `no')
-ifndef(`ifndef', `yes', `no')
-ifdef(`a_really_long_name', `yes', `no')
-ifndef(`a_really_long_name', `yes', `no')
-ifdef(`no_such', `yes', `no')
-ifndef(`no_such', `yes', `no')
-]])
-
-AT_CHECK_M4([in.m4], [0],
-[[yes
-no
-yes
-no
-yes
-no
-no
-yes
-]])
-
-AT_CLEANUP
-
-
-## ------- ##
-## iso8859 ##
-## ------- ##
-
-AT_SETUP([iso8859])
-
-# Eh eh eh...
-# We can't embed iso8859.m4 in here since it includes a NUL character,
-# and we can't yet rely on autom4te being NUL-clean (even though this
-# test shows that M4 is trying to be NUL-clean).
-
-AT_DATA([[expout]],
-[[# Testing quotes
-DEFINE # eol
-CHANGEQUOTE(«,») # eol
-0 TEST # TEST
-1 test # test
-2 «test» # «test»
-3 ««test»» # ««test»»
-CHANGEQUOTE(«««,»»») # eol
-0 TEST # TEST
-1 «TEST» # «TEST»
-2 ««TEST»» # ««TEST»»
-3 test # test
-# Test use of all iso8859 characters except ^Z (win32 EOF) and NUL ` '
-Length of string is: 254
-Comparing strings: MATCH
-# NUL passes through now!
-42
-]])
-
-AT_CHECK_M4(["$abs_srcdir/iso8859.m4"], 0, expout)
-
-AT_CLEANUP
-
-
-## ------------- ##
-## nul character ##
-## ------------- ##
-
-AT_SETUP([nul character])
-
-# Operating on a binary file is a GNU sed extension.
-AT_CHECK([test `printf 'a\0b\n' | $SED s/a.b/abc/ | wc -c` = 4 dnl
-|| { echo "skipping: $SED can't handle NUL"; exit 77; }])
-
-# We don't embed null.* in here, since it is harder to guarantee the
-# behavior of NUL through autom4te.
-$SED "s|null.m4|$abs_srcdir/null.m4|" < "$abs_srcdir/null.out" > expout
-$SED "s|null.m4|$abs_srcdir/null.m4|" < "$abs_srcdir/null.err" > experr
-
-dnl all but m4exit
-AT_CHECK_M4([-Dm4exit -I "$abs_srcdir" null.m4], [1], [expout], [experr])
-
-dnl just m4exit
-AT_CHECK_M4(["$abs_srcdir/null.m4"], [1],
-[[# This file tests m4 behavior on NUL bytes.
-]], [stderr])
-AT_CHECK([sed "s|$abs_srcdir/||" stderr], [0],
-[[m4:null.m4:5: warning: m4exit: non-numeric argument '2\0002'
-]])
-
-AT_CLEANUP
-
-
-## --------- ##
-## recursion ##
-## --------- ##
-
-AT_SETUP([recursion])
-
-dnl This input exploits contents of loop.m4 to print out the final value
-dnl of the recursion.
-AT_DATA([in.m4],
-[[define(`foo', `divert`'len(popdef(`_foreachq')_foreachq($@))')dnl
-define(`debug', `pushdef(`_foreachq', defn(`foo'))')dnl
-include(`loop.m4')dnl
-]])
-
-dnl boxed recursion
-AT_CHECK_M4([-I "$top_srcdir/doc/examples" -Dlimit=10 -Dverbose loop.m4], [0],
-[[ 1 2 3 4 5 6 7 8 9 10
-]])
-AT_CHECK_M4([-I "$top_srcdir/doc/examples" -Dlimit=2500 loop.m4], [0])
-AT_CHECK_M4([-I "$top_srcdir/doc/examples" -Dlimit=10000 in.m4], [0], [[48894
-]])
-
-dnl unboxed recursion
-AT_CHECK_M4([-I "$top_srcdir/doc/examples" -Dlimit=10 -Dverbose -Dalt loop.m4], [0],
-[[ 1 2 3 4 5 6 7 8 9 10
-]])
-AT_CHECK_M4([-I "$top_srcdir/doc/examples" -Dlimit=2500 -Dalt loop.m4], [0])
-AT_CHECK_M4([-I "$top_srcdir/doc/examples" -Dlimit=10000 -Dalt in.m4], [0],
-[[48894
-]])
-
-dnl foreach via forloop recursion
-AT_CHECK_M4([-I "$top_srcdir/doc/examples" -Dlimit=10 -Dverbose -Dalt=4 loop.m4],
-[0], [[ 1 2 3 4 5 6 7 8 9 10
-]])
-AT_CHECK_M4([-I "$top_srcdir/doc/examples" -Dlimit=2500 -Dalt=4 loop.m4], [0])
-AT_CHECK_M4([-I "$top_srcdir/doc/examples" -Dlimit=10000 -Dalt=4 in.m4], [0],
-[[48894
-]])
-
-dnl foreach via definition stack
-AT_DATA([in.m4], [[include(`forloop3.m4')include(`stack_sep.m4')dnl
-forloop(`i', `1', `10000', `pushdef(`s', i)')dnl
-define(`colon', `:')define(`dash', `-')dnl
-len(stack_foreach_sep(`s', `dash', `', `colon'))
-]])
-AT_CHECK_M4([-I "$top_srcdir/doc/examples" in.m4], [0], [[58893
-]])
-
-AT_CLEANUP
-
-
-## ------- ##
-## reverse ##
-## ------- ##
-
-AT_SETUP([reverse])
-
-AT_DATA([[reverse.m4]],
-[[define(`reverse', `ifelse(eval($# > 1), 1, `reverse(shift($@)), `$1'', ``$1'')')
-``'' => reverse.
-``hej'' => reverse(hej).
-``hej, med, dig'' => reverse(hej, med, dig).
-]])
-
-AT_CHECK_M4([reverse.m4], 0,
-[[
-`' => .
-`hej' => hej.
-`hej, med, dig' => dig, med, hej.
-]])
-
-AT_CLEANUP
-
-
-## ------------- ##
-## stderr closed ##
-## ------------- ##
-
-AT_SETUP([stderr closed])
-
-dnl no error when stderr is not used
-AT_CHECK_M4([2>&-], [0])
-
-dnl no error when stderr is not used
-AT_DATA([in.m4], [[hello world
-]])
-AT_CHECK_M4([2>&-], [0], [[hello world
-]], [], [in.m4])
-
-dnl must exit nonzero when error issued
-AT_CHECK_M4([--unknown 2>&-], [1])
-
-dnl must exit nonzero if stderr used
-AT_DATA([in.m4], [[errprint(`hello world
-')dnl
-]])
-AT_CHECK_M4([2>&-], [1], [], [], [in.m4])
-
-dnl must exit nonzero if stderr used
-AT_DATA([in.m4], [[hello
-dnl(`world')
-]])
-AT_CHECK_M4([2>&-], [1], [[hello
-]], [], [in.m4])
-
-dnl must exit nonzero on error, in spite of m4exit requesting 0
-AT_DATA([in.m4], [[errprint(`hello world
-')m4exit(`0')
-]])
-AT_CHECK_M4([2>&-], [1], [], [], [in.m4])
-
-dnl preserve m4exit's failure value
-AT_DATA([in.m4], [[errprint(`hello world
-')m4exit(`2')
-]])
-AT_CHECK_M4([2>&-], [2], [], [], [in.m4])
-
-dnl trace file must not collide with closed stderr
-AT_DATA([in.m4], [[errprint(`hello world
-')dnl
-]])
-AT_CHECK_M4([--debugfile=trace -terrprint 2>&-], [1], [], [], [in.m4])
-AT_CHECK([cat trace], [0], [[m4trace: -1- errprint(`hello world
-') -> `'
-]])
-
-dnl spilled diversion file must not collide with closed stderr
-AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(1)f
-and`'dnl(not)
-divert
-hello`'dnl(world)
-undivert
-goodbye
-]])
-AT_CHECK_M4([2>&-], [1], [stdout-nolog], [], [in.m4])
-AT_CHECK([$SED -ne '/./p' stdout], [0],
-[[hello
-and
-goodbye
-]])
-
-dnl command line input file must not collide with closed stderr
-AT_DATA([in.m4], [[syscmd(`echo <&2')ifelse(sysval,
-`0', `skipping: sh cannot detect closed fds
-m4exit(`77')')
-]])
-AT_CHECK_M4([2>&-], [0], [ignore], [ignore], [in.m4])
-AT_DATA([in.m4], [[syscmd(`cat <&2')sysval
-dnl this line should not be read by cat
-]])
-AT_CHECK_M4([2>&-], [0], [[1
-]], [], [in.m4])
-AT_CHECK_M4([in.m4 2>&-], [0], [[1
-]])
-
-AT_CLEANUP
-
-
-## ------------ ##
-## stdin closed ##
-## ------------ ##
-
-AT_SETUP([stdin closed])
-
-dnl no error when stdin is not used due to early exit
-AT_CHECK_M4([--version], [0], [ignore], [], [-])
-
-dnl no error when stdin is not used due to supplied file
-AT_DATA([in.m4], [[hello world
-]])
-AT_CHECK_M4([in.m4], [0], [[hello world
-]], [], [-])
-
-dnl Some systems reopen closed stdin to /dev/null, particularly when using
-dnl the shell script tests/m4 instead of a binary src/m4.
-AT_CHECK([cat <&- && { echo "skipping: can't detect closed stdin"; exit 77; }],
-[1], [], [stderr])
-mv stderr experr
-AT_DATA([in.m4], [[syscmd(`cat')ifelse(sysval,
-`0', `skipping: unable to start with closed stdin
-m4exit(`77')')
-]])
-AT_CHECK_M4([in.m4], [0], [ignore], [ignore], [-])
-
-dnl error when stdin must be read
-AT_CHECK_M4([], [1], [],
-[[m4:stdin:1: error reading 'stdin'
-m4: error closing file: Bad file descriptor
-]], [-])
-
-dnl error when stdin must be read
-AT_CHECK_M4([-], [1], [],
-[[m4:stdin:1: error reading 'stdin'
-m4: error closing file: Bad file descriptor
-]], [-])
-
-dnl error once per command-line attempt to read stdin
-AT_DATA([in.m4], [[hello world
-]])
-AT_CHECK_M4([- in.m4 -], [1], [[hello world
-]], [[m4:stdin:1: error reading 'stdin'
-m4:stdin:1: error reading 'stdin'
-m4: error closing file: Bad file descriptor
-]], [-])
-
-dnl command line and trace file must not collide with stdin
-AT_DATA([in.m4], [[syscmd(`cat')dnl
-]])
-AT_CHECK_M4([--debugfile=trace -tdnl in.m4], [0], [], [experr], [-])
-AT_CHECK([cat trace], [0], [[m4trace: -1- dnl -> `'
-]])
-
-dnl diversions must not collide with stdin
-AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(`1')f
-syscmd(`cat')dnl
-divert(`-1')undivert
-]])
-AT_CHECK_M4([in.m4], [0], [], [experr], [-])
-
-dnl diversions must not collide with stdin
-AT_DATA([in.m4], [M4_ONE_MEG_DEFN[hello divert(`1')f
-]])
-AT_DATA([in2.m4], [[divert(`-1')undivert
-divert`'world
-]])
-AT_CHECK_M4([in.m4 - in2.m4], [1], [[hello world
-]], [[m4:stdin:1: error reading 'stdin'
-m4: error closing file: Bad file descriptor
-]], [-])
-
-AT_CLEANUP
-
-## -------------- ##
-## stdin seekable ##
-## -------------- ##
-
-AT_SETUP([stdin seekable])
-
-dnl POSIX requires that if stdin is seekable, m4 must seek to the location
-dnl of unprocessed data for the benefit of other copies of the fd.
-
-dnl Check internal follow-on process.
-AT_DATA([in.m4], [[syscmd(`cat')m4exit(15)
-]])
-AT_CHECK_M4([], [0], [[m4exit(15)
-]], [], [in.m4])
-
-dnl Check external follow-on process, after m4exit.
-AT_DATA([in.m4], [[m4exit(
-0)trailing data
-]])
-AT_CHECK([($M4; cat) < in.m4], [0], [[trailing data
-]])
-
-dnl Check external follow-on process, after fatal error.
-dnl We can't use AT_CHECK_M4, so we must post-process stderr ourselves.
-AT_DATA([in.m4], [[dnl(
-0)trailing data
-]])
-AT_CHECK([($M4 -EE; cat) < in.m4], [0], [[trailing data
-]], [stderr])
-AT_CHECK([[$SED 's/^[^:]*[lt-]*m4[.ex]*:/m4:/' stderr]], [0],
-[[m4:stdin:1: warning: dnl: extra arguments ignored: 1 > 0
-]])
-
-dnl Not all sed and libc combinations get the remaining tests right (for
-dnl example, sed 4.1.4 on glibc, or cygwin 1.5.22 and earlier).
-AT_CHECK([($SED -ne 1q; cat) < in.m4], [0], [stdout])
-AT_CHECK([test "x`cat stdout`" = "x0)trailing data" || \
- { echo "skipping: $SED is too greedy on seekable stdin"; exit 77; }])
-
-dnl Ensure that esyscmd resumes parsing where the child process left off.
-AT_DATA([in.m4], [[define(`foo', `FOO')m4 foo
-esyscmd(`$SED -e "s/foo/bar/;q"')sed foo
-m4 foo
-]])
-AT_CHECK_M4([], [0], [[m4 FOO
-sed bar
-m4 FOO
-]], [], [in.m4])
-
-dnl Ensure that syscmd resumes parsing where the child process left off.
-AT_DATA([in.m4], [[define(`foo', `FOO')m4 foo
-syscmd(`$SED -e "s/foo/bar/;q"')sed foo
-m4 foo
-]])
-AT_CHECK_M4([], [0], [[m4 FOO
-sed bar
-m4 FOO
-]], [], [in.m4])
-
-AT_CLEANUP
-
-## ----------------------- ##
-## stdin and stdout closed ##
-## ----------------------- ##
-
-AT_SETUP([stdin and stdout closed])
-
-dnl no error when only stderr is used
-AT_DATA([in.m4], [[esyscmd(echo hi >&2 && echo err"print(bye
-)d"nl)dnl
-]])
-AT_CHECK_M4([in.m4 >&-], [0], [], [[hi
-bye
-]], [-])
-
-AT_CLEANUP
-
-## ------------- ##
-## stdout closed ##
-## ------------- ##
-
-AT_SETUP([stdout closed])
-
-dnl error when stdout must be used
-AT_CHECK_M4([--version >&-], [1], [],
-[[m4: write error: Bad file descriptor
-]])
-
-dnl no error when stdout is not used
-AT_CHECK_M4([>&-], [0])
-
-dnl no error when stdout is not used
-AT_DATA([in.m4], [[errprint(`hello world
-')dnl
-]])
-AT_CHECK_M4([>&-], [0], [], [[hello world
-]], [in.m4])
-
-dnl error when stdout must be used
-AT_CHECK_M4([-P >&-], [1], [],
-[[m4: write error: Bad file descriptor
-]], [in.m4])
-
-dnl error must occur in spite of m4exit requesting 0
-AT_DATA([in.m4], [[hello world
-m4exit(`0')
-]])
-AT_CHECK_M4([>&-], [1], [],
-[[m4:stdin:2: write error: Bad file descriptor
-]], [in.m4])
-
-dnl preserve m4exit's failure value
-AT_DATA([in.m4], [[hello world
-m4exit(`2')
-]])
-AT_CHECK_M4([>&-], [2], [],
-[[m4:stdin:2: write error: Bad file descriptor
-]], [in.m4])
-
-dnl trace file must not collide with closed stdout
-AT_DATA([in.m4], [[hello world
-dnl
-]])
-AT_CHECK_M4([--debugfile=trace -tdnl >&-], [1], [],
-[[m4: write error: Bad file descriptor
-]], [in.m4])
-AT_CHECK([cat trace], [0], [[m4trace: -1- dnl -> `'
-]])
-
-dnl esyscmd always has valid stdout
-AT_DATA([in.m4], [[errprint(esyscmd(`echo hello'))dnl
-]])
-AT_CHECK_M4([>&-], [0], [], [[hello
-]], [in.m4])
-
-dnl syscmd inherits closed stdout
-AT_DATA([hi], [[hi
-]])
-AT_CHECK([cat hi >&- && { echo "skipping: can't detect closed stdout"; exit 77; }],
-[1], [], [stderr])
-AT_CHECK([$SED 's/Bad file number/Bad file descriptor/' < stderr > experr])
-AT_DATA([in.m4], [[syscmd(`cat hi')dnl
-]])
-AT_CHECK_M4([>&-], [0], [], [experr], [in.m4])
-
-dnl spilled diversion file must not collide with closed stdout
-AT_DATA([in.m4], [M4_ONE_MEG_DEFN[divert(1)f
-syscmd(`cat hi')
-divert(`-1')undivert
-]])
-AT_CHECK_M4([>&-], [0], [], [experr], [in.m4])
-
-dnl command line input file must not collide with closed stdout
-AT_DATA([in.m4], [[syscmd(`echo <&2')ifelse(sysval,
-`0', `skipping: sh cannot detect closed fds
-m4exit(`77')')
-]])
-AT_CHECK_M4([2>&-], [0], [ignore], [ignore], [in.m4])
-AT_DATA([in.m4], [[syscmd(`cat <&1 >&2')dnl
-dnl this line should not be read by cat
-]])
-AT_CHECK_M4([in.m4 >&-], [0], [], [stderr])
-AT_CHECK([[$SED -e 's/.*[Bb]\(ad file descriptor\)$/B\1/' stderr]], [0],
-[[Bad file descriptor
-]])
-
-AT_CLEANUP
-
-
-## ----------- ##
-## stdout full ##
-## ----------- ##
-
-AT_SETUP([stdout full])
-AT_CHECK([test -w /dev/full && test -c /dev/full || {
- echo "skipping: no /dev/full support";
- exit 77
-}])
-
-dnl Be careful when modifying these tests. Writes that exceed stdio buffering
-dnl limits trigger different but legal behavior where errno is lost. Tests
-dnl that currently require "No space left on device" may fail if the amount of
-dnl output changes. The --help test shows how to handle this.
-
-dnl detect write failures on --help
-AT_CHECK_M4([--help >/dev/full], [1], [], [stderr])
-AT_CHECK([grep '^m4: write error' stderr], [0], [ignore])
-
-dnl detect write failures on --version
-AT_CHECK_M4([--version >/dev/full], [1], [],
-[[m4: write error: No space left on device
-]])
-
-dnl detect ordinary write failures
-AT_DATA([in.m4], [[hello world
-]])
-AT_CHECK_M4([in.m4 >/dev/full], [1], [],
-[[m4: write error: No space left on device
-]])
-
-dnl detect stderr write failures
-AT_DATA([in.m4], [[dnl(hello world)
-]])
-AT_CHECK_M4([in.m4 2>/dev/full], [1])
-
-dnl detect trace write failures
-AT_DATA([in.m4], [[dnl
-]])
-AT_CHECK_M4([-tdnl in.m4 2>/dev/full], [1])
-
-dnl detect trace write failures
-AT_DATA([in.m4], [[dnl
-]])
-AT_CHECK_M4([--debugfile=/dev/full -tdnl in.m4], [1], [],
-[[m4: error writing to debug stream: No space left on device
-]])
-
-dnl too hard to test for spilled diversion failures, without requiring the
-dnl user to have a nearly full partition that we can assign to $TMPDIR.
-
-dnl write failures must override m4exit requesting 0
-AT_DATA([in.m4], [[hello world m4exit(`0')
-]])
-AT_CHECK_M4([in.m4 >/dev/full], [1], [],
-[[m4:in.m4:1: write error: No space left on device
-]])
-
-dnl preserve m4exit's failure value
-AT_DATA([in.m4], [[hello world m4exit(`2')
-]])
-AT_CHECK_M4([in.m4 >/dev/full], [2], [],
-[[m4:in.m4:1: write error: No space left on device
-]])
-
-AT_CLEANUP
-
-
-## --------- ##
-## sysv-args ##
-## --------- ##
-
-AT_SETUP([sysv-args])
-
-AT_DATA([[sysv-args.m4]],
-[[divert(-1)
-define(`nargs', `$#')
-define(`concat', `ifelse(1, $#, `$1', `$1` 'concat(shift($@))')')
-traceon(`concat', `nargs')
-divert
-
-nargs
-nargs()
-nargs(1,2,3,4,5,6)
-
-concat()
-concat(`hej', `med', `dig')
-concat(`hej', `med', `dig', `en gang igen')
-concat(an, awful, lot, of, argument, at, least, more, that, ten, silly, arguments)
-]])
-
-AT_DATA([[expout]],
-[[
-
-0
-1
-6
-
-
-hej med dig
-hej med dig en gang igen
-an awful lot of argument at least more that ten silly arguments
-]])
-
-AT_DATA([[experr]],
-[[m4trace: -1- nargs -> `0'
-m4trace: -1- nargs(`') -> `1'
-m4trace: -1- nargs(`1', `2', `3', `4', `5', `6') -> `6'
-m4trace: -1- concat(`') -> `ifelse(1, 1, `', `` 'concat(shift(`'))')'
-m4trace: -1- concat(`hej', `med', `dig') -> `ifelse(1, 3, `hej', `hej` 'concat(shift(`hej',`med',`dig'))')'
-m4trace: -1- concat(`med', `dig') -> `ifelse(1, 2, `med', `med` 'concat(shift(`med',`dig'))')'
-m4trace: -1- concat(`dig') -> `ifelse(1, 1, `dig', `dig` 'concat(shift(`dig'))')'
-m4trace: -1- concat(`hej', `med', `dig', `en gang igen') -> `ifelse(1, 4, `hej', `hej` 'concat(shift(`hej',`med',`dig',`en gang igen'))')'
-m4trace: -1- concat(`med', `dig', `en gang igen') -> `ifelse(1, 3, `med', `med` 'concat(shift(`med',`dig',`en gang igen'))')'
-m4trace: -1- concat(`dig', `en gang igen') -> `ifelse(1, 2, `dig', `dig` 'concat(shift(`dig',`en gang igen'))')'
-m4trace: -1- concat(`en gang igen') -> `ifelse(1, 1, `en gang igen', `en gang igen` 'concat(shift(`en gang igen'))')'
-m4trace: -1- concat(`an', `awful', `lot', `of', `argument', `at', `least', `more', `that', `ten', `silly', `arguments') -> `ifelse(1, 12, `an', `an` 'concat(shift(`an',`awful',`lot',`of',`argument',`at',`least',`more',`that',`ten',`silly',`arguments'))')'
-m4trace: -1- concat(`awful', `lot', `of', `argument', `at', `least', `more', `that', `ten', `silly', `arguments') -> `ifelse(1, 11, `awful', `awful` 'concat(shift(`awful',`lot',`of',`argument',`at',`least',`more',`that',`ten',`silly',`arguments'))')'
-m4trace: -1- concat(`lot', `of', `argument', `at', `least', `more', `that', `ten', `silly', `arguments') -> `ifelse(1, 10, `lot', `lot` 'concat(shift(`lot',`of',`argument',`at',`least',`more',`that',`ten',`silly',`arguments'))')'
-m4trace: -1- concat(`of', `argument', `at', `least', `more', `that', `ten', `silly', `arguments') -> `ifelse(1, 9, `of', `of` 'concat(shift(`of',`argument',`at',`least',`more',`that',`ten',`silly',`arguments'))')'
-m4trace: -1- concat(`argument', `at', `least', `more', `that', `ten', `silly', `arguments') -> `ifelse(1, 8, `argument', `argument` 'concat(shift(`argument',`at',`least',`more',`that',`ten',`silly',`arguments'))')'
-m4trace: -1- concat(`at', `least', `more', `that', `ten', `silly', `arguments') -> `ifelse(1, 7, `at', `at` 'concat(shift(`at',`least',`more',`that',`ten',`silly',`arguments'))')'
-m4trace: -1- concat(`least', `more', `that', `ten', `silly', `arguments') -> `ifelse(1, 6, `least', `least` 'concat(shift(`least',`more',`that',`ten',`silly',`arguments'))')'
-m4trace: -1- concat(`more', `that', `ten', `silly', `arguments') -> `ifelse(1, 5, `more', `more` 'concat(shift(`more',`that',`ten',`silly',`arguments'))')'
-m4trace: -1- concat(`that', `ten', `silly', `arguments') -> `ifelse(1, 4, `that', `that` 'concat(shift(`that',`ten',`silly',`arguments'))')'
-m4trace: -1- concat(`ten', `silly', `arguments') -> `ifelse(1, 3, `ten', `ten` 'concat(shift(`ten',`silly',`arguments'))')'
-m4trace: -1- concat(`silly', `arguments') -> `ifelse(1, 2, `silly', `silly` 'concat(shift(`silly',`arguments'))')'
-m4trace: -1- concat(`arguments') -> `ifelse(1, 1, `arguments', `arguments` 'concat(shift(`arguments'))')'
-]])
-
-AT_CHECK_M4([sysv-args.m4], 0, [expout], [experr])
-
-AT_CLEANUP
diff --git a/tests/shadow.c b/tests/shadow.c
deleted file mode 100644
index ae8cac7d..00000000
--- a/tests/shadow.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* GNU m4 -- A simple macro processor
- Copyright (C) 1999-2000, 2006-2008, 2010, 2013-2014, 2017 Free
- Software Foundation, Inc.
-
- This file is part of GNU M4.
-
- GNU M4 is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- GNU M4 is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include <config.h>
-
-/* Build using only the exported interfaces, unless NDEBUG is set, in
- which case use private symbols to speed things up as much as possible. */
-#ifndef NDEBUG
-# include <m4/m4module.h>
-#else
-# include "m4private.h"
-#endif
-
-/* function macros blind side minargs maxargs */
-#define builtin_functions \
- BUILTIN (shadow, false, false, false, 0, -1 ) \
- BUILTIN (test, false, false, false, 0, -1 ) \
-
-
-#define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler)
- builtin_functions
-#undef BUILTIN
-
-static const m4_builtin m4_builtin_table[] =
-{
-#define BUILTIN(handler, macros, blind, side, min, max) \
- M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
-
- builtin_functions
-#undef BUILTIN
-
- { NULL, NULL, 0, 0, 0 },
-};
-
-static const m4_macro m4_macro_table[] =
-{
- /* name text min max */
- { "__test__", "`shadow'", 0, 0 },
- { NULL, NULL, 0, 0 },
-};
-
-
-
-void
-include_shadow (m4 *context, m4_module *module, m4_obstack *obs)
-{
- const char *s = "Shadow module loaded.";
-
- if (obs)
- obstack_grow (obs, s, strlen (s));
-
- m4_install_builtins (context, module, m4_builtin_table);
- m4_install_macros (context, module, m4_macro_table);
-}
-
-
-
-/**
- * shadow()
- **/
-M4BUILTIN_HANDLER (shadow)
-{
- const char *s = "Shadow::`shadow' called.";
- obstack_grow (obs, s, strlen (s));
-}
-
-/**
- * test()
- **/
-M4BUILTIN_HANDLER (test)
-{
- const char *s = "Shadow::`test' called.";
- obstack_grow (obs, s, strlen (s));
-}
diff --git a/tests/stackovf.test b/tests/stackovf.test
deleted file mode 100755
index d57fc0f0..00000000
--- a/tests/stackovf.test
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/bin/sh
-# This file is part of the GNU m4 testsuite
-# Copyright (C) 2000, 2003, 2007, 2010, 2013-2014, 2017 Free Software
-# Foundation, Inc.
-#
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-exit 77
-
-# Script to verify that stack overflow is diagnosed properly when
-# there is infinite macro call nesting.
-# (causes coredump in m4-1.0.3)
-
-# On some systems the ulimit command is available in ksh or bash but not sh
-(exec 2>/dev/null; ulimit -HSs 300) || {
- for altshell in bash bsh ksh ; do
- if (exec >/dev/null 2>&1; $altshell -c 'ulimit -HSs 300') &&
- test -z "$1"
- then
- echo "Using $altshell because it supports ulimit"
- exec $altshell $0 running-with-$altshell
- exit 9
- fi
- done
-}
-
-PATH=.:..:$PATH; export PATH;
-: ${M4=../../src/m4}
-type $M4
-
-tmpfile=`tempfile 2> /dev/null` || tmpfile=/tmp/t.$$
-trap 'rm -f $tmpfile; exit 1' 1 2 3 15
-
-rm -f core
-perl -e '
-# Generate nested define sequence
-$max=1000000;
-for ($i=0; $i<$max; $i++) {
- print "define(X$i,\n";
-}
-for ($i=$max-1; $i>=0; $i--) {
- print "body with substance no. $i)dnl\n"
-}
-' | \
-(
-# Limit the stack size if the shell we are running permits it
-if (exec 2>/dev/null; ulimit -HSs 50)
-then
- (exec >/dev/null 2>&1; ulimit -v) && ulimitdashv=ok
- ulimit -HSs 50
- #ulimit -HSd 8000
- #test -n "$ulimitdashv" && ulimit -HSv 8000
- echo "Stack limit is `ulimit -s`K";
- echo "Heap limit is `ulimit -d`K";
- test -n "$ulimitdashv" &&
- echo "VMem limit is `ulimit -v`K";
-else
- echo "Can't reset stack limit - this may take a while..."
-fi
-#strace -o /tmp/aaa $M4 -L999999999 > $tmpfile 2>&1
-$M4 -L999999999 > $tmpfile 2>&1
-)
-result=$?
-{ echo "Output from $M4:"; cat $tmpfile; }
-
-exitcode=1
-if test $result -eq 0 ; then
- echo "TEST DID NOT WORK - m4 did not abort. Output:"
-else
- # See if stack overflow was diagnosed
- case "`cat $tmpfile`" in
- *overflow*)
- echo "Test succeeded.";
- exitcode=0
- ;;
- *ut*of*emory*|*emory*xhausted)
- echo "*** Test is INCONCLUSIVE (ran out of heap before stack overflow)";
- ;;
- *) echo "*** Test FAILED. $M4 aborted unexpectedly. Output:";
- ;;
- esac
-fi
-
-if test -f core ; then
- ls -l core
- exitcode=1
-fi
-
-#(test $exitcode -ne 0) &&
- { echo "Output from $M4:"; cat $tmpfile; }
-
-exit $exitcode
diff --git a/tests/testsuite.at b/tests/testsuite.at
deleted file mode 100644
index 19fc9ee7..00000000
--- a/tests/testsuite.at
+++ /dev/null
@@ -1,180 +0,0 @@
-# Process with autom4te to create an -*- Autotest -*- test suite.
-
-# Test suite for GNU M4.
-# Copyright (C) 2001, 2006-2010, 2013-2014, 2017 Free Software
-# Foundation, Inc.
-
-# This file is part of GNU M4.
-#
-# GNU M4 is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# GNU M4 is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-# We need a recent Autotest.
-m4_version_prereq([2.63b-41])
-
-# Default to testing "m4 -b", but allow overrides.
-dnl This uses knowledge of undocumented autotest internals; hopefully
-dnl it isn't too much of a problem. FIXME: Help autoconf document
-dnl proper usage of HELP_OTHER, at_write_fail, and at_tested (or better
-dnl yet, add AT_FOO macros that wrap these internal details).
-m4_divert_text([HELP_OTHER],
-[cat <<\_ATEOF || at_write_fail=1
-
-The environment variable `M4' controls which binary is tested, default `m4 -b'.
-_ATEOF])
-m4_divert_text([PREPARE_TESTS],
-[[if test "${M4+set}" = set; then
- case $M4 in
- *[\\/]* ) at_tested= ;;
- * ) at_tested=`set x $M4; echo $2` ;;
- esac
-else
- M4='m4 -b'
-fi]])
-
-# AT_CHECK_M4(ARGS, [EXIT-STATUS = 0], [STDOUT = `'], [STDERR = `'],
-# [STDIN = `/dev/null'], [INHIBIT-D])
-# ------------------------------------------------------------------
-# Run m4 with ARGS, and stdin redirected from STDIN, or with stdin closed
-# if STDIN is `-'. ARGS may redirect stdout and/or stderr, but should
-# not redirect stdin. Expect EXIT-STATUS, with output matching STDOUT and
-# STDERR as in AT_CHECK. If STDERR is specified, normalize the observed
-# error output. Unless INHIBIT-D is specified, add -d prior to ARGS.
-#
-# When testing an uninstalled wrapper, tests/m4 is on the path, but invokes
-# src/m4, which may itself be a libtool wrapper. Also, some platforms
-# choose to display argv[0] differently:
-# path/to/lt-m4:file:line: message
-# or m4.exe:file:line: message
-# to m4:file:line
-#
-# When testing closed file descriptors, the message is platform-dependent:
-# m4: error closing file: Bad file number
-# to m4: error closing file: Bad file descriptor
-#
-# When tracing modules, the module name is platform-dependent:
-# m4debug: module gnu: opening file `gnu.so'
-# or m4debug: module gnu: opening file `gnu.a'
-# to m4debug: module gnu: opening file
-#
-# When testing modules, a failed module name is platform-dependent:
-# m4:input.m4:7: cannot open module `no_such': no_such.so: cannot open shared object file: No such file or directory
-# or m4:input.m4:7: cannot open module `no_such': can't open the module
-# to m4:input.m4:7: cannot open module `no_such'
-#
-# When encountering command line option errors, the error message is
-# platform-dependent, but contains " option ":
-# m4: unrecognized option `--diversions=1' # glibc 2.6
-# or m4: unrecognized option '--diversions=1' # glibc 2.11
-# or m4: unknown option -- --diversions # BSD
-# or m4: option '--debu' is ambiguous # glibc 2.11
-# or m4: ambiguous option -- --debu # BSD
-# to m4: bad option
-m4_define([AT_CHECK_M4],
-[AT_CHECK([$M4 m4_ifval([$6], [], [-d ])$1 ]m4_if([$5], [-], [<&-],
- [< m4_default([$5], [/dev/null])]),
- [$2], [$3], m4_case([$4], [], [], [ignore], [ignore], [stderr]))
-m4_case([$4], [], [], [ignore], [],
-[AT_CHECK([[$SED 's/^[^:]*[lt-]*m4[.ex]*:/m4:/
- /^m4debug: module/s/opening file.*/opening file/
- s/\(cannot open module [^:]*\):.*/\1/
- s/Bad file number/Bad file descriptor/
- s/^m4:.* option .*/m4: bad option/
- ' stderr >&2]], [0], [], [$4])])
-])
-
-# M4_ONE_MEG_DEFN
-# ---------------
-# emit a code snippet for use in AT_DATA that will define a macro `f' to
-# consist of 1M bytes of newlines. With that in place, it is then easy
-# to use divert and invoke `f' in the test file to force diversions to
-# spill into a temporary file.
-m4_define([M4_ONE_MEG_DEFN],
-[pushdef(`diversion', divnum)divert(-1)
-define(`f', `
-')
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-define(`f', defn(`f')defn(`f'))
-divert(diversion)popdef(`diversion')])
-
-# AT_TEST_M4(TITLE, INPUT, [STDOUT = `'], [STDERR = `'])
-# ------------------------------------------------------
-# Run m4 on INPUT, expecting a success.
-m4_define([AT_TEST_M4],
-[AT_SETUP([$1])
-AT_DATA([[input.m4]], [$2])
-AT_CHECK_M4([[input.m4]], 0, [$3], [$4])
-AT_CLEANUP
-])
-
-# We use `dnl' in zillions of places...
-m4_pattern_allow([^dnl$])
-
-# We exercise m4.
-AT_TESTED([m4])
-
-# AT_CHECK_GMP
-# -----------------------
-# Add keyword `gmp' to the test, and skip the test if the use of GMP
-# was disabled at configure time.
-m4_define([AT_CHECK_GMP],
-[AT_KEYWORDS([gmp])
-AT_CHECK([if test "x$USE_GMP" = xno ; then
- echo libgmp support not detected, skipping this test.
- exit 77
-fi])])
-
-## ----------- ##
-## The suite. ##
-## ----------- ##
-
-AT_INIT
-
-# Macro definitions, uses, tracing etc.
-m4_include([macros.at])
-
-# Torturing builtins.
-m4_include([builtins.at])
-
-# Options.
-m4_include([options.at])
-
-# Frozen files.
-m4_include([freeze.at])
-
-# Hand crafted tests.
-m4_include([others.at])
-
-# Torturing the modules support.
-m4_include([modules.at])
-
-# From the documention.
-m4_include([generated.at])