summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Bailey <jbailey@raspberryginger.com>2000-02-17 03:03:19 +0000
committerJeff Bailey <jbailey@raspberryginger.com>2000-02-17 03:03:19 +0000
commitbd11691d6520f7539e7ed2efdf75f266719e27e9 (patch)
tree13d3a4e534f6df846a128af52438769b9f51f09e
downloadm4-bd11691d6520f7539e7ed2efdf75f266719e27e9.tar.gz
Initial revision
-rw-r--r--ABOUT-NLS226
-rw-r--r--AUTHORS20
-rw-r--r--BACKLOG51
-rw-r--r--COPYING339
-rw-r--r--ChangeLog1526
-rw-r--r--INSTALL167
-rw-r--r--LOCALE41
-rw-r--r--Makefile.am3
-rw-r--r--Makefile.in138
-rw-r--r--NEWS200
-rw-r--r--README31
-rw-r--r--README-alpha12
-rw-r--r--THANKS71
-rw-r--r--TODO41
-rw-r--r--acconfig.h36
-rw-r--r--acinclude.m4418
-rw-r--r--aclocal.m485
-rw-r--r--acm4/Makefile.am12
-rw-r--r--acm4/Makefile.in186
-rw-r--r--acm4/error.m411
-rw-r--r--acm4/gettext.m4384
-rw-r--r--acm4/gmp.m430
-rw-r--r--acm4/ltdl.m4429
-rw-r--r--acm4/modules.m427
-rw-r--r--acm4/regex.m423
-rw-r--r--c-boxes.el406
-rw-r--r--checks/01.define5
-rw-r--r--checks/02.arguments5
-rw-r--r--checks/02.define13
-rw-r--r--checks/03.arguments7
-rw-r--r--checks/04.arguments5
-rw-r--r--checks/05.arguments5
-rw-r--r--checks/06.arguments5
-rw-r--r--checks/06.pseudo_argu9
-rw-r--r--checks/07.pseudo_argu5
-rw-r--r--checks/08.pseudo_argu5
-rw-r--r--checks/09.pseudo_argu11
-rw-r--r--checks/10.pseudo_argu5
-rw-r--r--checks/11.pseudo_argu5
-rw-r--r--checks/11.undefine11
-rw-r--r--checks/12.defn7
-rw-r--r--checks/12.undefine11
-rw-r--r--checks/13.defn7
-rw-r--r--checks/13.pushdef17
-rw-r--r--checks/14.defn9
-rw-r--r--checks/14.pushdef17
-rw-r--r--checks/15.indir7
-rw-r--r--checks/15.pushdef17
-rw-r--r--checks/16.ifdef7
-rw-r--r--checks/16.pushdef17
-rw-r--r--checks/17.ifelse9
-rw-r--r--checks/17.indir7
-rw-r--r--checks/18.ifdef7
-rw-r--r--checks/18.ifelse3
-rw-r--r--checks/19.ifelse9
-rw-r--r--checks/19.loops5
-rw-r--r--checks/20.ifelse3
-rw-r--r--checks/20.loops10
-rw-r--r--checks/21.dumpdef9
-rw-r--r--checks/21.loops7
-rw-r--r--checks/22.loops10
-rw-r--r--checks/22.trace13
-rw-r--r--checks/23.dnl4
-rw-r--r--checks/23.dumpdef9
-rw-r--r--checks/24.changequote7
-rw-r--r--checks/24.trace13
-rw-r--r--checks/25.changequote7
-rw-r--r--checks/25.dnl4
-rw-r--r--checks/26.changequote9
-rw-r--r--checks/27.changecom11
-rw-r--r--checks/27.changequote7
-rw-r--r--checks/28.changecom7
-rw-r--r--checks/28.changequote9
-rw-r--r--checks/29.changecom11
-rw-r--r--checks/29.m4wrap9
-rw-r--r--checks/30.changecom7
-rw-r--r--checks/30.include6
-rw-r--r--checks/31.changesynta11
-rw-r--r--checks/31.include8
-rw-r--r--checks/32.changesynta11
-rw-r--r--checks/32.include8
-rw-r--r--checks/33.changesynta9
-rw-r--r--checks/33.divert9
-rw-r--r--checks/34.changesynta9
-rw-r--r--checks/34.divert6
-rw-r--r--checks/35.changesynta15
-rw-r--r--checks/35.undivert11
-rw-r--r--checks/36.changesynta5
-rw-r--r--checks/36.undivert13
-rw-r--r--checks/37.changesynta13
-rw-r--r--checks/37.undivert9
-rw-r--r--checks/38.divnum13
-rw-r--r--checks/38.m4wrap9
-rw-r--r--checks/39.cleardiv7
-rw-r--r--checks/39.include6
-rw-r--r--checks/40.cleardiv4
-rw-r--r--checks/40.include8
-rw-r--r--checks/41.include8
-rw-r--r--checks/41.len5
-rw-r--r--checks/42.divert9
-rw-r--r--checks/42.index5
-rw-r--r--checks/43.divert6
-rw-r--r--checks/43.regexp5
-rw-r--r--checks/44.regexp3
-rw-r--r--checks/44.undivert11
-rw-r--r--checks/45.substr5
-rw-r--r--checks/45.undivert13
-rw-r--r--checks/46.translit7
-rw-r--r--checks/46.undivert9
-rw-r--r--checks/47.divnum13
-rw-r--r--checks/47.patsubst11
-rw-r--r--checks/48.cleardiv7
-rw-r--r--checks/48.patsubst9
-rw-r--r--checks/49.cleardiv4
-rw-r--r--checks/49.format5
-rw-r--r--checks/50.incr5
-rw-r--r--checks/50.len5
-rw-r--r--checks/51.eval18
-rw-r--r--checks/51.index5
-rw-r--r--checks/52.eval11
-rw-r--r--checks/52.regexp5
-rw-r--r--checks/53.esyscmd6
-rw-r--r--checks/53.regexp3
-rw-r--r--checks/54.substr5
-rw-r--r--checks/54.sysval9
-rw-r--r--checks/55.errprint5
-rw-r--r--checks/55.translit7
-rw-r--r--checks/56.errprint5
-rw-r--r--checks/56.patsubst11
-rw-r--r--checks/57.m4exit6
-rw-r--r--checks/57.patsubst9
-rw-r--r--checks/58.format5
-rw-r--r--checks/59.incr5
-rw-r--r--checks/60.eval18
-rw-r--r--checks/61.eval11
-rw-r--r--checks/62.esyscmd6
-rw-r--r--checks/63.sysval9
-rw-r--r--checks/64.errprint5
-rw-r--r--checks/65.errprint5
-rw-r--r--checks/66.m4exit6
-rw-r--r--checks/Makefile.am16
-rw-r--r--checks/Makefile.in76
-rwxr-xr-xchecks/check-them51
-rw-r--r--checks/foo1
-rwxr-xr-xchecks/get-them68
-rw-r--r--checks/incl.m43
-rw-r--r--checks/stamp-checks0
-rwxr-xr-xconfig.guess883
-rw-r--r--config.h.in129
-rwxr-xr-xconfig.sub954
-rwxr-xr-xconfigure2123
-rw-r--r--configure.in88
-rw-r--r--doc/Makefile.am1
-rw-r--r--doc/Makefile.in92
-rw-r--r--doc/helptoman.pl249
-rw-r--r--doc/m4.1121
-rw-r--r--doc/m4.info112
-rw-r--r--doc/m4.info-11495
-rw-r--r--doc/m4.info-21468
-rw-r--r--doc/m4.info-3227
-rw-r--r--doc/m4.texinfo3415
-rw-r--r--doc/mdate-sh92
-rw-r--r--doc/stamp-vti1
-rw-r--r--doc/texinfo.tex4365
-rw-r--r--doc/version.texi3
-rw-r--r--examples/Makefile.am5
-rw-r--r--examples/Makefile.in60
-rw-r--r--examples/WWW/Makefile18
-rw-r--r--examples/WWW/_footer.htm15
-rw-r--r--examples/WWW/_header.htm234
-rw-r--r--examples/WWW/bugs.htm284
-rw-r--r--examples/WWW/changelog.htm2248
-rw-r--r--examples/WWW/download.htm302
-rw-r--r--examples/WWW/features.htm380
-rw-r--r--examples/WWW/feedback.htm297
-rw-r--r--examples/WWW/index.htm319
-rw-r--r--examples/WWW/lists.htm320
-rw-r--r--examples/WWW/m4lib/bugs.m452
-rw-r--r--examples/WWW/m4lib/changelog.m418
-rw-r--r--examples/WWW/m4lib/download.m421
-rw-r--r--examples/WWW/m4lib/features.m462
-rw-r--r--examples/WWW/m4lib/feedback.m420
-rw-r--r--examples/WWW/m4lib/html.m4119
-rw-r--r--examples/WWW/m4lib/index.m436
-rw-r--r--examples/WWW/m4lib/layout.m450
-rw-r--r--examples/WWW/m4lib/lists.m432
-rw-r--r--examples/WWW/m4lib/menu.m435
-rw-r--r--examples/WWW/m4lib/modules.m418
-rw-r--r--examples/WWW/m4lib/news.m418
-rw-r--r--examples/WWW/m4lib/readme.m418
-rw-r--r--examples/WWW/m4lib/setup.m47
-rw-r--r--examples/WWW/m4lib/test.m49
-rw-r--r--examples/WWW/m4lib/thanks.m418
-rw-r--r--examples/WWW/m4lib/thissite.m439
-rw-r--r--examples/WWW/m4lib/tmpl.m411
-rw-r--r--examples/WWW/m4lib/todo.m418
-rw-r--r--examples/WWW/m4lib/uses.m436
-rw-r--r--examples/WWW/m4lib/visions.m428
-rw-r--r--examples/WWW/m4lib/whatis.m443
-rw-r--r--examples/WWW/modules.htm347
-rw-r--r--examples/WWW/news.htm551
-rw-r--r--examples/WWW/readme.htm329
-rw-r--r--examples/WWW/thanks.htm377
-rw-r--r--examples/WWW/thissite.htm327
-rw-r--r--examples/WWW/todo.htm388
-rw-r--r--examples/WWW/uses.htm322
-rw-r--r--examples/WWW/visions.htm309
-rw-r--r--examples/WWW/whatis.htm327
-rw-r--r--examples/capitalize.m48
-rwxr-xr-xexamples/capitalize.test21
-rw-r--r--examples/comments.m47
-rwxr-xr-xexamples/comments.test24
-rw-r--r--examples/ddivert.m44
-rwxr-xr-xexamples/ddivert.test18
-rw-r--r--examples/debug.m44
-rwxr-xr-xexamples/debug.test33
-rw-r--r--examples/defs54
-rw-r--r--examples/esyscmd.m45
-rwxr-xr-xexamples/esyscmd.test18
-rw-r--r--examples/exp.m41
-rwxr-xr-xexamples/exp.test23
-rw-r--r--examples/file.m45
-rw-r--r--examples/foreach.m419
-rwxr-xr-xexamples/foreach.test28
-rw-r--r--examples/forloop.m48
-rwxr-xr-xexamples/forloop.test26
-rw-r--r--examples/fstab.m47
-rwxr-xr-xexamples/fstab.test21
-rw-r--r--examples/hanoi.m415
-rwxr-xr-xexamples/hanoi.test23
-rw-r--r--examples/incl-test.m42
-rw-r--r--examples/include.m47
-rwxr-xr-xexamples/include.test28
-rw-r--r--examples/indir.m410
-rwxr-xr-xexamples/indir.test24
-rw-r--r--examples/iso8859.m4bin0 -> 1146 bytes
-rwxr-xr-xexamples/iso8859.test33
-rw-r--r--examples/misc.m49
-rwxr-xr-xexamples/misc.test17
-rw-r--r--examples/mktests.sh65
-rw-r--r--examples/multiquotes.m417
-rwxr-xr-xexamples/multiquotes.test47
-rw-r--r--examples/patsubst.m48
-rwxr-xr-xexamples/patsubst.test26
-rw-r--r--examples/pushpop.m425
-rwxr-xr-xexamples/pushpop.test28
-rw-r--r--examples/regexp.m412
-rwxr-xr-xexamples/regexp.test39
-rw-r--r--examples/reverse.m44
-rwxr-xr-xexamples/reverse.test20
-rw-r--r--examples/stackovf.sh83
-rw-r--r--examples/sync-lines.m411
-rw-r--r--examples/sysv-args.m414
-rwxr-xr-xexamples/sysv-args.test53
-rw-r--r--examples/trace.m430
-rwxr-xr-xexamples/trace.test96
-rw-r--r--examples/translit.m48
-rwxr-xr-xexamples/translit.test22
-rw-r--r--examples/undivert.incl1
-rw-r--r--examples/undivert.m45
-rwxr-xr-xexamples/undivert.test21
-rw-r--r--examples/wrap.m410
-rwxr-xr-xexamples/wrap.test22
-rw-r--r--gettext.m4384
-rwxr-xr-xinstall-sh238
-rw-r--r--lib/COPYING.LIB481
-rw-r--r--lib/Makefile.am12
-rw-r--r--lib/Makefile.in92
-rw-r--r--lib/alloca.c492
-rw-r--r--lib/error.c119
-rw-r--r--lib/error.h65
-rw-r--r--lib/getdate.h46
-rw-r--r--lib/getopt.c748
-rw-r--r--lib/getopt.h129
-rw-r--r--lib/getopt1.c180
-rw-r--r--lib/m4error.c259
-rw-r--r--lib/m4error.h98
-rw-r--r--lib/m4module.c214
-rw-r--r--lib/m4module.h240
-rw-r--r--lib/m4obstack.c598
-rw-r--r--lib/m4obstack.h593
-rw-r--r--lib/m4private.h68
-rw-r--r--lib/m4regex.c5880
-rw-r--r--lib/m4regex.h542
-rw-r--r--lib/obstack.c485
-rw-r--r--lib/obstack.h516
-rw-r--r--lib/regex.c5244
-rw-r--r--lib/regex.h487
-rw-r--r--lib/strtol.c186
-rw-r--r--lib/xmalloc.c95
-rw-r--r--lib/xstrdup.c36
-rw-r--r--libltdl/COPYING.LIB481
-rw-r--r--libltdl/Makefile.am44
-rw-r--r--libltdl/Makefile.in454
-rw-r--r--libltdl/README1
-rw-r--r--libltdl/acconfig.h12
-rw-r--r--libltdl/acinclude.m4427
-rw-r--r--libltdl/aclocal.m4566
-rw-r--r--libltdl/config.h.in80
-rwxr-xr-xlibltdl/configure3077
-rw-r--r--libltdl/configure.in373
-rw-r--r--libltdl/ltdl.c1577
-rw-r--r--libltdl/ltdl.h91
-rw-r--r--libltdl/stamp-h.in1
-rwxr-xr-xltconfig1512
-rw-r--r--ltmain.sh2453
-rwxr-xr-xmissing134
-rwxr-xr-xmkinstalldirs32
-rw-r--r--modules/Makefile.am9
-rw-r--r--modules/Makefile.in300
-rw-r--r--modules/README62
-rw-r--r--modules/TODO3
-rw-r--r--modules/defs58
-rwxr-xr-xmodules/modpath1.test26
-rwxr-xr-xmodules/modpath2.test25
-rwxr-xr-xmodules/modpath3.test30
-rwxr-xr-xmodules/modpath4.test24
-rw-r--r--modules/shadow.c75
-rw-r--r--modules/shadow.m459
-rwxr-xr-xmodules/shadow.test91
-rw-r--r--modules/stdlib.c293
-rw-r--r--modules/stdlib.m441
-rw-r--r--modules/test.c58
-rw-r--r--modules/test.m43
-rwxr-xr-xmodules/test.test24
-rw-r--r--modules/time.c193
-rw-r--r--modules/time.m416
-rwxr-xr-xmodules/time.test50
-rw-r--r--modules/time2.m414
-rw-r--r--po/ChangeLog0
-rw-r--r--po/Makefile.in.in254
-rw-r--r--po/POTFILES.in1
-rw-r--r--po/cat-id-tbl.c72
-rw-r--r--po/cs.gmobin0 -> 12502 bytes
-rw-r--r--po/cs.po725
-rw-r--r--po/de.gmobin0 -> 12496 bytes
-rw-r--r--po/de.po507
-rw-r--r--po/el.gmobin0 -> 12751 bytes
-rw-r--r--po/el.po690
-rw-r--r--po/fr.gmobin0 -> 12645 bytes
-rw-r--r--po/fr.po468
-rw-r--r--po/it.gmobin0 -> 6243 bytes
-rw-r--r--po/it.po406
-rw-r--r--po/ja.gmobin0 -> 13592 bytes
-rw-r--r--po/ja.po515
-rw-r--r--po/m4.pot116
-rw-r--r--po/nl.gmobin0 -> 12351 bytes
-rw-r--r--po/nl.po464
-rw-r--r--po/pl.gmobin0 -> 11935 bytes
-rw-r--r--po/pl.po500
-rw-r--r--po/ru.gmobin0 -> 12173 bytes
-rw-r--r--po/ru.po498
-rw-r--r--po/stamp-cat-id1
-rw-r--r--po/sv.gmobin0 -> 334 bytes
-rw-r--r--po/sv.po549
-rw-r--r--src/Makefile.am15
-rw-r--r--src/Makefile.in122
-rw-r--r--src/ansi2knr.119
-rw-r--r--src/ansi2knr.c439
-rw-r--r--src/builtin.c1732
-rw-r--r--src/builtin.h39
-rw-r--r--src/debug.c421
-rw-r--r--src/eval.c774
-rw-r--r--src/evalmp.c27
-rw-r--r--src/format.c744
-rw-r--r--src/freeze.c369
-rw-r--r--src/getopt.c1051
-rw-r--r--src/getopt.h180
-rw-r--r--src/getopt1.c188
-rw-r--r--src/input.c852
-rw-r--r--src/ltdl.c1691
-rw-r--r--src/ltdl.h141
-rw-r--r--src/m4.c493
-rw-r--r--src/m4.h475
-rw-r--r--src/macro.c316
-rw-r--r--src/module.c206
-rw-r--r--src/numb.c418
-rw-r--r--src/numb.h156
-rw-r--r--src/output.c590
-rw-r--r--src/path.c151
-rw-r--r--src/stackovf.c392
-rw-r--r--src/symtab.c266
-rw-r--r--stamp-h.in1
-rw-r--r--tests/Makefile.am35
-rw-r--r--tests/Makefile.in235
-rwxr-xr-xtests/argument.1.test21
-rwxr-xr-xtests/argument.2.test23
-rwxr-xr-xtests/argument.3.test21
-rwxr-xr-xtests/argument.4.test21
-rwxr-xr-xtests/changeco.1.test27
-rwxr-xr-xtests/changeco.2.test23
-rwxr-xr-xtests/changequ.1.test23
-rwxr-xr-xtests/changequ.2.test23
-rwxr-xr-xtests/changequ.3.test25
-rwxr-xr-xtests/changesy.1.test27
-rwxr-xr-xtests/changesy.2.test27
-rwxr-xr-xtests/changesy.3.test25
-rwxr-xr-xtests/changesy.4.test25
-rwxr-xr-xtests/changesy.5.test31
-rwxr-xr-xtests/changesy.6.test21
-rwxr-xr-xtests/changesy.7.test29
-rwxr-xr-xtests/cleardiv.1.test23
-rwxr-xr-xtests/cleardiv.2.test20
-rwxr-xr-xtests/define.1.test21
-rwxr-xr-xtests/define.2.test29
-rwxr-xr-xtests/defn.1.test23
-rwxr-xr-xtests/defn.2.test25
-rw-r--r--tests/defs54
-rwxr-xr-xtests/divert.1.test25
-rwxr-xr-xtests/divert.2.test22
-rwxr-xr-xtests/divnum.1.test29
-rwxr-xr-xtests/dnl.1.test20
-rwxr-xr-xtests/dumpdef.1.test29
-rwxr-xr-xtests/errprint.1.test25
-rwxr-xr-xtests/errprint.2.test25
-rwxr-xr-xtests/esyscmd.1.test22
-rwxr-xr-xtests/eval.1.test38
-rwxr-xr-xtests/eval.2.test27
-rw-r--r--tests/foo1
-rwxr-xr-xtests/format.1.test21
-rwxr-xr-xtests/generated-tests/argument.1.test21
-rwxr-xr-xtests/generated-tests/argument.2.test23
-rwxr-xr-xtests/generated-tests/argument.3.test21
-rwxr-xr-xtests/generated-tests/argument.4.test21
-rwxr-xr-xtests/generated-tests/changeco.1.test27
-rwxr-xr-xtests/generated-tests/changeco.2.test23
-rwxr-xr-xtests/generated-tests/changequ.1.test23
-rwxr-xr-xtests/generated-tests/changequ.2.test23
-rwxr-xr-xtests/generated-tests/changequ.3.test25
-rwxr-xr-xtests/generated-tests/changesy.1.test27
-rwxr-xr-xtests/generated-tests/changesy.2.test27
-rwxr-xr-xtests/generated-tests/changesy.3.test25
-rwxr-xr-xtests/generated-tests/changesy.4.test25
-rwxr-xr-xtests/generated-tests/changesy.5.test31
-rwxr-xr-xtests/generated-tests/changesy.6.test21
-rwxr-xr-xtests/generated-tests/changesy.7.test29
-rwxr-xr-xtests/generated-tests/changesy.8.test29
-rwxr-xr-xtests/generated-tests/cleardiv.1.test23
-rwxr-xr-xtests/generated-tests/cleardiv.2.test20
-rwxr-xr-xtests/generated-tests/define.1.test21
-rwxr-xr-xtests/generated-tests/define.2.test29
-rwxr-xr-xtests/generated-tests/defn.1.test23
-rwxr-xr-xtests/generated-tests/defn.2.test25
-rwxr-xr-xtests/generated-tests/divert.1.test25
-rwxr-xr-xtests/generated-tests/divert.2.test22
-rwxr-xr-xtests/generated-tests/divnum.1.test29
-rwxr-xr-xtests/generated-tests/dnl.1.test20
-rwxr-xr-xtests/generated-tests/dumpdef.1.test29
-rwxr-xr-xtests/generated-tests/errprint.1.test25
-rwxr-xr-xtests/generated-tests/errprint.2.test25
-rwxr-xr-xtests/generated-tests/esyscmd.1.test22
-rwxr-xr-xtests/generated-tests/eval.1.test38
-rwxr-xr-xtests/generated-tests/eval.2.test27
-rwxr-xr-xtests/generated-tests/format.1.test21
-rwxr-xr-xtests/generated-tests/ifdef.1.test23
-rwxr-xr-xtests/generated-tests/ifelse.1.test25
-rwxr-xr-xtests/generated-tests/ifelse.2.test19
-rwxr-xr-xtests/generated-tests/include.1.test26
-rwxr-xr-xtests/generated-tests/include.2.test24
-rwxr-xr-xtests/generated-tests/include.3.test24
-rwxr-xr-xtests/generated-tests/incr.1.test21
-rwxr-xr-xtests/generated-tests/index.1.test21
-rwxr-xr-xtests/generated-tests/indir.1.test23
-rwxr-xr-xtests/generated-tests/len.1.test21
-rwxr-xr-xtests/generated-tests/loops.1.test23
-rwxr-xr-xtests/generated-tests/loops.2.test26
-rwxr-xr-xtests/generated-tests/m4exit.1.test26
-rwxr-xr-xtests/generated-tests/m4wrap.1.test25
-rwxr-xr-xtests/generated-tests/patsubst.1.test27
-rwxr-xr-xtests/generated-tests/patsubst.2.test25
-rwxr-xr-xtests/generated-tests/pseudoar.1.test25
-rwxr-xr-xtests/generated-tests/pseudoar.2.test21
-rwxr-xr-xtests/generated-tests/pseudoar.3.test21
-rwxr-xr-xtests/generated-tests/pseudoar.4.test27
-rwxr-xr-xtests/generated-tests/pseudoar.5.test21
-rwxr-xr-xtests/generated-tests/pushdef.1.test33
-rwxr-xr-xtests/generated-tests/pushdef.2.test33
-rwxr-xr-xtests/generated-tests/regexp.1.test21
-rwxr-xr-xtests/generated-tests/regexp.2.test19
-rwxr-xr-xtests/generated-tests/substr.1.test21
-rwxr-xr-xtests/generated-tests/symbols.1.test19
-rwxr-xr-xtests/generated-tests/sysval.1.test25
-rwxr-xr-xtests/generated-tests/trace.1.test33
-rwxr-xr-xtests/generated-tests/translit.1.test23
-rwxr-xr-xtests/generated-tests/undefine.1.test27
-rwxr-xr-xtests/generated-tests/undivert.1.test27
-rwxr-xr-xtests/generated-tests/undivert.2.test29
-rwxr-xr-xtests/generated-tests/undivert.3.test25
-rwxr-xr-xtests/gentest/argument.1.m421
-rwxr-xr-xtests/gentest/argument.1.test21
-rwxr-xr-xtests/gentest/argument.2.m423
-rwxr-xr-xtests/gentest/argument.2.test23
-rwxr-xr-xtests/gentest/argument.3.m421
-rwxr-xr-xtests/gentest/argument.3.test21
-rwxr-xr-xtests/gentest/argument.4.m421
-rwxr-xr-xtests/gentest/argument.4.test21
-rwxr-xr-xtests/gentest/changeco.1.m427
-rwxr-xr-xtests/gentest/changeco.1.test27
-rwxr-xr-xtests/gentest/changeco.2.m423
-rwxr-xr-xtests/gentest/changeco.2.test23
-rwxr-xr-xtests/gentest/changequ.1.m423
-rwxr-xr-xtests/gentest/changequ.1.test23
-rwxr-xr-xtests/gentest/changequ.2.m423
-rwxr-xr-xtests/gentest/changequ.2.test23
-rwxr-xr-xtests/gentest/changequ.3.m425
-rwxr-xr-xtests/gentest/changequ.3.test25
-rwxr-xr-xtests/gentest/changesy.1.m427
-rwxr-xr-xtests/gentest/changesy.1.test27
-rwxr-xr-xtests/gentest/changesy.2.m427
-rwxr-xr-xtests/gentest/changesy.2.test27
-rwxr-xr-xtests/gentest/changesy.3.m425
-rwxr-xr-xtests/gentest/changesy.3.test25
-rwxr-xr-xtests/gentest/changesy.4.m425
-rwxr-xr-xtests/gentest/changesy.4.test25
-rwxr-xr-xtests/gentest/changesy.5.m431
-rwxr-xr-xtests/gentest/changesy.5.test31
-rwxr-xr-xtests/gentest/changesy.6.m421
-rwxr-xr-xtests/gentest/changesy.6.test21
-rwxr-xr-xtests/gentest/changesy.7.m429
-rwxr-xr-xtests/gentest/changesy.7.test29
-rwxr-xr-xtests/gentest/cleardiv.1.m423
-rwxr-xr-xtests/gentest/cleardiv.1.test23
-rwxr-xr-xtests/gentest/cleardiv.2.m420
-rwxr-xr-xtests/gentest/cleardiv.2.test20
-rwxr-xr-xtests/gentest/define.1.m421
-rwxr-xr-xtests/gentest/define.1.test21
-rwxr-xr-xtests/gentest/define.2.m429
-rwxr-xr-xtests/gentest/define.2.test29
-rwxr-xr-xtests/gentest/defn.1.m423
-rwxr-xr-xtests/gentest/defn.1.test23
-rwxr-xr-xtests/gentest/defn.2.m425
-rwxr-xr-xtests/gentest/defn.2.test25
-rwxr-xr-xtests/gentest/divert.1.m425
-rwxr-xr-xtests/gentest/divert.1.test25
-rwxr-xr-xtests/gentest/divert.2.m422
-rwxr-xr-xtests/gentest/divert.2.test22
-rwxr-xr-xtests/gentest/divnum.1.m429
-rwxr-xr-xtests/gentest/divnum.1.test29
-rwxr-xr-xtests/gentest/dnl.1.m420
-rwxr-xr-xtests/gentest/dnl.1.test20
-rwxr-xr-xtests/gentest/dumpdef.1.m429
-rwxr-xr-xtests/gentest/dumpdef.1.test29
-rwxr-xr-xtests/gentest/errprint.1.m425
-rwxr-xr-xtests/gentest/errprint.1.test25
-rwxr-xr-xtests/gentest/errprint.2.m425
-rwxr-xr-xtests/gentest/errprint.2.test25
-rwxr-xr-xtests/gentest/esyscmd.1.m422
-rwxr-xr-xtests/gentest/esyscmd.1.test22
-rwxr-xr-xtests/gentest/eval.1.m438
-rwxr-xr-xtests/gentest/eval.1.test38
-rwxr-xr-xtests/gentest/eval.2.m427
-rwxr-xr-xtests/gentest/eval.2.test27
-rwxr-xr-xtests/gentest/format.1.m421
-rwxr-xr-xtests/gentest/format.1.test21
-rwxr-xr-xtests/gentest/ifdef.1.m423
-rwxr-xr-xtests/gentest/ifdef.1.test23
-rwxr-xr-xtests/gentest/ifelse.1.m425
-rwxr-xr-xtests/gentest/ifelse.1.test25
-rwxr-xr-xtests/gentest/ifelse.2.m419
-rwxr-xr-xtests/gentest/ifelse.2.test19
-rwxr-xr-xtests/gentest/include.1.m426
-rwxr-xr-xtests/gentest/include.1.test26
-rwxr-xr-xtests/gentest/include.2.m424
-rwxr-xr-xtests/gentest/include.2.test24
-rwxr-xr-xtests/gentest/include.3.m424
-rwxr-xr-xtests/gentest/include.3.test24
-rwxr-xr-xtests/gentest/incr.1.m421
-rwxr-xr-xtests/gentest/incr.1.test21
-rwxr-xr-xtests/gentest/index.1.m421
-rwxr-xr-xtests/gentest/index.1.test21
-rwxr-xr-xtests/gentest/indir.1.m423
-rwxr-xr-xtests/gentest/indir.1.test23
-rwxr-xr-xtests/gentest/len.1.m421
-rwxr-xr-xtests/gentest/len.1.test21
-rwxr-xr-xtests/gentest/loops.1.m423
-rwxr-xr-xtests/gentest/loops.1.test23
-rwxr-xr-xtests/gentest/loops.2.m426
-rwxr-xr-xtests/gentest/loops.2.test26
-rwxr-xr-xtests/gentest/m4exit.1.m426
-rwxr-xr-xtests/gentest/m4exit.1.test26
-rwxr-xr-xtests/gentest/m4wrap.1.m425
-rwxr-xr-xtests/gentest/m4wrap.1.test25
-rwxr-xr-xtests/gentest/patsubst.1.m427
-rwxr-xr-xtests/gentest/patsubst.1.test27
-rwxr-xr-xtests/gentest/patsubst.2.m425
-rwxr-xr-xtests/gentest/patsubst.2.test25
-rwxr-xr-xtests/gentest/pseudoar.1.m425
-rwxr-xr-xtests/gentest/pseudoar.1.test25
-rwxr-xr-xtests/gentest/pseudoar.2.m421
-rwxr-xr-xtests/gentest/pseudoar.2.test21
-rwxr-xr-xtests/gentest/pseudoar.3.m421
-rwxr-xr-xtests/gentest/pseudoar.3.test21
-rwxr-xr-xtests/gentest/pseudoar.4.m427
-rwxr-xr-xtests/gentest/pseudoar.4.test27
-rwxr-xr-xtests/gentest/pseudoar.5.m421
-rwxr-xr-xtests/gentest/pseudoar.5.test21
-rwxr-xr-xtests/gentest/pushdef.1.m433
-rwxr-xr-xtests/gentest/pushdef.1.test33
-rwxr-xr-xtests/gentest/pushdef.2.m433
-rwxr-xr-xtests/gentest/pushdef.2.test33
-rwxr-xr-xtests/gentest/regexp.1.m421
-rwxr-xr-xtests/gentest/regexp.1.test21
-rwxr-xr-xtests/gentest/regexp.2.m419
-rwxr-xr-xtests/gentest/regexp.2.test19
-rwxr-xr-xtests/gentest/substr.1.m421
-rwxr-xr-xtests/gentest/substr.1.test21
-rwxr-xr-xtests/gentest/sysval.1.m425
-rwxr-xr-xtests/gentest/sysval.1.test25
-rwxr-xr-xtests/gentest/trace.1.m433
-rwxr-xr-xtests/gentest/trace.1.test33
-rwxr-xr-xtests/gentest/translit.1.m423
-rwxr-xr-xtests/gentest/translit.1.test23
-rwxr-xr-xtests/gentest/undefine.1.m427
-rwxr-xr-xtests/gentest/undefine.1.test27
-rwxr-xr-xtests/gentest/undivert.1.m427
-rwxr-xr-xtests/gentest/undivert.1.test27
-rwxr-xr-xtests/gentest/undivert.2.m429
-rwxr-xr-xtests/gentest/undivert.2.test29
-rwxr-xr-xtests/gentest/undivert.3.m425
-rwxr-xr-xtests/gentest/undivert.3.test25
-rwxr-xr-xtests/get-them112
-rwxr-xr-xtests/ifdef.1.test23
-rwxr-xr-xtests/ifelse.1.test25
-rwxr-xr-xtests/ifelse.2.test19
-rw-r--r--tests/incl.m43
-rwxr-xr-xtests/include.1.test26
-rwxr-xr-xtests/include.2.test24
-rwxr-xr-xtests/include.3.test24
-rwxr-xr-xtests/incr.1.test21
-rwxr-xr-xtests/index.1.test21
-rwxr-xr-xtests/indir.1.test23
-rwxr-xr-xtests/len.1.test21
-rwxr-xr-xtests/loops.1.test23
-rwxr-xr-xtests/loops.2.test26
-rwxr-xr-xtests/m4exit.1.test26
-rwxr-xr-xtests/m4wrap.1.test25
-rw-r--r--tests/mkconfig.sh4
-rw-r--r--tests/other-tests/discard-comments.m47
-rwxr-xr-xtests/other-tests/discard-comments.test17
-rw-r--r--tests/other-tests/gmp.m410
-rwxr-xr-xtests/other-tests/gmp.test120
-rw-r--r--tests/other-tests/import-environment.m44
-rwxr-xr-xtests/other-tests/import-environment.test28
-rw-r--r--tests/other-tests/iso8859.m4bin0 -> 1146 bytes
-rwxr-xr-xtests/other-tests/iso8859.test31
-rwxr-xr-xtests/other-tests/stackovf.test86
-rw-r--r--tests/other-tests/sync-lines.m412
-rwxr-xr-xtests/other-tests/sync-lines.test35
-rwxr-xr-xtests/patsubst.1.test27
-rwxr-xr-xtests/patsubst.2.test25
-rwxr-xr-xtests/pseudoar.1.test25
-rwxr-xr-xtests/pseudoar.2.test21
-rwxr-xr-xtests/pseudoar.3.test21
-rwxr-xr-xtests/pseudoar.4.test27
-rwxr-xr-xtests/pseudoar.5.test21
-rwxr-xr-xtests/pushdef.1.test33
-rwxr-xr-xtests/pushdef.2.test33
-rwxr-xr-xtests/regexp.1.test21
-rwxr-xr-xtests/regexp.2.test19
-rwxr-xr-xtests/run-test29
-rw-r--r--tests/stamp-TESTS0
-rwxr-xr-xtests/substr.1.test21
-rwxr-xr-xtests/sysval.1.test25
-rwxr-xr-xtests/trace.1.test33
-rwxr-xr-xtests/translit.1.test23
-rwxr-xr-xtests/undefine.1.test27
-rwxr-xr-xtests/undivert.1.test27
-rwxr-xr-xtests/undivert.2.test29
-rwxr-xr-xtests/undivert.3.test25
669 files changed, 88215 insertions, 0 deletions
diff --git a/ABOUT-NLS b/ABOUT-NLS
new file mode 100644
index 00000000..75f8a27f
--- /dev/null
+++ b/ABOUT-NLS
@@ -0,0 +1,226 @@
+Notes on the GNU Translation Project
+************************************
+
+ GNU is going international! The GNU Translation Project is a way to
+get maintainers, translators, and users all together, so that GNU will
+gradually become able to speak many languages. A few packages already
+provide translations for their messages.
+
+ If you found this `ABOUT-NLS' file inside a GNU distribution, you
+may assume that the distributed package does use GNU `gettext'
+internally, itself available at your nearest GNU archive site. But you
+do *not* need to install GNU `gettext' prior to configuring, installing
+or using this package with messages translated.
+
+ Installers will find here some useful hints. These notes also
+explain how users should proceed for getting the programs to use the
+available translations. They tell how people wanting to contribute and
+work at translations should contact the appropriate team.
+
+ When reporting bugs in the `intl/' directory or bugs which may be
+related to internationalization, you should tell about the version of
+`gettext' which is used. The information can be found in the
+`intl/VERSION' file, in internationalized packages.
+
+One advise in advance
+=====================
+
+ If you want to exploit the full power of internationalization, you
+should configure it using
+
+ ./configure --with-included-gettext
+
+to force usage of internationalizing routines provided within this
+package, despite the existence of internationalizing capabilities in
+the operating system where this package is being installed. So far, no
+prior implementation provides as many useful features (such as locale
+alias or message inheritance). It is also not possible to offer this
+additional functionality on top of a `catgets' implementation. Future
+versions of GNU `gettext' will very likely convey even more
+functionality. So it might be a good idea to change to GNU `gettext'
+as soon as possible.
+
+INSTALL Matters
+===============
+
+ Some GNU packages are "localizable" when properly installed; the
+programs they contain can be made to speak your own native language.
+Most such packages use GNU `gettext'. Other packages have their own
+ways to internationalization, predating GNU `gettext'.
+
+ By default, this package will be installed to allow translation of
+messages. It will automatically detect whether the system provides
+usable `catgets' (if using this is selected by the installer) or
+`gettext' functions. If neither is available, the GNU `gettext' own
+library will be used. This library is wholly contained within this
+package, usually in the `intl/' subdirectory, so prior installation of
+the GNU `gettext' package is *not* required. Installers may use
+special options at configuration time for changing the default
+behaviour. The commands:
+
+ ./configure --with-included-gettext
+ ./configure --with-catgets
+ ./configure --disable-nls
+
+will respectively bypass any pre-existing `catgets' or `gettext' to use
+the internationalizing routines provided within this package, enable
+the use of the `catgets' functions (if found on the locale system), or
+else, *totally* disable translation of messages.
+
+ When you already have GNU `gettext' installed on your system and run
+configure without an option for your new package, `configure' will
+probably detect the previously built and installed `libintl.a' file and
+will decide to use this. This might be not what is desirable. You
+should use the more recent version of the GNU `gettext' library. I.e.
+if the file `intl/VERSION' shows that the library which comes with this
+package is more recent, you should use
+
+ ./configure --with-included-gettext
+
+to prevent auto-detection.
+
+ By default the configuration process will not test for the `catgets'
+function and therefore they will not be used. The reasons are already
+given above: the emulation on top of `catgets' cannot provide all the
+extensions provided by the GNU `gettext' library. If you nevertheless
+want to use the `catgets' functions use
+
+ ./configure --with-catgets
+
+to enable the test for `catgets' (this causes no harm if `catgets' is
+not available on your system). If you really select this option we
+would like to hear about the reasons because we cannot think of any
+good one ourself.
+
+ Internationalized packages have usually many `po/LL.po' files, where
+LL gives an ISO 639 two-letter code identifying the language. Unless
+translations have been forbidden at `configure' time by using the
+`--disable-nls' switch, all available translations are installed
+together with the package. However, the environment variable `LINGUAS'
+may be set, prior to configuration, to limit the installed set.
+`LINGUAS' should then contain a space separated list of two-letter
+codes, stating which languages are allowed.
+
+Using This Package
+==================
+
+ As a user, if your language has been installed for this package, you
+only have to set the `LANG' environment variable to the appropriate
+ISO 639 `LL' two-letter code prior to using the programs in the
+package. For example, let's suppose that you speak German. At the
+shell prompt, merely execute `setenv LANG de' (in `csh'),
+`export LANG; LANG=de' (in `sh') or `export LANG=de' (in `bash'). This
+can be done from your `.login' or `.profile' file, once and for all.
+
+ An operating system might already offer message localization for
+many of its programs, while other programs (whether GNU or not) have
+been installed locally with the full capabilities of GNU `gettext'.
+Just using `gettext' extended syntax for `LANG' would break proper
+localization of already available operating system programs. In this
+case, users should set both `LANGUAGE' and `LANG' variables in their
+environment, as programs using GNU `gettext' give preference to
+`LANGUAGE'. For example, some Swedish users would rather read
+translations in German than English for when Swedish is not available.
+This is easily accomplished by setting `LANGUAGE' to `sv:de' while
+leaving `LANG' to `sv'.
+
+Translating Teams
+=================
+
+ For the GNU Translation Project to be a success, we need interested
+people who like their own language and write it well, and who are also
+able to synergize with other translators speaking the same language.
+Each translation team has its own mailing list, courtesy of Linux
+International. You may reach your translation team at the address
+`LL@li.org', replacing LL by the two-letter ISO 639 code for your
+language. Language codes are *not* the same as the country codes given
+in ISO 3166. The following translation teams exist, as of February
+1997:
+
+ Arabic `ar', Chinese `zh', Czech `cs', Danish `da', Dutch `nl',
+ English `en', Esperanto `eo', Finnish `fi', French `fr', German
+ `de', Greek `el', Hebrew `he', Hungarian `hu', Irish `ga', Italian
+ `it', Indonesian `id', Japanese `ja', Korean `ko', Latin `la',
+ Norwegian `no', Persian `fa', Polish `pl', Portuguese `pt',
+ Russian `ru', Slovenian `sl', Spanish `es', Swedish `sv', Telugu
+ `te', Turkish `tr' and Ukrainian `uk'.
+
+For example, you may reach the Chinese translation team by writing to
+`zh@li.org'.
+
+ If you'd like to volunteer to *work* at translating messages, you
+should become a member of the translating team for your own language.
+The subscribing address is *not* the same as the list itself, it has
+`-request' appended. For example, speakers of Swedish can send a
+message to `sv-request@li.org', having this message body:
+
+ subscribe
+
+ Keep in mind that team members are expected to participate
+*actively* in translations, or at solving translational difficulties,
+rather than merely lurking around. If your team does not exist yet and
+you want to start one, or if you are unsure about what to do or how to
+get started, please write to `gnu-translation@gnu.ai.mit.edu' to reach
+the GNU coordinator for all translator teams.
+
+ The English team is special. It works at improving and uniformizing
+the terminology used in GNU. Proven linguistic skill are praised more
+than programming skill, here. For the time being, please avoid
+subscribing to the English team unless explicitly invited to do so.
+
+Available Packages
+==================
+
+ Languages are not equally supported in all GNU packages. The
+following matrix shows the current state of GNU internationalization,
+as of February 1997. The matrix shows, in regard of each package, for
+which languages PO files have been submitted to translation
+coordination.
+
+ Ready PO files cs de en es fi fr ja ko nl no pl pt sl sv
+ .-------------------------------------------.
+ bash | [] [] [] | 3
+ bison | [] [] [] | 3
+ clisp | [] [] [] | 3
+ cpio | [] [] [] [] [] | 5
+ diffutils | [] [] [] [] | 4
+ enscript | [] [] [] [] [] | 5
+ fileutils | [] [] [] [] [] [] [] [] | 8
+ findutils | [] [] [] [] [] [] [] | 7
+ flex | [] [] [] | 3
+ gcal | [] [] [] | 3
+ gettext | [] [] [] [] [] [] [] [] [] [] | 11
+ grep | [] [] [] [] [] [] [] [] | 8
+ hello | [] [] [] [] [] [] [] [] [] [] | 10
+ id-utils | [] [] | 2
+ indent | [] [] | 2
+ libc | [] [] [] [] [] [] [] | 7
+ m4 | [] [] [] [] [] | 5
+ make | [] [] [] [] [] [] | 6
+ music | [] | 1
+ ptx | [] [] [] [] [] [] [] [] | 8
+ recode | [] [] [] [] [] [] [] [] | 8
+ sh-utils | [] [] [] [] [] | 5
+ sharutils | [] [] [] [] [] | 5
+ tar | [] [] [] [] [] [] [] [] [] | 9
+ texinfo | | 0
+ textutils | [] [] [] [] [] [] | 6
+ wdiff | [] [] [] [] [] [] [] [] | 8
+ `-------------------------------------------'
+ 14 languages cs de en es fi fr ja ko nl no pl pt sl sv
+ 27 packages 1 22 1 14 1 25 1 10 20 7 14 7 7 15 145
+
+ Some counters in the preceding matrix are higher than the number of
+visible blocks let us expect. This is because a few extra PO files are
+used for implementing regional variants of languages, or language
+dialects.
+
+ For a PO file in the matrix above to be effective, the package to
+which it applies should also have been internationalized and
+distributed as such by its maintainer. There might be an observable
+lag between the mere existence a PO file and its wide availability in a
+GNU distribution.
+
+ If February 1997 seems to be old, you may fetch a more recent copy
+of this `ABOUT-NLS' file on most GNU archive sites.
+
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 00000000..93f8e657
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,20 @@
+Authors of GNU m4.
+
+The following contributions warranted legal paper exchanges with the
+Free Software Foundation. Also see files ChangeLog and THANKS.
+
+M4 Rene Seindal (DENMARK, 1964)
+Assigns the program.
+
+M4 University of Copenhagen
+Disclaims the program.
+
+M4 James L. Avera (USA) 10/4/93
+Assigns changes to M4.
+Changed (in m4-1.0.3): M4.c M4.h debug.c Makefile.in configure.in
+Changelog
+Added: stackovf.c tests/stackovf_test.sh
+
+M4 Pete Chown (UK, 1972) 6/28/94
+Assigns changes to M4 (builtin.c, input.c, m4.h, m4.texinfo, macro.c).
+
diff --git a/BACKLOG b/BACKLOG
new file mode 100644
index 00000000..addae38e
--- /dev/null
+++ b/BACKLOG
@@ -0,0 +1,51 @@
+# Summary of pending email for GNU m4 1.4.
+# Last updated: Saturday, November 05, 1994.
+
+rmail/announce
+ 1. 15 Sep 94 <pinard@IRO.UMontreal.CA> Release: GNU m4 1.3
+ 2. 29 Oct 94 <pinard@IRO.UMontreal.CA> Prerelease: GNU m4 1.3.1
+
+rmail/changeword
+ 1. 02 Sep 94 <pinard> Re: Prerelease: GNU m4 1.2.3
+ 2. 05 Sep 94 <Pete.Chown@dale.dircon.co.uk> Re: Prerelease: GNU m4 1.2.3
+
+rmail/configuration
+ 1. 03 Nov 94 <Fredrik_Lundh@ivab.se> Re: m4 1.3 on DEC OSF/1 3.0
+ 2. 05 Nov 94 <pinard> Re: m4 1.3 on DEC OSF/1 3.0
+
+rmail/documentation
+ 1. 05 Jun 92 <berstel@mipsmath.math.uqam.ca> Re: M4
+ 2. 10 Nov 92 <tchrist@convex.COM> Re: Is anyone using m4?
+ 3. 25 May 94 <schwab@issan.informatik.uni-dortmund.de> Autoconf 1.11: minor bu
+ 4. 27 Jul 94 <pinard@IRO.UMontreal.CA> Re: 0.95: Spacing details
+ 5. 28 Jul 94 <pinard@IRO.UMontreal.CA> Re: 0.95: Spacing details
+ 6. 31 Aug 94 <kb@cs.umb.edu> Re: Frozen file documentation to proofread
+
+rmail/floating-point
+ 1. 27 Oct 94 <johnm@vlibs.com> Re: enhancement to m4 eval()
+ 2. 25 Oct 94 <johnm@vlibs.com> enhancement to m4
+ 3. 27 Oct 94 <pinard> Re: enhancement to m4
+ 4. 27 Oct 94 <johnm@vlibs.com> Re: enhancement to m4 eval()
+ 5. 27 Oct 94 <pinard> Re: enhancement to m4 eval()
+ 6. 27 Oct 94 <johnm@vlibs.com> Re: enhancement to m4 eval()
+ 7. 28 Oct 94 <pinard> Re: enhancement to m4 eval()
+ 8. 28 Oct 94 <pinard> Re: enhancement to m4 eval()
+ 9. 28 Oct 94 <feeley@IRO.UMontreal.CA> Re: enhancement to m4 eval()
+10. 28 Oct 94 <pinard> Re: enhancement to m4 eval()
+11. 28 Oct 94 <johnm@vlibs.com> Re: enhancement to m4 eval()
+12. 28 Oct 94 <johnm@vlibs.com> Re: enhancement to m4 eval()
+13. 28 Oct 94 <pinard@IRO.UMontreal.CA> Re: enhancement to m4 eval()
+
+rmail/format-rewrite
+ 1. 25 Jun 94 <tmcconne@sedona.intel.com> Re: Prerelease: GNU m4 1.1.3
+
+rmail/named-formals
+ 1. 30 Sep 94 <djm@va.pubnix.com> m4 macros with named formal parameters
+
+rmail/purify
+ 1. 06 Dec 93 <vern@horse.ee.lbl.gov> m4 1.1.1 "make realclean"
+
+rmail/speed
+ 1. 29 Aug 94 <pinard> Re: diversions and freezing
+ 2. 05 Sep 94 <djm@va.pubnix.com> slowness
+ 3. 04 Oct 94 <pinard> Autoconf, m4, and dnl's.
diff --git a/COPYING b/COPYING
new file mode 100644
index 00000000..a43ea212
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) 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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. 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.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: 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
+convey 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) 19yy <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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This 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 Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 00000000..664472a5
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,1526 @@
+Sat Nov 5 15:52:47 1994 Francois Pinard (pinard@icule)
+
+ * Release 1.4.
+
+ * doc/Makefile.in (realclean): Also remove stamp-vti.
+ Reported by Eric Backus.
+
+Wed Nov 2 00:47:53 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Tue Nov 1 22:02:37 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Mon Oct 31 02:11:19 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sun Oct 30 08:13:03 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sat Oct 29 05:10:03 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Fri Oct 28 20:33:55 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Thu Oct 27 22:32:58 1994 Francois Pinard (pinard@icule)
+
+ * Makefile.in (mostlyclean-local): Do not remove *~.
+ * */Makefile.in (mostlyclean): Idem.
+ Reported by Robert E. Brown and Richard Stallman.
+
+Sun Oct 9 08:30:13 1994 Francois Pinard (pinard@icule)
+
+ * src/m4.h: Get rid of CONFIG_BROKETS.
+
+Sun Oct 2 16:48:10 1994 Francois Pinard (pinard@icule)
+
+ * configure.in: Use AC_ARG_PROGRAM.
+ * aclocal.m4 (fp_C_PROTOTYPES): Substitute @kr@ by kr or empty.
+ Reported by David MacKenzie.
+
+Sat Oct 1 11:22:42 1994 Francois Pinard (pinard@icule)
+
+ * configure.in: Do not add -O to CFLAGS for GNU C, now that
+ configure does it automatically.
+ Reported by Jim Meyering.
+
+Fri Sep 23 08:16:58 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sun Sep 18 11:42:50 1994 Francois Pinard (pinard@icule)
+
+ * src/Makefile.in (TAGS): Include a ../lib/TAGS reference.
+ Reported by Karl Berry.
+
+Wed Sep 14 10:00:22 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Tue Sep 13 19:21:05 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sat Sep 10 12:34:04 1994 Francois Pinard (pinard@icule)
+
+ * configure.in: Use fp_ to match aclocal.m4. Revert _OS_ macros
+ to old names, for following Autoconf.
+
+Thu Sep 8 15:07:27 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Tue Sep 6 12:07:33 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Fri Sep 2 10:37:10 1994 Francois Pinard (pinard@icule)
+
+ * lib/Makefile.in (install): Depend on all.
+
+Wed Aug 31 11:17:21 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Tue Aug 30 01:44:29 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Mon Aug 29 12:27:19 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sun Aug 28 05:20:02 1994 Francois Pinard (pinard@icule)
+
+ * Makefile.in, lib/Makefile.in, checks/Makefile.in: Arrange so
+ dist works from another build directory.
+
+Sat Aug 27 14:32:45 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Wed Aug 24 16:14:19 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Mon Aug 15 12:38:05 1994 Francois Pinard (pinard@icule)
+
+ * m4.c (long_options): Use "error-output", the dash was missing.
+ Reported by Akiko Matsushita.
+
+Fri Aug 12 16:38:01 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Fri Jul 29 10:15:52 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Thu Jul 21 22:43:17 1994 Francois Pinard (pinard@icule)
+
+ * m4.c (usage): Replace printf par fputs.
+
+Mon Jul 18 23:48:23 1994 Francois Pinard (pinard@icule)
+
+ * Release 1.2
+
+Sun Jul 17 08:08:25 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sat Jul 16 20:36:19 1994 Francois Pinard (pinard@icule)
+
+ * ansi2knr.c: New version sent by its author, Peter Deutsch.
+
+Fri Jul 15 14:36:21 1994 Francois Pinard (pinard@icule)
+
+ * Makefile.in: Modify so parallel make will not try making
+ lib/libm4.a twice simultaneously.
+ Reported by Jim Meyering.
+
+Thu Jul 14 17:23:17 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Tue Jul 12 06:54:31 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Thu Jul 7 22:38:10 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Wed Jul 6 13:16:31 1994 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.
+
+Tue Jul 5 19:13:54 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sat Jul 2 00:58:47 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Wed Jun 29 22:41:53 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Mon Jun 27 14:24:23 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sat Jun 25 00:10:05 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Fri Jun 24 23:30:31 1994 Francois Pinard (pinard@icule)
+
+ * Makefile.in (DISTFILES): Distribute install.sh.
+ * install.sh: New file, copied from elsewhere.
+ Reported by Assar Westerlund and Kaveh R. Ghazi.
+
+Thu Jun 23 00:00:30 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Wed Jun 22 21:58:54 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sun Jun 5 16:25:19 1994 Francois Pinard (pinard@icule)
+
+ * m4.h (_): Change argument from `x' to `Args'.
+
+Wed May 4 23:59:39 1994 Francois Pinard (pinard@icule)
+
+ * Makefile.in: Remove all occurrences of $(MFLAGS), which were
+ bringing more evil than good on a few systems.
+ Reported by Greg A. Woods.
+
+Fri Apr 22 15:59:35 1994 Francois Pinard (pinard@icule)
+
+ * m4.h: Rename Args() to _().
+ * m4.h: Remove extern specifier from all function declarations.
+
+Fri Apr 22 15:51:21 1994 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.
+
+Wed Apr 13 14:10:30 1994 Francois Pinard (pinard@icule)
+
+ * checks/Makefile.in: Rename .all-stamp to stamp-checks.
+
+ * Makefile.in (Makefile, etc.): Adapt for Autoconf 1.8.
+
+Sun Jan 30 14:24:19 1994 (pinard at icule)
+
+ * 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.
+
+Tue Jan 25 18:39:37 1994 Francois Pinard (pinard at icule)
+
+ * m4.h: Move the conditional definition of volatile after the
+ inclusion of system files, because they may define it first.
+
+Tue Jan 4 19:46:50 1994 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Mon Jan 3 00:21:45 1994 Francois Pinard (pinard@icule)
+
+ * Makefile.in: Do not define LDFLAGS, use CFLAGS on link calls.
+ Reported by Richard Stallman.
+
+Sat Dec 25 08:06:05 1993 Francois Pinard (pinard@icule)
+
+ * configure.in: Correct test for strerror, AC_FUNC_CHECK was used
+ instead of AC_HAVE_FUNCS.
+ Reported by Noah Friedman.
+
+Wed Dec 1 09:37:53 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sat Nov 27 10:43:24 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Wed Nov 24 22:16:15 1993 Francois Pinard (pinard@icule)
+
+ * checks/get-them: Escape braces with backslashes in patterns,
+ because HPUX-9.01 awk needs this.
+ Reported by Jim Meyering.
+
+Mon Nov 22 10:55:52 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sat Nov 20 08:26:15 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Wed Nov 17 09:34:55 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Fri Nov 12 10:02:26 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Tue Nov 9 09:31:47 1993 Francois Pinard (pinard@icule)
+
+ * m4.h: Do not define volatile if already defined.
+ Reported by Rene' 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.
+
+Mon Nov 8 21:11:44 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Mon Nov 8 12:45:34 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Fri Nov 5 09:49:30 1993 Francois Pinard (pinard@compy.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.
+
+Thu Nov 4 13:50:52 1993 Francois Pinard (pinard@lagrande.IRO.UMontreal.CA)
+
+ * lib/Makefile.in (dist): Correct permissions on files.
+
+ * output.c: Declare tmpfile, some systems don't.
+
+Wed Nov 3 09:09:16 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Tue Nov 2 00:55:41 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Mon Nov 1 07:45:24 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sat Oct 30 12:51:47 1993 Francois Pinard (pinard@icule)
+
+ * Makefile.in (m4.info): Use -I$(srcdir) on $(MAKEINFO).
+ Reported by Noah Friedman.
+
+Mon Oct 25 14:58:48 1993 Francois Pinard (pinard@icule)
+
+ * Makefile.in: Remove MDEFINES and cleanup.
+
+Wed Jun 9 14:59:46 1993 Francois Pinard (pinard@icule)
+
+ * Makefile.in (dist): Replace "echo `pwd`" by a mere "pwd".
+ Create a gzip file.
+
+Sat Feb 6 14:59:22 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Sun Jan 17 15:38:05 1993 Francois Pinard (pinard@icule)
+
+ * Makefile.in, lib/Makefile.in: Put $(CFLAGS) after $(CPPFLAGS),
+ so the installer can override automatically configured choices.
+ Reported by Karl Berry.
+
+Fri Jan 15 16:07:00 1993 Francois Pinard (pinard@icule)
+
+ * 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.
+
+Fri Jan 1 19:42:23 1993 Francois Pinard (pinard at icule)
+
+ * Makefile.in, lib/Makefile.in: Reinstate $(CPPFLAGS), use it.
+ Richard wants it there.
+
+Sun Dec 27 07:01:54 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Wed Dec 23 12:46:55 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+ Reported by Greg A. Woods.
+
+Sun Dec 20 10:40:20 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Sat Dec 19 08:21:34 1992 Francois Pinard (pinard at icule)
+
+ * 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!
+
+Fri Dec 18 11:08:03 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Wed Nov 18 07:57:19 1992 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.
+
+Tue Nov 17 01:58:40 1992 Francois Pinard (pinard at icule)
+
+ * *.[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.
+
+Mon Nov 16 20:42:56 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Mon Nov 16 07:48:52 1992 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'.
+
+Sun Nov 15 09:42:09 1992 Francois Pinard (pinard at icule)
+
+ * *.[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.
+
+Sat Nov 14 11:01:20 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Fri Nov 13 00:12:50 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Thu Nov 12 14:42:57 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Wed Nov 11 17:40:35 1992 Francois Pinard (pinard at icule)
+
+ * 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().
+
+Tue Nov 10 08:57:05 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Fri Nov 6 02:05:21 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Thu Nov 5 12:37:13 1992 Francois Pinard (pinard at icule)
+
+ * 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/.
+
+Tue Mar 10 00:29:46 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Mon Mar 9 14:53:40 1992 Francois Pinard (pinard at icule)
+
+ * 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.
+
+Sun Mar 8 11:01:55 1992 Francois Pinard (pinard at icule)
+
+ * 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 Rene' to Franc,ois.
+
+Thu Oct 24 15:18:46 1991 Rene' Seindal (seindal at 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.
+
+Fri Jul 26 15:28:42 1991 Rene' Seindal (seindal at diku.dk)
+
+ * Fixed various bugs. Release 0.99, manual 0.09. Many thanks to
+ Francois 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.
+
+Thu Nov 15 21:51:06 1990 Rene' Seindal (seindal at 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.
+
+Mon Jan 22 21:08:52 1990 Rene' Seindal (seindal at diku.dk)
+
+ * Initial beta release. Release 0.50, manual 0.05.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 00000000..0338fbce
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,167 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source directory by typing `make clean'. To also remove the files
+ that `configure' created (so you can compile the package for a
+ different kind of computer), type `make distclean'.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Using a Different Build Directory
+=================================
+
+ You can compile the package in a different directory from the one
+containing the source code. Doing so allows you to compile it on more
+than one kind of computer at the same time. To do this, you must use a
+version of `make' that supports the `VPATH' variable, such as GNU
+`make'. `cd' to the directory where you want the object files and
+executables to go and run the `configure' script. `configure'
+automatically checks for the source code in the directory that
+`configure' is in and in `..'.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Save the results of the tests in FILE instead of `config.cache'.
+ Set FILE to `/dev/null' to disable caching, for debugging
+ `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/LOCALE b/LOCALE
new file mode 100644
index 00000000..b3ce2ee9
--- /dev/null
+++ b/LOCALE
@@ -0,0 +1,41 @@
+This GNU package is `localizable'.
+
+It can be made to speak your native language (or mother tongue).
+If you are lucky, someone already did it for you. Check in the
+distribution for `??.tt' files. `??' is usually one of:
+
+ de for German
+ fr for French
+ nl for Dutch
+ sv for Swedish
+
+If your language is already supported, usage is quite simple.
+Let's suppose, here, that you speak German. At the shell prompt,
+merely execute `setenv LANG de' (in csh) or `export LANG; LANG=de'
+(in sh). You may want to put this in your .login or .profile file.
+
+If your language is not supported, you have to work a bit for it.
+Let's suppose again that you speak German. Eventually, when the GNU
+locale package will have been published, you will follow these steps:
+
+1) Check with the maintainer if the work has been, or is being done.
+2) Ensure that GNU locale has been installed on your site.
+3) In the distribution, initialize `de.tt' by copying `fr.tt'.
+4) Carefully edit `de.tt', replacing French parts by German parts.
+5) Edit `Makefile.in', adding `de.msg' to the `CATALOGS =' line.
+6) You do not need to reconfigure again. Execute `make install'.
+7) Use `setenv LANG de', and just use the programs as usual.
+8) Send `de.tt' to the maintainer, to be later distributed in GNU.
+
+But for the time being, GNU local package is still in alpha pretest,
+so you are not completely free of me yet! Follow these steps:
+
+1) Check with the maintainer if the work has been, or is being done.
+2) In the distribution, initialize `de.tt' by copying `fr.tt'.
+3) Carefully edit `de.tt', replacing French parts by German parts.
+4) Send `de.tt' to the maintainer, then wait for `de.msg' in return.
+5) Install `de.msg' as `/usr/local/share/locale/de/PACKAGE.msg'.
+6) Use `setenv LANG de', and just use the programs as usual.
+
+In step 5), of course, replace PACKAGE by the GNU package name, which
+is usually the first word in the name of the distributed tar file.
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 00000000..81175178
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,3 @@
+SUBDIRS=intl po doc lib src checks examples
+
+EXTRA_DIST = LOCALE
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 00000000..3de59a49
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,138 @@
+# Main Makefile for GNU m4.
+# Copyright (C) 1992, 1993, 1994 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 2, 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, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+PRODUCT = @PRODUCT@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+srcdir = @srcdir@
+VPATH = @srcdir@
+@SET_MAKE@
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = $(exec_prefix)/bin
+infodir = $(prefix)/info
+
+MDEFINES = CC='$(CC)' CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' LIBS='$(LIBS)' \
+prefix='$(prefix)' exec_prefix='$(exec_prefix)' \
+bindir='$(bindir)' infodir='$(infodir)'
+
+SUBDIRS = doc lib src checks examples
+
+DISTFILES = README NEWS TODO THANKS COPYING INSTALL ChangeLog c-boxes.el \
+configure.in acconfig.h aclocal.m4 mkinstalldirs install-sh Makefile.in \
+stamp-h.in config.h.in configure BACKLOG
+
+.SUFFIXES:
+
+all install uninstall: config.h
+ for subdir in $(SUBDIRS); do \
+ echo making $@ in $$subdir; \
+ (cd $$subdir && $(MAKE) $(MDEFINES) $@) || exit 1; \
+ done
+
+info dvi:
+ cd doc && $(MAKE) $@
+
+check: all
+ cd checks && $(MAKE) $@
+
+tags:
+ cd lib && $(MAKE) $@
+ cd src && $(MAKE) $@
+
+mostlyclean: mostlyclean-recursive mostlyclean-local
+
+clean: clean-recursive clean-local
+
+distclean: distclean-recursive distclean-local
+ rm config.status
+
+realclean: realclean-recursive realclean-local
+ rm config.status
+
+mostlyclean-recursive clean-recursive distclean-recursive realclean-recursive:
+ for subdir in $(SUBDIRS); do \
+ target=`echo $@ | sed 's/-recursive//'`; \
+ echo making $$target in $$subdir; \
+ (cd $$subdir && $(MAKE) $$target) || exit 1; \
+ done
+
+mostlyclean-local:
+
+clean-local: mostlyclean-local
+
+distclean-local: clean-local
+ rm -f Makefile config.cache config.h config.log stamp-h
+
+realclean-local: distclean-local
+
+dist: $(DISTFILES)
+ rm -rf $(PRODUCT)-$(VERSION)
+ mkdir $(PRODUCT)-$(VERSION)
+ chmod 777 $(PRODUCT)-$(VERSION)
+ @echo "Copying distribution files"
+ @for file in $(DISTFILES); do \
+ ln $(srcdir)/$$file $(PRODUCT)-$(VERSION) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(PRODUCT)-$(VERSION); \
+ done
+ for subdir in $(SUBDIRS); do \
+ echo making $@ in $$subdir; \
+ mkdir $(PRODUCT)-$(VERSION)/$$subdir; \
+ chmod 777 $(PRODUCT)-$(VERSION)/$$subdir; \
+ (cd $$subdir && $(MAKE) $@) || exit 1; \
+ done
+ chmod -R a+r $(PRODUCT)-$(VERSION)
+ tar chozf $(PRODUCT)-$(VERSION).tar.gz $(PRODUCT)-$(VERSION)
+ rm -rf $(PRODUCT)-$(VERSION)
+
+# For an explanation of the following Makefile rules, see node
+# `Automatic Remaking' in GNU Autoconf documentation.
+Makefile: Makefile.in config.status
+ CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+config.status: configure
+ ./config.status --recheck
+configure: configure.in aclocal.m4
+ cd $(srcdir) && autoconf
+
+config.h: stamp-h
+stamp-h: config.h.in config.status
+ CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
+config.h.in: stamp-h.in
+stamp-h.in: configure.in aclocal.m4 acconfig.h
+ cd $(srcdir) && autoheader
+ date > $(srcdir)/stamp-h.in
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS b/NEWS
new file mode 100644
index 00000000..932085e5
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,200 @@
+GNU m4 NEWS - User visible changes.
+Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+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 built-in 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:
diff --git a/README b/README
new file mode 100644
index 00000000..0b010f5f
--- /dev/null
+++ b/README
@@ -0,0 +1,31 @@
+GNU `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). `m4' also has built-in functions for including files,
+running shell commands, doing arithmetic, etc. Autoconf needs GNU
+`m4' for generating `configure' scripts, but not for running them.
+
+GNU `m4' has been originally written by Rene' Seindal, from Denmark.
+This release is to be considered as stable.
+
+If GNU `m4' is meant to serve GNU `autoconf', beware that `m4'
+should be fully installed *prior to* configuring `autoconf' itself.
+
+In the subdirectory `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 `BACKLOG' for a summary of pending mail and articles.
+See file `COPYING' for copying conditions.
+See file `INSTALL' for compilation and installation instructions.
+See file `NEWS' for a list of major changes in the current release.
+See file `THANKS' for a list of contributors.
+
+By using `./configure --enable-changeword', you get an experimental
+feature which allows for changing the syntax of what is a "word" in
+`m4'. This might go away, so don't count on it yet.
+
+Send bug reports to `bug-gnu-utils@prep.ai.mit.edu'. 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.
diff --git a/README-alpha b/README-alpha
new file mode 100644
index 00000000..4ed792df
--- /dev/null
+++ b/README-alpha
@@ -0,0 +1,12 @@
+This is a alpha version of GNU m4.
+
+Please see the file TODO for a list of open problems and known bugs.
+
+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, ...
+
+GNU m4 has a web-site at http://www.seindal.dk/rene/gnu/
diff --git a/THANKS b/THANKS
new file mode 100644
index 00000000..d5e4a905
--- /dev/null
+++ b/THANKS
@@ -0,0 +1,71 @@
+GNU m4 THANKS file
+
+GNU m4 has originally been written by Rene' Seindal. Many people
+further contributed to GNU m4 by reporting problems, suggesting
+various improvements or submitting actual code. Here is a list of
+these people. Help me keep it complete and exempt of errors.
+
+Akiko Matsushita matusita@sra.co.jp
+Alan Magnuson awm@osc.edu
+Alexander Lehmann alex@hal.rhein-main.de
+Amos Shapira amoss@cs.huji.ac.il
+Andreas Gustafsson gson@niksula.hut.fi
+Andreas Schwab schwab@ls5.informatik.uni-dortmund.de
+Assar Westerlund assar@nada.kth.se
+Ben A. Mesander ben@piglet.cr.usgs.gov
+Bengt Mertensson bengt@mathematik.uni-bremen.de
+Bernhard Daeubler daeb@physik.uni-ulm.de
+Bjorn R. Bjornsson brb@falcon.is
+Brendan Kehoe brendan@cygnus.com
+David J. MacKenzie djm@uunet.uu.net
+Erez Zadok ezk@cs.columbia.edu
+Eric Allman eric@cs.berkeley.edu
+Eric Backus ericb@lsid.hp.com
+Franc,ois Pinard pinard@iro.umontreal.ca
+Geoff Russell grussell@guest.adelaide.edu.au
+Greg A. Woods woods@web.apc.org
+Hal Peterson hrp@pecan.cray.com
+Hoang Uong hoang@ornews.intel.com
+Ian Taylor ian@cygnus.com
+Jason Merrill jason@jarthur.claremont.edu
+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
+Joseph E. Sacco jsacco@ssl.com
+Karl Berry karl@cs.umb.edu
+Karl Vogel vogelke@c-17igp.wpafb.af.mil
+Kaveh R. Ghazi ghazi@noc.rutgers.edu
+Kristine Lund lund@lpnaxp.in2p3.fr
+Krste Asanovic krste@icsi.berkeley.edu
+Marion Hakanson hakanson@cse.ogi.edu
+Mark Seiden mis@seiden.com
+Matthias Rabe rabe@mathematik.uni-bielefeld.de
+Michael Fetterman mafetter@ichips.intel.com
+Michael L. Welcome welcome@bigbird.llnl.gov
+Mike Lijewski lijewski@theory.tc.cornell.edu
+Nick S. Kanakakorn skanan@otl.scu.edu
+Nicolas Pioch pioch@inf.enst.fr
+Noah Friedman friedman@gnu.ai.mit.edu
+Pete Chown pete.chown@dale.dircon.co.uk
+Pierre Gaumond gaumondp@ere.umontreal.ca
+Pierre Mathieu mathieu@geod.emr.ca
+Robert Bernstein rocky@panix.com
+Rene' Seindal seindal@diku.dk
+Richard Stallman rms@gnu.ai.mit.edu
+Roland H. Pesch roland@wrs.com
+Roland McGrath roland@gnu.ai.mit.edu
+Scott Bartram deneb!scottb
+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
+Thorsten Ohl ohl@physics.harvard.edu
+Tom McConnell tmcconne@sedona.intel.com
+Tom Quinn trq@dionysos.thphys.ox.ac.uk
+Tom Tromey tromey@cns.caltech.edu
+Ulrich Drepper drepper@ira.uka.de
+Vern Paxson vern@ee.lbl.gov
+Vivek P. Singhal singhal@cs.utexas.edu
+Walter Wong wcw+@cmu.edu
diff --git a/TODO b/TODO
new file mode 100644
index 00000000..c53e93b8
--- /dev/null
+++ b/TODO
@@ -0,0 +1,41 @@
+TODO file for GNU m4
+
+Tell <pinard@iro.umontreal.ca> if you feel like volunteering for any
+of these ideas, listed more or less in decreasing order of priority.
+
+* Features or problems
+ - Update documentation from accumulated mail about it
+ - Changeword without arguments should restore default behavior
+ - Study synclines at the very beginning of each diverted sequence
+ - Make eval work on bignums - the 32 bits limit is artificial
+ From Krste Asanovic <krste@icsi.berkeley.edu>, 1993-03-20
+
+* Optimization and clean up
+ - Check for memory leaks and uninitialized reads
+ From Vern Paxson <vern@horse.ee.lbl.gov> on 1993-12-06
+ - Simplify format/ecvt code, together with HAVE_EFGCVT
+ - Finalize the stdarg vs varargs thing
+ - Profile GNU m4 and speed it up
+ From David J. MacKenzie <djm@eng.umd.edu>, 1993-01-20
+
+ GNU m4 should be sped up by a factor of three for competing
+ with other versions (I think that the lexer is not agressive
+ enough and too often return single characters; obstacks might
+ be a little abused, too).
+ - Have NULs go really undisturbed through GNU m4
+ See `dumpdef' and debugging section, which abuses %s
+ From Thorsten Ohl <ohl@chico.harvard.edu>, 1992-12-21
+
+ path.c (add_include_directory): Why the '\0' terminator?
+
+ GNU m4 is lousy regarding NULs in streams (this would require
+ maintaining the string lengths, and avoiding strlen, strcpy,
+ etc.).
+ - Clean up the obstack.[ch] code
+ - Use rx.[ch] instead of regex.[ch]
+ From Hal Peterson <hrp@ironwood.cray.com>, 1994-04-22
+
+Local Variables:
+mode: outline
+outline-regexp: " *[-+*.] \\| "
+End:
diff --git a/acconfig.h b/acconfig.h
new file mode 100644
index 00000000..807221aa
--- /dev/null
+++ b/acconfig.h
@@ -0,0 +1,36 @@
+/* Special definitions for GNU m4, processed by autoheader.
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+ Francois Pinard <pinard@iro.umontreal.ca>, 1993.
+*/
+
+/* Define to 1 if the changeword(REGEXP) functionnality is wanted. */
+#undef ENABLE_CHANGEWORD
+
+/* Define to 1 if you have ecvt(3), fcvt(3) and gcvt(3), define to 2 if
+ these are declared in <stdlib.h>. */
+#undef HAVE_EFGCVT
+
+/* Define to 1 if #include <signal.h> declares struct sigcontext */
+#undef HAVE_SIGCONTEXT
+
+/* Define to the name of the distribution. */
+#undef PRODUCT
+
+/* Define to 1 if ANSI function prototypes are usable. */
+#undef PROTOTYPES
+
+/* Define to int if rlim_t is not defined in sys/resource.h */
+#undef rlim_t
+
+/* Define to struct sigaltstack if stack_t is not defined in sys/signal.h */
+#undef stack_t
+
+/* Define to 1 if using stack overflow detection. */
+#undef USE_STACKOVF
+
+/* Define to the version of the distribution. */
+#undef VERSION
+
+/* Define to 1 for better use of the debugging malloc library. See
+ site ftp.antaire.com in antaire/src, file dmalloc/dmalloc.tar.gz. */
+#undef WITH_DMALLOC
diff --git a/acinclude.m4 b/acinclude.m4
new file mode 100644
index 00000000..a670f1cb
--- /dev/null
+++ b/acinclude.m4
@@ -0,0 +1,418 @@
+#serial 1
+
+dnl FIXME: put these prerequisite-only *.m4 files in a separate
+dnl directory -- otherwise, they'll conflict with existing files.
+
+dnl These are the prerequisite macros for GNU's error.c file.
+AC_DEFUN(jm_PREREQ_ERROR,
+[
+ AC_CHECK_FUNCS(strerror strerror_r vprintf doprnt)
+ AC_HEADER_STDC
+])
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# Modified for GNU m4 by René Seindal (rene@seindal.dk)
+
+# serial 5
+
+AC_DEFUN(AM_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS)
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CHECK_LIB(intl, gettext,
+ [LIBS="$LIBS -lintl"
+ gt_cv_func_gettext_libintl=yes],
+ [gt_cv_func_gettext_libintl=no])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT)
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ if test "$CATOBJEXT" = "NONE"; then
+ AC_MSG_CHECKING([whether catgets can be used])
+ AC_ARG_WITH(catgets,
+ [ --with-catgets use catgets functions if available],
+ nls_cv_use_catgets=$withval, nls_cv_use_catgets=no)
+ AC_MSG_RESULT($nls_cv_use_catgets)
+
+ if test "$nls_cv_use_catgets" = "yes"; then
+ dnl No gettext in C library. Try catgets next.
+ AC_CHECK_LIB(i, main)
+ AC_CHECK_FUNC(catgets,
+ [AC_DEFINE(HAVE_CATGETS)
+ INTLOBJS="\$(CATOBJS)"
+ AC_PATH_PROG(GENCAT, gencat, no)dnl
+ if test "$GENCAT" != "no"; then
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, no)
+ if test "$GMSGFMT" = "no"; then
+ AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)
+ fi
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.cat
+ INSTOBJEXT=.cat
+ DATADIRNAME=lib
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi])
+ fi
+ fi
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext program is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+ AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl)
+ AC_OUTPUT_COMMANDS(
+ [case "$CONFIG_FILES" in *po/Makefile.in*)
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+ esac])
+
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(AM_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+strdup __argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY)
+ fi
+
+ AM_LC_MESSAGES
+ AM_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ test -d intl || mkdir intl
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
+ dnl find the mkinstalldirs script in another subdir but ($top_srcdir).
+ dnl Try to locate is.
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile.
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES)
+ fi
+ fi])
+
+#serial 2
+
+dnl Derived from code in GNU grep.
+
+AC_DEFUN(jm_WITH_REGEX,
+ [
+ dnl Even packages that don't use regex.c can use this macro.
+ dnl Of course, for them it doesn't do anything.
+
+ syscmd([test -f lib/regex.c])
+ ifelse(sysval, 0,
+ [
+ AC_ARG_WITH(included-regex,
+ [ --without-included-regex don't compile regex (use with caution)],
+ jm_with_regex=$withval,
+ jm_with_regex=yes)
+ if test "$jm_with_regex" = yes; then
+ LIBOBJS="$LIBOBJS regex.o"
+ fi
+ ],
+ )
+ ]
+)
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 00000000..90812401
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,85 @@
+# Local additions to Autoconf macros.
+# Copyright (C) 1992, 1994 Free Software Foundation, Inc.
+# Francois Pinard <pinard@iro.umontreal.ca>, 1992.
+
+# @defmac AC_PROG_CC_STDC
+# @maindex PROG_CC_STDC
+# @ovindex CC
+# If the C compiler in not in ANSI C mode by default, try to add an option
+# to output variable @code{CC} to make it so. This macro tries various
+# options that select ANSI C on some system or another. It considers the
+# compiler to be in ANSI C mode if it defines @code{__STDC__} to 1 and
+# handles function prototypes correctly.
+#
+# If you use this macro, you should check after calling it whether the C
+# compiler has been set to accept ANSI C; if not, the shell variable
+# @code{ac_cv_prog_cc_stdc} is set to @samp{no}. If you wrote your source
+# code in ANSI C, you can make an un-ANSIfied copy of it by using the
+# program @code{ansi2knr}, which comes with Ghostscript.
+# @end defmac
+
+define(fp_PROG_CC_STDC,
+[AC_MSG_CHECKING(for ${CC-cc} option to accept ANSI C)
+AC_CACHE_VAL(ac_cv_prog_cc_stdc,
+[ac_cv_prog_cc_stdc=no
+ac_save_CFLAGS="$CFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX -Aa -D_HPUX_SOURCE
+# SVR4 -Xc
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
+do
+ CFLAGS="$ac_save_CFLAGS $ac_arg"
+ AC_TRY_COMPILE(
+[#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+], [int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};],
+[ac_cv_prog_cc_stdc="$ac_arg"; break])
+done
+CFLAGS="$ac_save_CFLAGS"
+])
+AC_MSG_RESULT($ac_cv_prog_cc_stdc)
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+])
+
+# Check for function prototypes.
+
+AC_DEFUN(fp_C_PROTOTYPES,
+[AC_REQUIRE([fp_PROG_CC_STDC])
+AC_MSG_CHECKING([for function prototypes])
+if test "$ac_cv_prog_cc_stdc" != no; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(PROTOTYPES)
+ U= ANSI2KNR=
+else
+ AC_MSG_RESULT(no)
+ U=_ ANSI2KNR=ansi2knr
+fi
+AC_SUBST(U)dnl
+AC_SUBST(ANSI2KNR)dnl
+])
+
+# Check if --with-dmalloc was given.
+
+AC_DEFUN(fp_WITH_DMALLOC,
+[AC_MSG_CHECKING(if malloc debugging is wanted)
+AC_ARG_WITH(dmalloc,
+[ --with-dmalloc use dmalloc, as in dmalloc.tar.gz from
+ @/ftp.antaire.com:antaire/src/dmalloc.],
+[if test "$withval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(WITH_DMALLOC)
+ LIBS="$LIBS -ldmalloc"
+ LDFLAGS="$LDFLAGS -g"
+else
+ AC_MSG_RESULT(no)
+fi], [AC_MSG_RESULT(no)])])
+
diff --git a/acm4/Makefile.am b/acm4/Makefile.am
new file mode 100644
index 00000000..1d2df7af
--- /dev/null
+++ b/acm4/Makefile.am
@@ -0,0 +1,12 @@
+EXTRA_DIST = $(ACINCLUDES_M4)
+
+ACINCLUDES_M4 = error.m4 gettext.m4 regex.m4
+
+ACINCLUDE_M4 = $(top_srcdir)/acinclude.m4
+
+all: $(ACINCLUDE_M4)
+
+$(ACINCLUDE_M4): $(ACINCLUDES_M4)
+ cat $(ACINCLUDES_M4) > $@
+ cd $(top_srcdir) && $(ACLOCAL)
+# cd $(top_srcdir) && $(MAKE)
diff --git a/acm4/Makefile.in b/acm4/Makefile.in
new file mode 100644
index 00000000..77d1cdd7
--- /dev/null
+++ b/acm4/Makefile.in
@@ -0,0 +1,186 @@
+# Makefile.in generated automatically by automake 1.3b from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# This Makefile.in 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+PACKAGE = @PACKAGE@
+PERL = @PERL@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+STACKOVF = @STACKOVF@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+l = @l@
+
+EXTRA_DIST = $(ACINCLUDES_M4)
+
+ACINCLUDES_M4 = error.m4 gettext.m4 regex.m4
+
+ACINCLUDE_M4 = $(top_srcdir)/acinclude.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+all: Makefile
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps acm4/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = acm4
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done
+info:
+dvi:
+check: all
+installcheck:
+install-exec:
+ @$(NORMAL_INSTALL)
+
+install-data:
+ @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+ @:
+
+uninstall:
+
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean: mostlyclean-generic
+
+clean: clean-generic mostlyclean
+
+distclean: distclean-generic clean
+ -rm -f config.status
+
+maintainer-clean: maintainer-clean-generic distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: tags distdir info dvi installcheck install-exec install-data \
+install uninstall all installdirs mostlyclean-generic distclean-generic \
+clean-generic maintainer-clean-generic clean mostlyclean distclean \
+maintainer-clean
+
+
+all: $(ACINCLUDE_M4)
+
+$(ACINCLUDE_M4): $(ACINCLUDES_M4)
+ cat $(ACINCLUDES_M4) > $@
+ cd $(top_srcdir) && $(ACLOCAL)
+# cd $(top_srcdir) && $(MAKE)
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/acm4/error.m4 b/acm4/error.m4
new file mode 100644
index 00000000..eb0f776b
--- /dev/null
+++ b/acm4/error.m4
@@ -0,0 +1,11 @@
+#serial 1
+
+dnl FIXME: put these prerequisite-only *.m4 files in a separate
+dnl directory -- otherwise, they'll conflict with existing files.
+
+dnl These are the prerequisite macros for GNU's error.c file.
+AC_DEFUN(jm_PREREQ_ERROR,
+[
+ AC_CHECK_FUNCS(strerror strerror_r vprintf doprnt)
+ AC_HEADER_STDC
+])
diff --git a/acm4/gettext.m4 b/acm4/gettext.m4
new file mode 100644
index 00000000..969d0922
--- /dev/null
+++ b/acm4/gettext.m4
@@ -0,0 +1,384 @@
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# Modified for GNU m4 by René Seindal (rene@seindal.dk)
+
+# serial 5
+
+AC_DEFUN(AM_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS)
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CHECK_LIB(intl, gettext,
+ [LIBS="$LIBS -lintl"
+ gt_cv_func_gettext_libintl=yes],
+ [gt_cv_func_gettext_libintl=no])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT)
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ if test "$CATOBJEXT" = "NONE"; then
+ AC_MSG_CHECKING([whether catgets can be used])
+ AC_ARG_WITH(catgets,
+ [ --with-catgets use catgets functions if available],
+ nls_cv_use_catgets=$withval, nls_cv_use_catgets=no)
+ AC_MSG_RESULT($nls_cv_use_catgets)
+
+ if test "$nls_cv_use_catgets" = "yes"; then
+ dnl No gettext in C library. Try catgets next.
+ AC_CHECK_LIB(i, main)
+ AC_CHECK_FUNC(catgets,
+ [AC_DEFINE(HAVE_CATGETS)
+ INTLOBJS="\$(CATOBJS)"
+ AC_PATH_PROG(GENCAT, gencat, no)dnl
+ if test "$GENCAT" != "no"; then
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, no)
+ if test "$GMSGFMT" = "no"; then
+ AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)
+ fi
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.cat
+ INSTOBJEXT=.cat
+ DATADIRNAME=lib
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi])
+ fi
+ fi
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext program is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+ AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl)
+ AC_OUTPUT_COMMANDS(
+ [case "$CONFIG_FILES" in *po/Makefile.in*)
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+ esac])
+
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(AM_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+strdup __argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY)
+ fi
+
+ AM_LC_MESSAGES
+ AM_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ test -d intl || mkdir intl
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
+ dnl find the mkinstalldirs script in another subdir but ($top_srcdir).
+ dnl Try to locate is.
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile.
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES)
+ fi
+ fi])
+
diff --git a/acm4/gmp.m4 b/acm4/gmp.m4
new file mode 100644
index 00000000..beea42b5
--- /dev/null
+++ b/acm4/gmp.m4
@@ -0,0 +1,30 @@
+AC_DEFUN(AM_WITH_GMP,
+ [AC_MSG_CHECKING(if extended and fractional arithmetic is wanted)
+ AC_ARG_WITH(gmp,
+ [ --with-gmp use gmp for extended and fractional arithmetic],
+ [use_gmp=$withval], [use_gmp=no])
+ AC_MSG_RESULT($use_gmp)
+
+ if test "$use_gmp" = yes; then
+ LIBS="$LIBS -lgmp"
+ AC_CHECK_HEADER([gmp.h],
+ [AC_CACHE_CHECK([for mpq_init in libgmp], ac_cv_func_mpq_init_libgmp,
+ [AC_TRY_LINK([#include <gmp.h>],
+ [mpq_t x; (void)mpq_init(x)],
+ ac_cv_func_mpq_init_libgmp=yes,
+ ac_cv_func_mpq_init_libgmp=no)])],
+ ac_cv_func_mpq_init_libgmp=no)
+
+ if test "$ac_cv_func_mpq_init_libgmp$ac_cv_header_gmp_h" = yesyes; then
+ AC_DEFINE(WITH_GMP)
+ else
+ LIBS=`echo $LIBS | sed -e 's/-lgmp//'`
+ AC_MSG_WARN([gmp library not found or does not appear to work])
+ use_gmp=no
+ fi
+ fi
+
+ if test "$use_gmp" != yes; then
+ AC_CHECK_SIZEOF(long long int, 0)
+ fi
+ ])
diff --git a/acm4/ltdl.m4 b/acm4/ltdl.m4
new file mode 100644
index 00000000..1601efc2
--- /dev/null
+++ b/acm4/ltdl.m4
@@ -0,0 +1,429 @@
+## libltdl.m4 - Configure ltdl for the target system. -*-Shell-script-*-
+## Copyright (C) 1999 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 2 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 1 AC_LIB_LTDL
+
+AC_DEFUN(AC_LIB_LTDL,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_C_CONST])dnl
+AC_REQUIRE([AC_C_INLINE])dnl
+
+dnl AC_LIB_LTDL must perform all the checks necessary for compilation
+dnl of the ltdl objects -- including compiler checks (above) and header
+dnl checks (below).
+AC_REQUIRE([AC_HEADER_STDC])dnl
+
+AC_CHECK_HEADERS(malloc.h memory.h stdlib.h stdio.h ctype.h dlfcn.h dl.h dld.h)
+AC_CHECK_HEADERS(string.h strings.h, break)
+AC_CHECK_FUNCS(strchr index, break)
+AC_CHECK_FUNCS(strrchr rindex, break)
+
+AC_REQUIRE([AC_LTDL_ENABLE_INSTALL])dnl
+AC_REQUIRE([AC_LTDL_SHLIBEXT])dnl
+AC_REQUIRE([AC_LTDL_SHLIBPATH])dnl
+AC_REQUIRE([AC_LTDL_OBJDIR])dnl
+AC_REQUIRE([AC_LTDL_DLPREOPEN])dnl
+AC_REQUIRE([AC_LTDL_DLLIB])dnl
+AC_REQUIRE([AC_LTDL_SYMBOL_USCORE])dnl
+])
+
+AC_DEFUN(AC_LTDL_ENABLE_INSTALL,
+[AC_ARG_ENABLE(ltdl-install,
+[ --enable-ltdl-install install libltdl])
+
+AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno)
+AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno)
+])])
+
+
+AC_DEFUN(AC_LTDL_SNARF_CONFIG,
+[# Read the libtool configuration
+rm -f conftest
+./libtool --config > conftest
+. ./conftest
+rm -f conftest
+])
+
+AC_DEFUN(AC_LTDL_SHLIBEXT,
+[AC_REQUIRE([AC_LTDL_SNARF_CONFIG])dnl
+AC_CACHE_CHECK([which extension is used for shared libraries],
+ libltdl_cv_shlibext, [dnl
+(
+ last=
+ for spec in $library_names_spec; do
+ last="$spec"
+ done
+changequote(, )
+ echo "$last" | sed 's/\[.*\]//;s/^[^.]*//;s/\$.*$//;s/\.$//' > conftest
+changequote([, ])
+)
+libltdl_cv_shlibext=`cat conftest`
+rm -f conftest
+])
+if test -n "$libltdl_cv_shlibext"; then
+ AC_DEFINE_UNQUOTED(LTDL_SHLIB_EXT, "$libltdl_cv_shlibext",
+ [Define to the extension used for shared libraries, say, ".so". ])
+fi
+])
+
+AC_DEFUN(AC_LTDL_SHLIBPATH,
+[AC_REQUIRE([AC_LTDL_SNARF_CONFIG])dnl
+AC_CACHE_CHECK([which variable specifies run-time library path],
+ libltdl_cv_shlibpath_var, [libltdl_cv_shlibpath_var="$shlibpath_var"])
+if test -n "$libltdl_cv_shlibpath_var"; then
+ AC_DEFINE_UNQUOTED(LTDL_SHLIBPATH_VAR, "$libltdl_cv_shlibpath_var",
+ [Define to the name of the environment variable that determines the dynamic library search path. ])
+fi
+])
+
+AC_DEFUN(AC_LTDL_OBJDIR,
+[AC_CACHE_CHECK([for objdir],
+ libltdl_cv_objdir, [libltdl_cv_objdir="$objdir"
+if test -n "$objdir"; then
+ :
+else
+ rm -f .libs 2>/dev/null
+ mkdir .libs 2>/dev/null
+ if test -d .libs; then
+ libltdl_cv_objdir=.libs
+ else
+ # MS-DOS does not allow filenames that begin with a dot.
+ libltdl_cv_objdir=_libs
+ fi
+rmdir .libs 2>/dev/null
+fi])
+AC_DEFINE_UNQUOTED(LTDL_OBJDIR, "$libltdl_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries. ])
+])
+
+AC_DEFUN(AC_LTDL_DLPREOPEN,
+[AC_REQUIRE([AC_LTDL_GLOBAL_SYMBOL_PIPE])dnl
+AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen],
+ libltdl_cv_preloaded_symbols, [dnl
+ if test -n "$global_symbol_pipe"; then
+ libltdl_cv_preloaded_symbols=yes
+ else
+ libltdl_cv_preloaded_symbols=no
+ fi
+])
+if test x"$libltdl_cv_preloaded_symbols" = x"yes"; then
+ AC_DEFINE(HAVE_PRELOADED_SYMBOLS, 1,
+ [Define if libtool can extract symbol lists from object files. ])
+fi
+])
+
+AC_DEFUN(AC_LTDL_DLLIB,
+[LIBADD_DL=
+AC_CHECK_LIB(dl, dlopen, [AC_DEFINE(HAVE_LIBDL, 1,
+ [Define if you have the libdl library or equivalent. ]) LIBADD_DL="-ldl"],
+[AC_CHECK_FUNC(dlopen, [AC_DEFINE(HAVE_LIBDL, 1,
+ [Define if you have the libdl library or equivalent.])])])
+AC_CHECK_FUNC(shl_load, [AC_DEFINE(HAVE_SHL_LOAD, 1,
+ [Define if you have the shl_load function.])],
+[AC_CHECK_LIB(dld, shl_load,
+ [AC_DEFINE(HAVE_SHL_LOAD, 1,
+ [Define if you have the shl_load function.])
+ LIBADD_DL="$LIBADD_DL -ldld"])
+])
+AC_CHECK_LIB(dld, dld_link, [AC_DEFINE(HAVE_DLD, 1,
+ [Define if you have the GNU dld library.])dnl
+test "x$ac_cv_lib_dld_shl_load" = yes || LIBADD_DL="$LIBADD_DL -ldld"])
+AC_SUBST(LIBADD_DL)
+
+if test "x$ac_cv_func_dlopen" = xyes || test "x$ac_cv_lib_dl_dlopen" = xyes; then
+ LIBS_SAVE="$LIBS"
+ LIBS="$LIBS $LIBADD_DL"
+ AC_CHECK_FUNCS(dlerror)
+ LIBS="$LIBS_SAVE"
+fi
+])
+
+AC_DEFUN(AC_LTDL_GLOBAL_SYMBOL_PIPE,
+[dnl Check for command to grab the raw symbol name followed
+dnl by C symbol name from nm.
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
+[# These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+changequote(,)dnl
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+changequote([,])dnl
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($ac_symcode\)[ ][ ]*\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+changequote(,)dnl
+lt_preloaded_symbols[] =
+changequote([,])dnl
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+ else
+ echo "$progname: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+AC_MSG_RESULT($ac_result)
+])
+
+AC_DEFUN(AC_LTDL_SYMBOL_USCORE,
+[dnl does the compiler prefix global symbols with an underscore?
+AC_REQUIRE([AC_LTDL_GLOBAL_SYMBOL_PIPE])dnl
+AC_MSG_CHECKING([for _ prefix in compiled symbols])
+AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
+[ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+fi
+rm -rf conftest*
+])
+AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
+AC_LTDL_DLSYM_USCORE
+])
+
+AC_DEFUN(AC_LTDL_DLSYM_USCORE,
+[AC_REQUIRE([AC_LTDL_SYMBOL_USCORE])dnl
+if test x"$ac_cv_sys_symbol_underscore" = xyes; then
+ if test x"$ac_cv_func_dlopen" = xyes ||
+ test x"$ac_cv_lib_dl_dlopen" = xyes ; then
+ AC_CACHE_CHECK([whether we have to add an underscore for dlsym],
+ libltdl_cv_need_uscore, [dnl
+ AC_TRY_RUN([
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 && !ptr2) { dlclose(self); exit(0); } } exit(1); }
+], libltdl_cv_need_uscore=no, libltdl_cv_need_uscore=yes,
+ libltdl_cv_need_uscore=cross
+)])
+ fi
+fi
+
+if test x"$libltdl_cv_need_uscore" = xyes; then
+ AC_DEFINE(NEED_USCORE, 1,
+ [Define if dlsym() requires a leading underscode in symbol names. ])
+fi
+])
diff --git a/acm4/modules.m4 b/acm4/modules.m4
new file mode 100644
index 00000000..c4a47b76
--- /dev/null
+++ b/acm4/modules.m4
@@ -0,0 +1,27 @@
+AC_DEFUN(AM_WITH_MODULES,
+ [AC_MSG_CHECKING(if support for dynamic modules is wanted)
+ AC_ARG_WITH(modules,
+ [ --with-modules add support for dynamic modules],
+ [use_modules=$withval], [use_modules=no])
+ AC_MSG_RESULT($use_modules)
+
+ if test "$use_modules" = yes; then
+ LIBS="$LIBS -ldl"
+ AC_CHECK_HEADER([dlfcn.h],
+ [AC_CACHE_CHECK([for dlopen in libdl], ac_cv_func_dlopen_libdl,
+ [AC_TRY_LINK([#include <dlfcn.h>],
+ [(void)dlopen(0, RTLD_NOW)],
+ ac_cv_func_dlopen_libdl=yes,
+ ac_cv_func_dlopen_libdl=no)])],
+ ac_cv_func_dlopen_libdl=no)
+
+ if test "$ac_cv_func_dlopen_libdl$ac_cv_header_dlfcn_h" = yesyes; then
+ AC_DEFINE(WITH_MODULES)
+ LDFLAGS="$LDFLAGS -rdynamic"
+ else
+ LIBS=`echo $LIBS | sed -e 's/-ldl//'`
+ AC_MSG_WARN([-ldl library not found or does not appear to work])
+ use_modules=no
+ fi
+ fi
+ ])
diff --git a/acm4/regex.m4 b/acm4/regex.m4
new file mode 100644
index 00000000..e5468c65
--- /dev/null
+++ b/acm4/regex.m4
@@ -0,0 +1,23 @@
+#serial 2
+
+dnl Derived from code in GNU grep.
+
+AC_DEFUN(jm_WITH_REGEX,
+ [
+ dnl Even packages that don't use regex.c can use this macro.
+ dnl Of course, for them it doesn't do anything.
+
+ syscmd([test -f lib/regex.c])
+ ifelse(sysval, 0,
+ [
+ AC_ARG_WITH(included-regex,
+ [ --without-included-regex don't compile regex (use with caution)],
+ jm_with_regex=$withval,
+ jm_with_regex=yes)
+ if test "$jm_with_regex" = yes; then
+ LIBOBJS="$LIBOBJS regex.o"
+ fi
+ ],
+ )
+ ]
+)
diff --git a/c-boxes.el b/c-boxes.el
new file mode 100644
index 00000000..c1b80e33
--- /dev/null
+++ b/c-boxes.el
@@ -0,0 +1,406 @@
+;;; Boxed comments for C mode.
+;;; Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+;;; Francois Pinard <pinard@iro.umontreal.ca>, April 1991.
+;;;
+;;; I often refill paragraphs inside C comments, while stretching or
+;;; shrinking the surrounding box as needed. This is a real pain to
+;;; do by hand. Here is the code I made to ease my life on this,
+;;; usable from within GNU Emacs. It would not be fair giving all
+;;; sources for a product without also giving the means for nicely
+;;; modifying them.
+;;;
+;;; The function rebox-c-comment adjust comment boxes without
+;;; refilling comment paragraphs, while reindent-c-comment adjust
+;;; comment boxes after refilling. Numeric prefixes are used to add,
+;;; remove, or change the style of the box surrounding the comment.
+;;; Since refilling paragraphs in C mode does make sense only for
+;;; comments, this code redefines the M-q command in C mode. I use
+;;; this hack by putting, in my .emacs file:
+;;;
+;;; (setq c-mode-hook
+;;; '(lambda ()
+;;; (define-key c-mode-map "\M-q" 'reindent-c-comment)))
+;;; (autoload 'rebox-c-comment "c-boxes" nil t)
+;;; (autoload 'reindent-c-comment "c-boxes" nil t)
+;;;
+;;; The cursor should be within a comment before any of these
+;;; commands, or else it should be between two comments, in which case
+;;; the command applies to the next comment. When the command is
+;;; given without prefix, the current comment box type is recognized
+;;; and preserved. Given 0 as a prefix, the comment box disappears
+;;; and the comment stays between a single opening `/*' and a single
+;;; closing `*/'. Given 1 or 2 as a prefix, a single or doubled lined
+;;; comment box is forced. Given 3 as a prefix, a Taarna style box is
+;;; forced, but you do not even want to hear about those. When a
+;;; negative prefix is given, the absolute value is used, but the
+;;; default style is changed. Any other value (like C-u alone) forces
+;;; the default box style.
+;;;
+;;; I observed rounded corners first in some code from Warren Tucker
+;;; <wht@n4hgf.mt-park.ga.us>.
+
+(defvar c-box-default-style 'single "*Preferred style for box comments.")
+(defvar c-mode-taarna-style nil "*Non-nil for Taarna team C-style.")
+
+;;; Set or reset the Taarna team's own way for a C style.
+
+(defun taarna-mode ()
+ (interactive)
+ (if c-mode-taarna-style
+ (progn
+
+ (setq c-mode-taarna-style nil)
+ (setq c-indent-level 2)
+ (setq c-continued-statement-offset 2)
+ (setq c-brace-offset 0)
+ (setq c-argdecl-indent 5)
+ (setq c-label-offset -2)
+ (setq c-tab-always-indent t)
+ (setq c-box-default-style 'single)
+ (message "C mode: GNU style"))
+
+ (setq c-mode-taarna-style t)
+ (setq c-indent-level 4)
+ (setq c-continued-statement-offset 4)
+ (setq c-brace-offset -4)
+ (setq c-argdecl-indent 4)
+ (setq c-label-offset -4)
+ (setq c-tab-always-indent t)
+ (setq c-box-default-style 'taarna)
+ (message "C mode: Taarna style")))
+
+;;; Return the minimum value of the left margin of all lines, or -1 if
+;;; all lines are empty.
+
+(defun buffer-left-margin ()
+ (let ((margin -1))
+ (goto-char (point-min))
+ (while (not (eobp))
+ (skip-chars-forward " \t")
+ (if (not (looking-at "\n"))
+ (setq margin
+ (if (< margin 0)
+ (current-column)
+ (min margin (current-column)))))
+ (forward-line 1))
+ margin))
+
+;;; Return the maximum value of the right margin of all lines. Any
+;;; sentence ending a line has a space guaranteed before the margin.
+
+(defun buffer-right-margin ()
+ (let ((margin 0) period)
+ (goto-char (point-min))
+ (while (not (eobp))
+ (end-of-line)
+ (if (bobp)
+ (setq period 0)
+ (backward-char 1)
+ (setq period (if (looking-at "[.?!]") 1 0))
+ (forward-char 1))
+ (setq margin (max margin (+ (current-column) period)))
+ (forward-char 1))
+ margin))
+
+;;; Add, delete or adjust a C comment box. If FLAG is nil, the
+;;; current boxing style is recognized and preserved. When 0, the box
+;;; is removed; when 1, a single lined box is forced; when 2, a double
+;;; lined box is forced; when 3, a Taarna style box is forced. If
+;;; negative, the absolute value is used, but the default style is
+;;; changed. For any other value (like C-u), the default style is
+;;; forced. If REFILL is not nil, refill the comment paragraphs prior
+;;; to reboxing.
+
+(defun rebox-c-comment-engine (flag refill)
+ (save-restriction
+ (let ((undo-list buffer-undo-list)
+ (marked-point (point-marker))
+ (saved-point (point))
+ box-style left-margin right-margin)
+
+ ;; First, find the limits of the block of comments following or
+ ;; enclosing the cursor, or return an error if the cursor is not
+ ;; within such a block of comments, narrow the buffer, and
+ ;; untabify it.
+
+ ;; - insure the point is into the following comment, if any
+
+ (skip-chars-forward " \t\n")
+ (if (looking-at "/\\*")
+ (forward-char 2))
+
+ (let ((here (point)) start end temp)
+
+ ;; - identify a minimal comment block
+
+ (search-backward "/*")
+ (setq temp (point))
+ (beginning-of-line)
+ (setq start (point))
+ (skip-chars-forward " \t")
+ (if (< (point) temp)
+ (progn
+ (goto-char saved-point)
+ (error "text before comment's start")))
+ (search-forward "*/")
+ (setq temp (point))
+ (end-of-line)
+ (if (looking-at "\n")
+ (forward-char 1))
+ (setq end (point))
+ (skip-chars-backward " \t\n")
+ (if (> (point) temp)
+ (progn
+ (goto-char saved-point)
+ (error "text after comment's end")))
+ (if (< end here)
+ (progn
+ (goto-char saved-point)
+ (error "outside any comment block")))
+
+ ;; - try to extend the comment block backwards
+
+ (goto-char start)
+ (while (and (not (bobp))
+ (progn (previous-line 1)
+ (beginning-of-line)
+ (looking-at "[ \t]*/\\*.*\\*/[ \t]*$")))
+ (setq start (point)))
+
+ ;; - try to extend the comment block forward
+
+ (goto-char end)
+ (while (looking-at "[ \t]*/\\*.*\\*/[ \t]*$")
+ (forward-line 1)
+ (beginning-of-line)
+ (setq end (point)))
+
+ ;; - narrow to the whole block of comments
+
+ (narrow-to-region start end))
+
+ ;; Second, remove all the comment marks, and move all the text
+ ;; rigidly to the left to insure the left margin stays at the
+ ;; same place. At the same time, recognize and save the box
+ ;; style in BOX-STYLE.
+
+ (let ((previous-margin (buffer-left-margin))
+ actual-margin)
+
+ ;; - remove all comment marks
+
+ (goto-char (point-min))
+ (replace-regexp "^\\([ \t]*\\)/\\*" "\\1 ")
+ (goto-char (point-min))
+ (replace-regexp "^\\([ \t]*\\)|" "\\1 ")
+ (goto-char (point-min))
+ (replace-regexp "\\(\\*/\\||\\)[ \t]*" "")
+ (goto-char (point-min))
+ (replace-regexp "\\*/[ \t]*/\\*" " ")
+
+ ;; - remove the first and last dashed lines
+
+ (setq box-style 'plain)
+ (goto-char (point-min))
+ (if (looking-at "^[ \t]*-*[.\+\\]?[ \t]*\n")
+ (progn
+ (setq box-style 'single)
+ (replace-match ""))
+ (if (looking-at "^[ \t]*=*[.\+\\]?[ \t]*\n")
+ (progn
+ (setq box-style 'double)
+ (replace-match ""))))
+ (goto-char (point-max))
+ (previous-line 1)
+ (beginning-of-line)
+ (if (looking-at "^[ \t]*[`\+\\]?*[-=]+[ \t]*\n")
+ (progn
+ (if (eq box-style 'plain)
+ (setq box-style 'taarna))
+ (replace-match "")))
+
+ ;; - remove all spurious whitespace
+
+ (goto-char (point-min))
+ (replace-regexp "[ \t]+$" "")
+ (goto-char (point-min))
+ (if (looking-at "\n+")
+ (replace-match ""))
+ (goto-char (point-max))
+ (skip-chars-backward "\n")
+ (if (looking-at "\n\n+")
+ (replace-match "\n"))
+ (goto-char (point-min))
+ (replace-regexp "\n\n\n+" "\n\n")
+
+ ;; - move the text left is adequate
+
+ (setq actual-margin (buffer-left-margin))
+ (if (not (= previous-margin actual-margin))
+ (indent-rigidly (point-min) (point-max)
+ (- previous-margin actual-margin))))
+
+ ;; Third, select the new box style from the old box style and
+ ;; the argument, choose the margins for this style and refill
+ ;; each paragraph.
+
+ ;; - modify box-style only if flag is defined
+
+ (if flag
+ (setq box-style
+ (cond ((eq flag 0) 'plain)
+ ((eq flag 1) 'single)
+ ((eq flag 2) 'double)
+ ((eq flag 3) 'taarna)
+ ((eq flag '-) (setq c-box-default-style 'plain) 'plain)
+ ((eq flag -1) (setq c-box-default-style 'single) 'single)
+ ((eq flag -2) (setq c-box-default-style 'double) 'double)
+ ((eq flag -3) (setq c-box-default-style 'taarna) 'taarna)
+ (t c-box-default-style))))
+
+ ;; - compute the left margin
+
+ (setq left-margin (buffer-left-margin))
+
+ ;; - temporarily set the fill prefix and column, then refill
+
+ (untabify (point-min) (point-max))
+
+ (if refill
+ (let ((fill-prefix (make-string left-margin ? ))
+ (fill-column (- fill-column
+ (if (memq box-style '(single double)) 4 6))))
+ (fill-region (point-min) (point-max))))
+
+ ;; - compute the right margin after refill
+
+ (setq right-margin (buffer-right-margin))
+
+ ;; Fourth, put the narrowed buffer back into a comment box,
+ ;; according to the value of box-style. Values may be:
+ ;; plain: insert between a single pair of comment delimiters
+ ;; single: complete box, overline and underline with dashes
+ ;; double: complete box, overline and underline with equal signs
+ ;; taarna: comment delimiters on each line, underline with dashes
+
+ ;; - move the right margin to account for left inserts
+
+ (setq right-margin (+ right-margin
+ (if (memq box-style '(single double))
+ 2
+ 3)))
+
+ ;; - construct the box comment, from top to bottom
+
+ (goto-char (point-min))
+ (cond ((eq box-style 'plain)
+
+ ;; - construct a plain style comment
+
+ (skip-chars-forward " " (+ (point) left-margin))
+ (insert (make-string (- left-margin (current-column)) ? )
+ "/* ")
+ (end-of-line)
+ (forward-char 1)
+ (while (not (eobp))
+ (skip-chars-forward " " (+ (point) left-margin))
+ (insert (make-string (- left-margin (current-column)) ? )
+ " ")
+ (end-of-line)
+ (forward-char 1))
+ (backward-char 1)
+ (insert " */"))
+ ((eq box-style 'single)
+
+ ;; - construct a single line style comment
+
+ (indent-to left-margin)
+ (insert "/*")
+ (insert (make-string (- right-margin (current-column)) ?-)
+ "-.\n")
+ (while (not (eobp))
+ (skip-chars-forward " " (+ (point) left-margin))
+ (insert (make-string (- left-margin (current-column)) ? )
+ "| ")
+ (end-of-line)
+ (indent-to right-margin)
+ (insert " |")
+ (forward-char 1))
+ (indent-to left-margin)
+ (insert "`")
+ (insert (make-string (- right-margin (current-column)) ?-)
+ "*/\n"))
+ ((eq box-style 'double)
+
+ ;; - construct a double line style comment
+
+ (indent-to left-margin)
+ (insert "/*")
+ (insert (make-string (- right-margin (current-column)) ?=)
+ "=\\\n")
+ (while (not (eobp))
+ (skip-chars-forward " " (+ (point) left-margin))
+ (insert (make-string (- left-margin (current-column)) ? )
+ "| ")
+ (end-of-line)
+ (indent-to right-margin)
+ (insert " |")
+ (forward-char 1))
+ (indent-to left-margin)
+ (insert "\\")
+ (insert (make-string (- right-margin (current-column)) ?=)
+ "*/\n"))
+ ((eq box-style 'taarna)
+
+ ;; - construct a Taarna style comment
+
+ (while (not (eobp))
+ (skip-chars-forward " " (+ (point) left-margin))
+ (insert (make-string (- left-margin (current-column)) ? )
+ "/* ")
+ (end-of-line)
+ (indent-to right-margin)
+ (insert " */")
+ (forward-char 1))
+ (indent-to left-margin)
+ (insert "/* ")
+ (insert (make-string (- right-margin (current-column)) ?-)
+ " */\n"))
+ (t (error "unknown box style")))
+
+ ;; Fifth, retabify, restore the point position, then cleanup the
+ ;; undo list of any boundary since we started.
+
+ ;; - retabify before left margin only (adapted from tabify.el)
+
+ (goto-char (point-min))
+ (while (re-search-forward "^[ \t][ \t][ \t]*" nil t)
+ (let ((column (current-column))
+ (indent-tabs-mode t))
+ (delete-region (match-beginning 0) (point))
+ (indent-to column)))
+
+ ;; - restore the point position
+
+ (goto-char (marker-position marked-point))
+
+ ;; - remove all intermediate boundaries from the undo list
+
+ (if (not (eq buffer-undo-list undo-list))
+ (let ((cursor buffer-undo-list))
+ (while (not (eq (cdr cursor) undo-list))
+ (if (car (cdr cursor))
+ (setq cursor (cdr cursor))
+ (rplacd cursor (cdr (cdr cursor))))))))))
+
+;;; Rebox a C comment without refilling it.
+
+(defun rebox-c-comment (flag)
+ (interactive "P")
+ (rebox-c-comment-engine flag nil))
+
+;;; Rebox a C comment after refilling.
+
+(defun reindent-c-comment (flag)
+ (interactive "P")
+ (rebox-c-comment-engine flag t))
diff --git a/checks/01.define b/checks/01.define
new file mode 100644
index 00000000..7a044c01
--- /dev/null
+++ b/checks/01.define
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:939: Origin of test
+define(`foo', `Hello world.')
+dnl @result{}
+foo
+dnl @result{}Hello world.
diff --git a/checks/02.arguments b/checks/02.arguments
new file mode 100644
index 00000000..0d459123
--- /dev/null
+++ b/checks/02.arguments
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:963: Origin of test
+define(`exch', `$2, $1')
+dnl @result{}
+exch(arg1, arg2)
+dnl @result{}arg2, arg1
diff --git a/checks/02.define b/checks/02.define
new file mode 100644
index 00000000..de8bc66d
--- /dev/null
+++ b/checks/02.define
@@ -0,0 +1,13 @@
+dnl ../doc/m4.texinfo:905: Origin of test
+define(`array', `defn(format(``array[%d]'', `$1'))')
+dnl @result{}
+define(`array_set', `define(format(``array[%d]'', `$1'), `$2')')
+dnl @result{}
+array_set(4, `array element no. 4')
+dnl @result{}
+array_set(17, `array element no. 17')
+dnl @result{}
+array(4)
+dnl @result{}array element no. 4
+array(eval(10+7))
+dnl @result{}array element no. 17
diff --git a/checks/03.arguments b/checks/03.arguments
new file mode 100644
index 00000000..9117964b
--- /dev/null
+++ b/checks/03.arguments
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:973: Origin of test
+define(`exch', `$2, $1')
+dnl @result{}
+define(exch(``expansion text'', ``macro''))
+dnl @result{}
+macro
+dnl @result{}expansion text
diff --git a/checks/04.arguments b/checks/04.arguments
new file mode 100644
index 00000000..8d325ac4
--- /dev/null
+++ b/checks/04.arguments
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:993: Origin of test
+define(`test', ``Macro name: $0'')
+dnl @result{}
+test
+dnl @result{}Macro name: test
diff --git a/checks/05.arguments b/checks/05.arguments
new file mode 100644
index 00000000..aaed75e0
--- /dev/null
+++ b/checks/05.arguments
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:1003: Origin of test
+define(`foo', `This is macro `foo'.')
+dnl @result{}
+foo
+dnl @result{}This is macro foo.
diff --git a/checks/06.arguments b/checks/06.arguments
new file mode 100644
index 00000000..b866e6c9
--- /dev/null
+++ b/checks/06.arguments
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:974: Origin of test
+define(`foo', `This is macro `foo'.')
+dnl @result{}
+foo
+dnl @result{}This is macro foo.
diff --git a/checks/06.pseudo_argu b/checks/06.pseudo_argu
new file mode 100644
index 00000000..8c1f9dfd
--- /dev/null
+++ b/checks/06.pseudo_argu
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:1027: Origin of test
+define(`nargs', `$#')
+dnl @result{}
+nargs
+dnl @result{}0
+nargs()
+dnl @result{}1
+nargs(arg1, arg2, arg3)
+dnl @result{}3
diff --git a/checks/07.pseudo_argu b/checks/07.pseudo_argu
new file mode 100644
index 00000000..0517066c
--- /dev/null
+++ b/checks/07.pseudo_argu
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:1041: Origin of test
+define(`echo', `$*')
+dnl @result{}
+echo(arg1, arg2, arg3 , arg4)
+dnl @result{}arg1,arg2,arg3 ,arg4
diff --git a/checks/08.pseudo_argu b/checks/08.pseudo_argu
new file mode 100644
index 00000000..8787b016
--- /dev/null
+++ b/checks/08.pseudo_argu
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:1052: Origin of test
+define(`echo', `$@')
+dnl @result{}
+echo(arg1, arg2, arg3 , arg4)
+dnl @result{}arg1,arg2,arg3 ,arg4
diff --git a/checks/09.pseudo_argu b/checks/09.pseudo_argu
new file mode 100644
index 00000000..440d7e7f
--- /dev/null
+++ b/checks/09.pseudo_argu
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:1062: Origin of test
+define(`echo1', `$*')
+dnl @result{}
+define(`echo2', `$@')
+dnl @result{}
+define(`foo', `This is macro `foo'.')
+dnl @result{}
+echo1(foo)
+dnl @result{}This is macro This is macro foo..
+echo2(foo)
+dnl @result{}This is macro foo.
diff --git a/checks/10.pseudo_argu b/checks/10.pseudo_argu
new file mode 100644
index 00000000..1842e3ed
--- /dev/null
+++ b/checks/10.pseudo_argu
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:1082: Origin of test
+define(`foo', `$$$ hello $$$')
+dnl @result{}
+foo
+dnl @result{}$$$ hello $$$
diff --git a/checks/11.pseudo_argu b/checks/11.pseudo_argu
new file mode 100644
index 00000000..dd46c979
--- /dev/null
+++ b/checks/11.pseudo_argu
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:1053: Origin of test
+define(`foo', `$$$ hello $$$')
+dnl @result{}
+foo
+dnl @result{}$$$ hello $$$
diff --git a/checks/11.undefine b/checks/11.undefine
new file mode 100644
index 00000000..9709263d
--- /dev/null
+++ b/checks/11.undefine
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:1113: Origin of test
+foo
+dnl @result{}foo
+define(`foo', `expansion text')
+dnl @result{}
+foo
+dnl @result{}expansion text
+undefine(`foo')
+dnl @result{}
+foo
+dnl @result{}foo
diff --git a/checks/12.defn b/checks/12.defn
new file mode 100644
index 00000000..9ebb42da
--- /dev/null
+++ b/checks/12.defn
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1158: Origin of test
+define(`zap', defn(`undefine'))
+dnl @result{}
+zap(`undefine')
+dnl @result{}
+undefine(`zap')
+dnl @result{}undefine(zap)
diff --git a/checks/12.undefine b/checks/12.undefine
new file mode 100644
index 00000000..1f61131d
--- /dev/null
+++ b/checks/12.undefine
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:1084: Origin of test
+foo
+dnl @result{}foo
+define(`foo', `expansion text')
+dnl @result{}
+foo
+dnl @result{}expansion text
+undefine(`foo')
+dnl @result{}
+foo
+dnl @result{}foo
diff --git a/checks/13.defn b/checks/13.defn
new file mode 100644
index 00000000..1deb3f44
--- /dev/null
+++ b/checks/13.defn
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1128: Origin of test
+define(`zap', defn(`undefine'))
+dnl @result{}
+zap(`undefine')
+dnl @result{}
+undefine(`zap')
+dnl @result{}undefine(zap)
diff --git a/checks/13.pushdef b/checks/13.pushdef
new file mode 100644
index 00000000..bdf078ba
--- /dev/null
+++ b/checks/13.pushdef
@@ -0,0 +1,17 @@
+dnl ../doc/m4.texinfo:1204: Origin of test
+define(`foo', `Expansion one.')
+dnl @result{}
+foo
+dnl @result{}Expansion one.
+pushdef(`foo', `Expansion two.')
+dnl @result{}
+foo
+dnl @result{}Expansion two.
+popdef(`foo')
+dnl @result{}
+foo
+dnl @result{}Expansion one.
+popdef(`foo')
+dnl @result{}
+foo
+dnl @result{}foo
diff --git a/checks/14.defn b/checks/14.defn
new file mode 100644
index 00000000..11ece953
--- /dev/null
+++ b/checks/14.defn
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:1148: Origin of test
+define(`string', `The macro dnl is very useful
+')
+dnl @result{}
+string
+dnl @result{}The macro
+defn(`string')
+dnl @result{}The macro dnl is very useful
+dnl @result{}
diff --git a/checks/14.pushdef b/checks/14.pushdef
new file mode 100644
index 00000000..dda7d3fe
--- /dev/null
+++ b/checks/14.pushdef
@@ -0,0 +1,17 @@
+dnl ../doc/m4.texinfo:1228: Origin of test
+define(`foo', `Expansion one.')
+dnl @result{}
+foo
+dnl @result{}Expansion one.
+pushdef(`foo', `Expansion two.')
+dnl @result{}
+foo
+dnl @result{}Expansion two.
+define(`foo', `Second expansion two.')
+dnl @result{}
+foo
+dnl @result{}Second expansion two.
+undefine(`foo')
+dnl @result{}
+foo
+dnl @result{}foo
diff --git a/checks/15.indir b/checks/15.indir
new file mode 100644
index 00000000..881b4deb
--- /dev/null
+++ b/checks/15.indir
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1272: Origin of test
+define(`$$internal$macro', `Internal macro (name `$0')')
+dnl @result{}
+$$internal$macro
+dnl @result{}$$internal$macro
+indir(`$$internal$macro')
+dnl @result{}Internal macro (name $$internal$macro)
diff --git a/checks/15.pushdef b/checks/15.pushdef
new file mode 100644
index 00000000..df2859af
--- /dev/null
+++ b/checks/15.pushdef
@@ -0,0 +1,17 @@
+dnl ../doc/m4.texinfo:1192: Origin of test
+define(`foo', `Expansion one.')
+dnl @result{}
+foo
+dnl @result{}Expansion one.
+pushdef(`foo', `Expansion two.')
+dnl @result{}
+foo
+dnl @result{}Expansion two.
+popdef(`foo')
+dnl @result{}
+foo
+dnl @result{}Expansion one.
+popdef(`foo')
+dnl @result{}
+foo
+dnl @result{}foo
diff --git a/checks/16.ifdef b/checks/16.ifdef
new file mode 100644
index 00000000..c4dec7b5
--- /dev/null
+++ b/checks/16.ifdef
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1343: Origin of test
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+dnl @result{}foo is not defined
+define(`foo', `')
+dnl @result{}
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+dnl @result{}foo is defined
diff --git a/checks/16.pushdef b/checks/16.pushdef
new file mode 100644
index 00000000..48c0cec6
--- /dev/null
+++ b/checks/16.pushdef
@@ -0,0 +1,17 @@
+dnl ../doc/m4.texinfo:1216: Origin of test
+define(`foo', `Expansion one.')
+dnl @result{}
+foo
+dnl @result{}Expansion one.
+pushdef(`foo', `Expansion two.')
+dnl @result{}
+foo
+dnl @result{}Expansion two.
+define(`foo', `Second expansion two.')
+dnl @result{}
+foo
+dnl @result{}Second expansion two.
+undefine(`foo')
+dnl @result{}
+foo
+dnl @result{}foo
diff --git a/checks/17.ifelse b/checks/17.ifelse
new file mode 100644
index 00000000..836a98f0
--- /dev/null
+++ b/checks/17.ifelse
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:1381: Origin of test
+ifelse(foo, bar, `true')
+dnl @result{}
+ifelse(foo, foo, `true')
+dnl @result{}true
+ifelse(foo, bar, `true', `false')
+dnl @result{}false
+ifelse(foo, foo, `true', `false')
+dnl @result{}true
diff --git a/checks/17.indir b/checks/17.indir
new file mode 100644
index 00000000..d573a386
--- /dev/null
+++ b/checks/17.indir
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1267: Origin of test
+define(`$$internal$macro', `Internal macro (name `$0')')
+dnl @result{}
+$$internal$macro
+dnl @result{}$$internal$macro
+indir(`$$internal$macro')
+dnl @result{}Internal macro (name $$internal$macro)
diff --git a/checks/18.ifdef b/checks/18.ifdef
new file mode 100644
index 00000000..40c355ca
--- /dev/null
+++ b/checks/18.ifdef
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1338: Origin of test
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+dnl @result{}foo is not defined
+define(`foo', `')
+dnl @result{}
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+dnl @result{}foo is defined
diff --git a/checks/18.ifelse b/checks/18.ifelse
new file mode 100644
index 00000000..ddfb7fbb
--- /dev/null
+++ b/checks/18.ifelse
@@ -0,0 +1,3 @@
+dnl ../doc/m4.texinfo:1400: Origin of test
+ifelse(foo, bar, `third', gnu, gnats, `sixth', `seventh')
+dnl @result{}seventh
diff --git a/checks/19.ifelse b/checks/19.ifelse
new file mode 100644
index 00000000..0886f6db
--- /dev/null
+++ b/checks/19.ifelse
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:1376: Origin of test
+ifelse(`foo', `bar', `true')
+dnl @result{}
+ifelse(`foo', `foo', `true')
+dnl @result{}true
+ifelse(`foo', `bar', `true', `false')
+dnl @result{}false
+ifelse(`foo', `foo', `true', `false')
+dnl @result{}true
diff --git a/checks/19.loops b/checks/19.loops
new file mode 100644
index 00000000..8ac68eb9
--- /dev/null
+++ b/checks/19.loops
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:1437: Origin of test
+shift(bar)
+dnl @result{}
+shift(foo, bar, baz)
+dnl @result{}bar,baz
diff --git a/checks/20.ifelse b/checks/20.ifelse
new file mode 100644
index 00000000..aff53225
--- /dev/null
+++ b/checks/20.ifelse
@@ -0,0 +1,3 @@
+dnl ../doc/m4.texinfo:1395: Origin of test
+ifelse(foo, bar, `third', gnu, gnats, `sixth', `seventh')
+dnl @result{}seventh
diff --git a/checks/20.loops b/checks/20.loops
new file mode 100644
index 00000000..55dfc86c
--- /dev/null
+++ b/checks/20.loops
@@ -0,0 +1,10 @@
+dnl ../doc/m4.texinfo:1447: Origin of test
+define(`reverse', `ifelse($#, 0, , $#, 1, ``$1'',
+ `reverse(shift($@)), `$1'')')
+dnl @result{}
+reverse
+dnl @result{}
+reverse(foo)
+dnl @result{}foo
+reverse(foo, bar, gnats, and gnus)
+dnl @result{}and gnus, gnats, bar, foo
diff --git a/checks/21.dumpdef b/checks/21.dumpdef
new file mode 100644
index 00000000..689bb786
--- /dev/null
+++ b/checks/21.dumpdef
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:1561: Origin of test
+define(`foo', `Hello world.')
+dnl @result{}
+dumpdef(`foo')
+dnl @error{}foo: `Hello world.'
+dnl @result{}
+dumpdef(`define')
+dnl @error{}define: <define>
+dnl @result{}
diff --git a/checks/21.loops b/checks/21.loops
new file mode 100644
index 00000000..2b0290b1
--- /dev/null
+++ b/checks/21.loops
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1432: Origin of test
+shift
+dnl @result{}
+shift(bar)
+dnl @result{}
+shift(foo, bar, baz)
+dnl @result{}bar,baz
diff --git a/checks/22.loops b/checks/22.loops
new file mode 100644
index 00000000..1ecdc076
--- /dev/null
+++ b/checks/22.loops
@@ -0,0 +1,10 @@
+dnl ../doc/m4.texinfo:1444: Origin of test
+define(`reverse', `ifelse($#, 0, , $#, 1, ``$1'',
+ `reverse(shift($@)), `$1'')')
+dnl @result{}
+reverse
+dnl @result{}
+reverse(foo)
+dnl @result{}foo
+reverse(foo, bar, gnats, and gnus)
+dnl @result{}and gnus, gnats, bar, foo
diff --git a/checks/22.trace b/checks/22.trace
new file mode 100644
index 00000000..ae4e639c
--- /dev/null
+++ b/checks/22.trace
@@ -0,0 +1,13 @@
+dnl ../doc/m4.texinfo:1606: Origin of test
+define(`foo', `Hello World.')
+dnl @result{}
+define(`echo', `$@')
+dnl @result{}
+traceon(`foo', `echo')
+dnl @result{}
+foo
+dnl @error{}m4trace: -1- foo -> `Hello World.'
+dnl @result{}Hello World.
+echo(gnus, and gnats)
+dnl @error{}m4trace: -1- echo(`gnus', `and gnats') -> ``gnus',`and gnats''
+dnl @result{}gnus,and gnats
diff --git a/checks/23.dnl b/checks/23.dnl
new file mode 100644
index 00000000..763d9843
--- /dev/null
+++ b/checks/23.dnl
@@ -0,0 +1,4 @@
+dnl ../doc/m4.texinfo:1757: Origin of test
+define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
+foo
+dnl @result{}Macro foo.
diff --git a/checks/23.dumpdef b/checks/23.dumpdef
new file mode 100644
index 00000000..c65f6934
--- /dev/null
+++ b/checks/23.dumpdef
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:1558: Origin of test
+define(`foo', `Hello world.')
+dnl @result{}
+dumpdef(`foo')
+dnl @error{}foo: `Hello world.'
+dnl @result{}
+dumpdef(`define')
+dnl @error{}define: <define>
+dnl @result{}
diff --git a/checks/24.changequote b/checks/24.changequote
new file mode 100644
index 00000000..c74dafdf
--- /dev/null
+++ b/checks/24.changequote
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1795: Origin of test
+changequote([, ])
+dnl @result{}
+define([foo], [Macro [foo].])
+dnl @result{}
+foo
+dnl @result{}Macro foo.
diff --git a/checks/24.trace b/checks/24.trace
new file mode 100644
index 00000000..491eef27
--- /dev/null
+++ b/checks/24.trace
@@ -0,0 +1,13 @@
+dnl ../doc/m4.texinfo:1603: Origin of test
+define(`foo', `Hello World.')
+dnl @result{}
+define(`echo', `$@')
+dnl @result{}
+traceon(`foo', `echo')
+dnl @result{}
+foo
+dnl @error{}m4trace: -1- foo -> `Hello World.'
+dnl @result{}Hello World.
+echo(gnus, and gnats)
+dnl @error{}m4trace: -1- echo(`gnus', `and gnats') -> ``gnus',`and gnats''
+dnl @result{}gnus,and gnats
diff --git a/checks/25.changequote b/checks/25.changequote
new file mode 100644
index 00000000..b3976016
--- /dev/null
+++ b/checks/25.changequote
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1807: Origin of test
+changequote([[, ]])
+dnl @result{}
+define([[foo]], [[Macro [[[foo]]].]])
+dnl @result{}
+foo
+dnl @result{}Macro [foo].
diff --git a/checks/25.dnl b/checks/25.dnl
new file mode 100644
index 00000000..ecdb9b24
--- /dev/null
+++ b/checks/25.dnl
@@ -0,0 +1,4 @@
+dnl ../doc/m4.texinfo:1755: Origin of test
+define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
+foo
+dnl @result{}Macro foo.
diff --git a/checks/26.changequote b/checks/26.changequote
new file mode 100644
index 00000000..2187982b
--- /dev/null
+++ b/checks/26.changequote
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:1819: Origin of test
+define(`foo', `Macro `FOO'.')
+dnl @result{}
+changequote(, )
+dnl @result{}
+foo
+dnl @result{}Macro `FOO'.
+`foo'
+dnl @result{}`Macro `FOO'.'
diff --git a/checks/27.changecom b/checks/27.changecom
new file mode 100644
index 00000000..108cbb59
--- /dev/null
+++ b/checks/27.changecom
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:1859: Origin of test
+define(`comment', `COMMENT')
+dnl @result{}
+# A normal comment
+dnl @result{}# A normal comment
+changecom(`/*', `*/')
+dnl @result{}
+# Not a comment anymore
+dnl @result{}# Not a COMMENT anymore
+But: /* this is a comment now */ while this is not a comment
+dnl @result{}But: /* this is a comment now */ while this is not a COMMENT
diff --git a/checks/27.changequote b/checks/27.changequote
new file mode 100644
index 00000000..bd71cb96
--- /dev/null
+++ b/checks/27.changequote
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1805: Origin of test
+changequote([[, ]])
+dnl @result{}
+define([[foo]], [[Macro [[[foo]]].]])
+dnl @result{}
+foo
+dnl @result{}Macro [foo].
diff --git a/checks/28.changecom b/checks/28.changecom
new file mode 100644
index 00000000..35604dee
--- /dev/null
+++ b/checks/28.changecom
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1880: Origin of test
+define(`comment', `COMMENT')
+dnl @result{}
+changecom
+dnl @result{}
+# Not a comment anymore
+dnl @result{}# Not a COMMENT anymore
diff --git a/checks/28.changequote b/checks/28.changequote
new file mode 100644
index 00000000..ed067f50
--- /dev/null
+++ b/checks/28.changequote
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:1817: Origin of test
+define(`foo', `Macro `FOO'.')
+dnl @result{}
+changequote(, )
+dnl @result{}
+foo
+dnl @result{}Macro `FOO'.
+`foo'
+dnl @result{}`Macro `FOO'.'
diff --git a/checks/29.changecom b/checks/29.changecom
new file mode 100644
index 00000000..7a1dfa60
--- /dev/null
+++ b/checks/29.changecom
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:1857: Origin of test
+define(`comment', `COMMENT')
+dnl @result{}
+# A normal comment
+dnl @result{}# A normal comment
+changecom(`/*', `*/')
+dnl @result{}
+# Not a comment anymore
+dnl @result{}# Not a COMMENT anymore
+But: /* this is a comment now */ while this is not a comment
+dnl @result{}But: /* this is a comment now */ while this is not a COMMENT
diff --git a/checks/29.m4wrap b/checks/29.m4wrap
new file mode 100644
index 00000000..b303c56c
--- /dev/null
+++ b/checks/29.m4wrap
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2019: Origin of test
+define(`cleanup', `This is the `cleanup' actions.
+')
+dnl @result{}
+m4wrap(`cleanup')
+dnl @result{}
+This is the first and last normal input line.
+dnl @result{}This is the first and last normal input line.
+dnl @result{}This is the cleanup actions.
diff --git a/checks/30.changecom b/checks/30.changecom
new file mode 100644
index 00000000..fce2579c
--- /dev/null
+++ b/checks/30.changecom
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:1878: Origin of test
+define(`comment', `COMMENT')
+dnl @result{}
+changecom
+dnl @result{}
+# Not a comment anymore
+dnl @result{}# Not a COMMENT anymore
diff --git a/checks/30.include b/checks/30.include
new file mode 100644
index 00000000..85968c80
--- /dev/null
+++ b/checks/30.include
@@ -0,0 +1,6 @@
+dnl ../doc/m4.texinfo:2078: Origin of test
+include(`no-such-file')
+dnl @result{}
+dnl @error{}30.include:2: m4: Cannot open no-such-file: No such file or directory
+sinclude(`no-such-file')
+dnl @result{}
diff --git a/checks/31.changesynta b/checks/31.changesynta
new file mode 100644
index 00000000..02f0ac23
--- /dev/null
+++ b/checks/31.changesynta
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:2023: Origin of test
+define(`test.1', `TEST ONE')
+dnl @result{}
+__file__
+dnl @result{}31.changesynta
+changesyntax(`O_', `W.')
+dnl @result{}
+__file__
+dnl @result{}__file__
+test.1
+dnl @result{}TEST ONE
diff --git a/checks/31.include b/checks/31.include
new file mode 100644
index 00000000..1d3e01bc
--- /dev/null
+++ b/checks/31.include
@@ -0,0 +1,8 @@
+dnl ../doc/m4.texinfo:2098: Origin of test
+define(`foo', `FOO')
+dnl @result{}
+include(`incl.m4')
+dnl @result{}Include file start
+dnl @result{}FOO
+dnl @result{}Include file end
+dnl @result{}
diff --git a/checks/32.changesynta b/checks/32.changesynta
new file mode 100644
index 00000000..8bd2f388
--- /dev/null
+++ b/checks/32.changesynta
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:2039: Origin of test
+define(`test', `$#')
+dnl @result{}
+test(a, b, c)
+dnl @result{}3
+changesyntax(`(<', `,|', `)>', `O(,)')
+dnl @result{}
+test(a, b, c)
+dnl @result{}0(a, b, c)
+test<a|b|c>
+dnl @result{}3
diff --git a/checks/32.include b/checks/32.include
new file mode 100644
index 00000000..ba3208f5
--- /dev/null
+++ b/checks/32.include
@@ -0,0 +1,8 @@
+dnl ../doc/m4.texinfo:2113: Origin of test
+define(`bar', include(`incl.m4'))
+dnl @result{}
+This is `bar': >>>bar<<<
+dnl @result{}This is bar: >>>Include file start
+dnl @result{}foo
+dnl @result{}Include file end
+dnl @result{}<<<
diff --git a/checks/33.changesynta b/checks/33.changesynta
new file mode 100644
index 00000000..e4f76f71
--- /dev/null
+++ b/checks/33.changesynta
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2056: Origin of test
+define(`test', `$1$2$3')
+dnl @result{}
+test(a, b, c)
+dnl @result{}abc
+changesyntax(`O ')
+dnl @result{}
+test(a, b, c)
+dnl @result{}a b c
diff --git a/checks/33.divert b/checks/33.divert
new file mode 100644
index 00000000..1f90fa5f
--- /dev/null
+++ b/checks/33.divert
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2201: Origin of test
+divert(1)
+This text is diverted.
+divert
+dnl @result{}
+This text is not diverted.
+dnl @result{}This text is not diverted.
+dnl @result{}
+dnl @result{}This text is diverted.
diff --git a/checks/34.changesynta b/checks/34.changesynta
new file mode 100644
index 00000000..7b430d69
--- /dev/null
+++ b/checks/34.changesynta
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2075: Origin of test
+define(`@', `TEST')
+dnl @result{}
+@
+dnl @result{}@
+changesyntax(`A@')
+dnl @result{}
+@
+dnl @result{}TEST
diff --git a/checks/34.divert b/checks/34.divert
new file mode 100644
index 00000000..6f0a8a78
--- /dev/null
+++ b/checks/34.divert
@@ -0,0 +1,6 @@
+dnl ../doc/m4.texinfo:2221: Origin of test
+divert(-1)
+define(`foo', `Macro `foo'.')
+define(`bar', `Macro `bar'.')
+divert
+dnl @result{}
diff --git a/checks/35.changesynta b/checks/35.changesynta
new file mode 100644
index 00000000..d2ab2d3f
--- /dev/null
+++ b/checks/35.changesynta
@@ -0,0 +1,15 @@
+dnl ../doc/m4.texinfo:2099: Origin of test
+define(`test', `TEST')
+dnl @result{}
+changesyntax(`L<', `R>')
+dnl @result{}
+<test>
+dnl @result{}test
+`test>
+dnl @result{}test
+changequote(<[>, `]')
+dnl @result{}
+<test>
+dnl @result{}<TEST>
+[test]
+dnl @result{}test
diff --git a/checks/35.undivert b/checks/35.undivert
new file mode 100644
index 00000000..a67dce3c
--- /dev/null
+++ b/checks/35.undivert
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:2252: Origin of test
+divert(1)
+This text is diverted.
+divert
+dnl @result{}
+This text is not diverted.
+dnl @result{}This text is not diverted.
+undivert(1)
+dnl @result{}
+dnl @result{}This text is diverted.
+dnl @result{}
diff --git a/checks/36.changesynta b/checks/36.changesynta
new file mode 100644
index 00000000..db3f46f2
--- /dev/null
+++ b/checks/36.changesynta
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2121: Origin of test
+changesyntax(`({<', `)}>', `,;:', `O(,)')
+dnl @result{}
+eval{2**4-1; 2 : 8>
+dnl @result{}00001111
diff --git a/checks/36.undivert b/checks/36.undivert
new file mode 100644
index 00000000..59e2741d
--- /dev/null
+++ b/checks/36.undivert
@@ -0,0 +1,13 @@
+dnl ../doc/m4.texinfo:2276: Origin of test
+divert(1)
+This text is diverted first.
+divert(0)undivert(1)dnl
+dnl @result{}
+dnl @result{}This text is diverted first.
+undivert(1)
+dnl @result{}
+divert(1)
+This text is also diverted but not appended.
+divert(0)undivert(1)dnl
+dnl @result{}
+dnl @result{}This text is also diverted but not appended.
diff --git a/checks/37.changesynta b/checks/37.changesynta
new file mode 100644
index 00000000..378d6d51
--- /dev/null
+++ b/checks/37.changesynta
@@ -0,0 +1,13 @@
+dnl ../doc/m4.texinfo:2132: Origin of test
+define(`test', `==$1==')
+dnl @result{}
+changequote(`<<', `>>')
+dnl @result{}
+changesyntax(<<L[>>, <<R]>>)
+dnl @result{}
+test(<<testing]>>)
+dnl @result{}==testing]==
+test([testing>>])
+dnl @result{}==testing>>==
+test([<<testing>>])
+dnl @result{}==<<testing>>==
diff --git a/checks/37.undivert b/checks/37.undivert
new file mode 100644
index 00000000..98a11953
--- /dev/null
+++ b/checks/37.undivert
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2302: Origin of test
+define(`bar', `BAR')
+dnl @result{}
+undivert(`foo')
+dnl @result{}bar
+dnl @result{}
+include(`foo')
+dnl @result{}BAR
+dnl @result{}
diff --git a/checks/38.divnum b/checks/38.divnum
new file mode 100644
index 00000000..e56346ee
--- /dev/null
+++ b/checks/38.divnum
@@ -0,0 +1,13 @@
+dnl ../doc/m4.texinfo:2328: Origin of test
+Initial divnum
+dnl @result{}Initial 0
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert
+dnl @result{}
+dnl @result{}
+dnl @result{}Diversion one: 1
+dnl @result{}
+dnl @result{}Diversion two: 2
diff --git a/checks/38.m4wrap b/checks/38.m4wrap
new file mode 100644
index 00000000..95fb12dd
--- /dev/null
+++ b/checks/38.m4wrap
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2293: Origin of test
+define(`cleanup', `This is the `cleanup' actions.
+')
+dnl @result{}
+m4wrap(`cleanup')
+dnl @result{}
+This is the first and last normal input line.
+dnl @result{}This is the first and last normal input line.
+dnl @result{}This is the cleanup actions.
diff --git a/checks/39.cleardiv b/checks/39.cleardiv
new file mode 100644
index 00000000..ab3176b7
--- /dev/null
+++ b/checks/39.cleardiv
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:2359: Origin of test
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert(-1)
+undivert
diff --git a/checks/39.include b/checks/39.include
new file mode 100644
index 00000000..68cba854
--- /dev/null
+++ b/checks/39.include
@@ -0,0 +1,6 @@
+dnl ../doc/m4.texinfo:2352: Origin of test
+include(`no-such-file')
+dnl @result{}
+dnl @error{}39.include:2: m4: Cannot open no-such-file: No such file or directory
+sinclude(`no-such-file')
+dnl @result{}
diff --git a/checks/40.cleardiv b/checks/40.cleardiv
new file mode 100644
index 00000000..9d095038
--- /dev/null
+++ b/checks/40.cleardiv
@@ -0,0 +1,4 @@
+dnl ../doc/m4.texinfo:2374: Origin of test
+define(`cleardivert',
+`pushdef(`_num', divnum)divert(-1)undivert($@)divert(_num)popdef(`_num')')
+dnl @result{}
diff --git a/checks/40.include b/checks/40.include
new file mode 100644
index 00000000..1afae8e2
--- /dev/null
+++ b/checks/40.include
@@ -0,0 +1,8 @@
+dnl ../doc/m4.texinfo:2372: Origin of test
+define(`foo', `FOO')
+dnl @result{}
+include(`incl.m4')
+dnl @result{}Include file start
+dnl @result{}FOO
+dnl @result{}Include file end
+dnl @result{}
diff --git a/checks/41.include b/checks/41.include
new file mode 100644
index 00000000..e5965be9
--- /dev/null
+++ b/checks/41.include
@@ -0,0 +1,8 @@
+dnl ../doc/m4.texinfo:2387: Origin of test
+define(`bar', include(`incl.m4'))
+dnl @result{}
+This is `bar': >>>bar<<<
+dnl @result{}This is bar: >>>Include file start
+dnl @result{}foo
+dnl @result{}Include file end
+dnl @result{}<<<
diff --git a/checks/41.len b/checks/41.len
new file mode 100644
index 00000000..1c64b8e4
--- /dev/null
+++ b/checks/41.len
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2416: Origin of test
+len()
+dnl @result{}0
+len(`abcdef')
+dnl @result{}6
diff --git a/checks/42.divert b/checks/42.divert
new file mode 100644
index 00000000..9c86c5de
--- /dev/null
+++ b/checks/42.divert
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2478: Origin of test
+divert(1)
+This text is diverted.
+divert
+dnl @result{}
+This text is not diverted.
+dnl @result{}This text is not diverted.
+dnl @result{}
+dnl @result{}This text is diverted.
diff --git a/checks/42.index b/checks/42.index
new file mode 100644
index 00000000..bac694f7
--- /dev/null
+++ b/checks/42.index
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2442: Origin of test
+index(`gnus, gnats, and armadillos', `nat')
+dnl @result{}7
+index(`gnus, gnats, and armadillos', `dag')
+dnl @result{}-1
diff --git a/checks/43.divert b/checks/43.divert
new file mode 100644
index 00000000..252fc982
--- /dev/null
+++ b/checks/43.divert
@@ -0,0 +1,6 @@
+dnl ../doc/m4.texinfo:2498: Origin of test
+divert(-1)
+define(`foo', `Macro `foo'.')
+define(`bar', `Macro `bar'.')
+divert
+dnl @result{}
diff --git a/checks/43.regexp b/checks/43.regexp
new file mode 100644
index 00000000..3ea5cac3
--- /dev/null
+++ b/checks/43.regexp
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2474: Origin of test
+regexp(`GNUs not Unix', `\<[a-z]\w+')
+dnl @result{}5
+regexp(`GNUs not Unix', `\<Q\w*')
+dnl @result{}-1
diff --git a/checks/44.regexp b/checks/44.regexp
new file mode 100644
index 00000000..8636b787
--- /dev/null
+++ b/checks/44.regexp
@@ -0,0 +1,3 @@
+dnl ../doc/m4.texinfo:2486: Origin of test
+regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
+dnl @result{}*** Unix *** nix ***
diff --git a/checks/44.undivert b/checks/44.undivert
new file mode 100644
index 00000000..f99162c6
--- /dev/null
+++ b/checks/44.undivert
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:2529: Origin of test
+divert(1)
+This text is diverted.
+divert
+dnl @result{}
+This text is not diverted.
+dnl @result{}This text is not diverted.
+undivert(1)
+dnl @result{}
+dnl @result{}This text is diverted.
+dnl @result{}
diff --git a/checks/45.substr b/checks/45.substr
new file mode 100644
index 00000000..a60c791b
--- /dev/null
+++ b/checks/45.substr
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2512: Origin of test
+substr(`gnus, gnats, and armadillos', 6)
+dnl @result{}gnats, and armadillos
+substr(`gnus, gnats, and armadillos', 6, 5)
+dnl @result{}gnats
diff --git a/checks/45.undivert b/checks/45.undivert
new file mode 100644
index 00000000..8835f78e
--- /dev/null
+++ b/checks/45.undivert
@@ -0,0 +1,13 @@
+dnl ../doc/m4.texinfo:2553: Origin of test
+divert(1)
+This text is diverted first.
+divert(0)undivert(1)dnl
+dnl @result{}
+dnl @result{}This text is diverted first.
+undivert(1)
+dnl @result{}
+divert(1)
+This text is also diverted but not appended.
+divert(0)undivert(1)dnl
+dnl @result{}
+dnl @result{}This text is also diverted but not appended.
diff --git a/checks/46.translit b/checks/46.translit
new file mode 100644
index 00000000..78c10daa
--- /dev/null
+++ b/checks/46.translit
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:2553: Origin of test
+translit(`GNUs not Unix', `A-Z')
+dnl @result{}s not nix
+translit(`GNUs not Unix', `a-z', `A-Z')
+dnl @result{}GNUS NOT UNIX
+translit(`GNUs not Unix', `A-Z', `z-a')
+dnl @result{}tmfs not fnix
diff --git a/checks/46.undivert b/checks/46.undivert
new file mode 100644
index 00000000..f951d011
--- /dev/null
+++ b/checks/46.undivert
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2579: Origin of test
+define(`bar', `BAR')
+dnl @result{}
+undivert(`foo')
+dnl @result{}bar
+dnl @result{}
+include(`foo')
+dnl @result{}BAR
+dnl @result{}
diff --git a/checks/47.divnum b/checks/47.divnum
new file mode 100644
index 00000000..c64945f8
--- /dev/null
+++ b/checks/47.divnum
@@ -0,0 +1,13 @@
+dnl ../doc/m4.texinfo:2605: Origin of test
+Initial divnum
+dnl @result{}Initial 0
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert
+dnl @result{}
+dnl @result{}
+dnl @result{}Diversion one: 1
+dnl @result{}
+dnl @result{}Diversion two: 2
diff --git a/checks/47.patsubst b/checks/47.patsubst
new file mode 100644
index 00000000..8235b50c
--- /dev/null
+++ b/checks/47.patsubst
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:2604: Origin of test
+patsubst(`GNUs not Unix', `^', `OBS: ')
+dnl @result{}OBS: GNUs not Unix
+patsubst(`GNUs not Unix', `\<', `OBS: ')
+dnl @result{}OBS: GNUs OBS: not OBS: Unix
+patsubst(`GNUs not Unix', `\w*', `(\&)')
+dnl @result{}(GNUs)() (not)() (Unix)
+patsubst(`GNUs not Unix', `\w+', `(\&)')
+dnl @result{}(GNUs) (not) (Unix)
+patsubst(`GNUs not Unix', `[A-Z][a-z]+')
+dnl @result{}GN not
diff --git a/checks/48.cleardiv b/checks/48.cleardiv
new file mode 100644
index 00000000..cd779109
--- /dev/null
+++ b/checks/48.cleardiv
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:2636: Origin of test
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert(-1)
+undivert
diff --git a/checks/48.patsubst b/checks/48.patsubst
new file mode 100644
index 00000000..0e042a62
--- /dev/null
+++ b/checks/48.patsubst
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2621: Origin of test
+define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
+define(`downcase', `translit(`$*', `A-Z', `a-z')')dnl
+define(`capitalize1',
+ `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')dnl
+define(`capitalize',
+ `patsubst(`$1', `\w+', `capitalize1(`\&')')')dnl
+capitalize(`GNUs not Unix')
+dnl @result{}Gnus Not Unix
diff --git a/checks/49.cleardiv b/checks/49.cleardiv
new file mode 100644
index 00000000..8d4b7501
--- /dev/null
+++ b/checks/49.cleardiv
@@ -0,0 +1,4 @@
+dnl ../doc/m4.texinfo:2651: Origin of test
+define(`cleardivert',
+`pushdef(`_num', divnum)divert(-1)undivert($@)divert(_num)popdef(`_num')')
+dnl @result{}
diff --git a/checks/49.format b/checks/49.format
new file mode 100644
index 00000000..0daa49a7
--- /dev/null
+++ b/checks/49.format
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2656: Origin of test
+define(`foo', `The brown fox jumped over the lazy dog')
+dnl @result{}
+format(`The string "%s" is %d characters long', foo, len(foo))
+dnl @result{}The string "The brown fox jumped over the lazy dog" is 38 characters long
diff --git a/checks/50.incr b/checks/50.incr
new file mode 100644
index 00000000..45ee7226
--- /dev/null
+++ b/checks/50.incr
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2726: Origin of test
+incr(4)
+dnl @result{}5
+decr(7)
+dnl @result{}6
diff --git a/checks/50.len b/checks/50.len
new file mode 100644
index 00000000..37c7cf72
--- /dev/null
+++ b/checks/50.len
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2693: Origin of test
+len()
+dnl @result{}0
+len(`abcdef')
+dnl @result{}6
diff --git a/checks/51.eval b/checks/51.eval
new file mode 100644
index 00000000..dcf04759
--- /dev/null
+++ b/checks/51.eval
@@ -0,0 +1,18 @@
+dnl ../doc/m4.texinfo:2808: Origin of test
+eval(-3 * 5)
+dnl @result{}-15
+eval(index(`Hello world', `llo') >= 0)
+dnl @result{}1
+define(`square', `eval(($1)**2)')
+dnl @result{}
+square(9)
+dnl @result{}81
+square(square(5)+1)
+dnl @result{}676
+define(`foo', `666')
+dnl @result{}
+eval(`foo'/6)
+dnl @error{}51.eval:14: m4: Bad expression in eval: foo/6
+dnl @result{}
+eval(foo/6)
+dnl @result{}111
diff --git a/checks/51.index b/checks/51.index
new file mode 100644
index 00000000..e540cdd8
--- /dev/null
+++ b/checks/51.index
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2719: Origin of test
+index(`gnus, gnats, and armadillos', `nat')
+dnl @result{}7
+index(`gnus, gnats, and armadillos', `dag')
+dnl @result{}-1
diff --git a/checks/52.eval b/checks/52.eval
new file mode 100644
index 00000000..b6a0da83
--- /dev/null
+++ b/checks/52.eval
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:2839: Origin of test
+eval(666, 10)
+dnl @result{}666
+eval(666, 11)
+dnl @result{}556
+eval(666, 6)
+dnl @result{}3030
+eval(666, 6, 10)
+dnl @result{}0000003030
+eval(-666, 6, 10)
+dnl @result{}-000003030
diff --git a/checks/52.regexp b/checks/52.regexp
new file mode 100644
index 00000000..27ad63d5
--- /dev/null
+++ b/checks/52.regexp
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2751: Origin of test
+regexp(`GNUs not Unix', `\<[a-z]\w+')
+dnl @result{}5
+regexp(`GNUs not Unix', `\<Q\w*')
+dnl @result{}-1
diff --git a/checks/53.esyscmd b/checks/53.esyscmd
new file mode 100644
index 00000000..c92f7941
--- /dev/null
+++ b/checks/53.esyscmd
@@ -0,0 +1,6 @@
+dnl ../doc/m4.texinfo:2924: Origin of test
+define(`vice', `esyscmd(grep Vice ../COPYING)')
+dnl @result{}
+vice
+dnl @result{} Ty Coon, President of Vice
+dnl @result{}
diff --git a/checks/53.regexp b/checks/53.regexp
new file mode 100644
index 00000000..b9263838
--- /dev/null
+++ b/checks/53.regexp
@@ -0,0 +1,3 @@
+dnl ../doc/m4.texinfo:2763: Origin of test
+regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
+dnl @result{}*** Unix *** nix ***
diff --git a/checks/54.substr b/checks/54.substr
new file mode 100644
index 00000000..b2ad41ff
--- /dev/null
+++ b/checks/54.substr
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2789: Origin of test
+substr(`gnus, gnats, and armadillos', 6)
+dnl @result{}gnats, and armadillos
+substr(`gnus, gnats, and armadillos', 6, 5)
+dnl @result{}gnats
diff --git a/checks/54.sysval b/checks/54.sysval
new file mode 100644
index 00000000..bc9400db
--- /dev/null
+++ b/checks/54.sysval
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2955: Origin of test
+syscmd(`false')
+dnl @result{}
+ifelse(sysval, 0, zero, non-zero)
+dnl @result{}non-zero
+syscmd(`true')
+dnl @result{}
+sysval
+dnl @result{}0
diff --git a/checks/55.errprint b/checks/55.errprint
new file mode 100644
index 00000000..ba292c22
--- /dev/null
+++ b/checks/55.errprint
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:3034: Origin of test
+errprint(`Illegal arguments to forloop
+')
+dnl @error{}Illegal arguments to forloop
+dnl @result{}
diff --git a/checks/55.translit b/checks/55.translit
new file mode 100644
index 00000000..d0c1a522
--- /dev/null
+++ b/checks/55.translit
@@ -0,0 +1,7 @@
+dnl ../doc/m4.texinfo:2830: Origin of test
+translit(`GNUs not Unix', `A-Z')
+dnl @result{}s not nix
+translit(`GNUs not Unix', `a-z', `A-Z')
+dnl @result{}GNUS NOT UNIX
+translit(`GNUs not Unix', `A-Z', `z-a')
+dnl @result{}tmfs not fnix
diff --git a/checks/56.errprint b/checks/56.errprint
new file mode 100644
index 00000000..a5be31ff
--- /dev/null
+++ b/checks/56.errprint
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:3059: Origin of test
+errprint(`m4:'__file__:__line__: `Input error
+')
+dnl @error{}m4:56.errprint:2: Input error
+dnl @result{}
diff --git a/checks/56.patsubst b/checks/56.patsubst
new file mode 100644
index 00000000..5da8e3c7
--- /dev/null
+++ b/checks/56.patsubst
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:2881: Origin of test
+patsubst(`GNUs not Unix', `^', `OBS: ')
+dnl @result{}OBS: GNUs not Unix
+patsubst(`GNUs not Unix', `\<', `OBS: ')
+dnl @result{}OBS: GNUs OBS: not OBS: Unix
+patsubst(`GNUs not Unix', `\w*', `(\&)')
+dnl @result{}(GNUs)() (not)() (Unix)
+patsubst(`GNUs not Unix', `\w+', `(\&)')
+dnl @result{}(GNUs) (not) (Unix)
+patsubst(`GNUs not Unix', `[A-Z][a-z]+')
+dnl @result{}GN not
diff --git a/checks/57.m4exit b/checks/57.m4exit
new file mode 100644
index 00000000..2cbb2d18
--- /dev/null
+++ b/checks/57.m4exit
@@ -0,0 +1,6 @@
+dnl ../doc/m4.texinfo:3082: Origin of test
+define(`fatal_error', `errprint(`m4: '__file__: __line__`: fatal error: $*
+')m4exit(1)')
+dnl @result{}
+fatal_error(`This is a BAD one, buster')
+dnl @error{}m4: 57.m4exit: 5: fatal error: This is a BAD one, buster
diff --git a/checks/57.patsubst b/checks/57.patsubst
new file mode 100644
index 00000000..36f0f315
--- /dev/null
+++ b/checks/57.patsubst
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:2898: Origin of test
+define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
+define(`downcase', `translit(`$*', `A-Z', `a-z')')dnl
+define(`capitalize1',
+ `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')dnl
+define(`capitalize',
+ `patsubst(`$1', `\w+', `capitalize1(`\&')')')dnl
+capitalize(`GNUs not Unix')
+dnl @result{}Gnus Not Unix
diff --git a/checks/58.format b/checks/58.format
new file mode 100644
index 00000000..edeefd7e
--- /dev/null
+++ b/checks/58.format
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:2933: Origin of test
+define(`foo', `The brown fox jumped over the lazy dog')
+dnl @result{}
+format(`The string "%s" is %d characters long', foo, len(foo))
+dnl @result{}The string "The brown fox jumped over the lazy dog" is 38 characters long
diff --git a/checks/59.incr b/checks/59.incr
new file mode 100644
index 00000000..a6c4f6f2
--- /dev/null
+++ b/checks/59.incr
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:3003: Origin of test
+incr(4)
+dnl @result{}5
+decr(7)
+dnl @result{}6
diff --git a/checks/60.eval b/checks/60.eval
new file mode 100644
index 00000000..89490b2e
--- /dev/null
+++ b/checks/60.eval
@@ -0,0 +1,18 @@
+dnl ../doc/m4.texinfo:3097: Origin of test
+eval(-3 * 5)
+dnl @result{}-15
+eval(index(`Hello world', `llo') >= 0)
+dnl @result{}1
+define(`square', `eval(($1)**2)')
+dnl @result{}
+square(9)
+dnl @result{}81
+square(square(5)+1)
+dnl @result{}676
+define(`foo', `666')
+dnl @result{}
+eval(`foo'/6)
+dnl @error{}60.eval:14: m4: Bad expression in eval: foo/6
+dnl @result{}
+eval(foo/6)
+dnl @result{}111
diff --git a/checks/61.eval b/checks/61.eval
new file mode 100644
index 00000000..64594c57
--- /dev/null
+++ b/checks/61.eval
@@ -0,0 +1,11 @@
+dnl ../doc/m4.texinfo:3128: Origin of test
+eval(666, 10)
+dnl @result{}666
+eval(666, 11)
+dnl @result{}556
+eval(666, 6)
+dnl @result{}3030
+eval(666, 6, 10)
+dnl @result{}0000003030
+eval(-666, 6, 10)
+dnl @result{}-000003030
diff --git a/checks/62.esyscmd b/checks/62.esyscmd
new file mode 100644
index 00000000..27c3bda4
--- /dev/null
+++ b/checks/62.esyscmd
@@ -0,0 +1,6 @@
+dnl ../doc/m4.texinfo:3213: Origin of test
+define(`vice', `esyscmd(grep Vice ../COPYING)')
+dnl @result{}
+vice
+dnl @result{} Ty Coon, President of Vice
+dnl @result{}
diff --git a/checks/63.sysval b/checks/63.sysval
new file mode 100644
index 00000000..1b7b110a
--- /dev/null
+++ b/checks/63.sysval
@@ -0,0 +1,9 @@
+dnl ../doc/m4.texinfo:3244: Origin of test
+syscmd(`false')
+dnl @result{}
+ifelse(sysval, 0, zero, non-zero)
+dnl @result{}non-zero
+syscmd(`true')
+dnl @result{}
+sysval
+dnl @result{}0
diff --git a/checks/64.errprint b/checks/64.errprint
new file mode 100644
index 00000000..b0cfbffd
--- /dev/null
+++ b/checks/64.errprint
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:3324: Origin of test
+errprint(`Illegal arguments to forloop
+')
+dnl @error{}Illegal arguments to forloop
+dnl @result{}
diff --git a/checks/65.errprint b/checks/65.errprint
new file mode 100644
index 00000000..230093e8
--- /dev/null
+++ b/checks/65.errprint
@@ -0,0 +1,5 @@
+dnl ../doc/m4.texinfo:3349: Origin of test
+errprint(`m4:'__file__:__line__: `Input error
+')
+dnl @error{}m4:65.errprint:2: Input error
+dnl @result{}
diff --git a/checks/66.m4exit b/checks/66.m4exit
new file mode 100644
index 00000000..eccef14b
--- /dev/null
+++ b/checks/66.m4exit
@@ -0,0 +1,6 @@
+dnl ../doc/m4.texinfo:3372: Origin of test
+define(`fatal_error', `errprint(`m4: '__file__: __line__`: fatal error: $*
+')m4exit(1)')
+dnl @result{}
+fatal_error(`This is a BAD one, buster')
+dnl @error{}m4: 66.m4exit: 5: fatal error: This is a BAD one, buster
diff --git a/checks/Makefile.am b/checks/Makefile.am
new file mode 100644
index 00000000..65d0de77
--- /dev/null
+++ b/checks/Makefile.am
@@ -0,0 +1,16 @@
+EXTRA_DIST = check-them foo get-them incl.m4 stamp-checks $(CHECKS)
+
+CHECKS = ??.*
+
+all: stamp-checks
+
+stamp-checks: get-them ../doc/m4.texinfo
+ rm -f $(srcdir)/$(CHECKS)
+ cd $(srcdir) && AWK=$(AWK) ./get-them ../doc/m4.texinfo
+ touch $(srcdir)/stamp-checks
+
+check: stamp-checks
+ PATH=`pwd`/../src:$$PATH; export PATH; \
+ cd $(srcdir) && ./check-them $(CHECKS)
+
+
diff --git a/checks/Makefile.in b/checks/Makefile.in
new file mode 100644
index 00000000..c1c4aaf8
--- /dev/null
+++ b/checks/Makefile.in
@@ -0,0 +1,76 @@
+# Makefile for GNU m4 checks directory.
+# Copyright (C) 1992, 1993, 1994 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 2, 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, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+PRODUCT = @PRODUCT@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+# Should be GNU awk, for the get-them script.
+AWK = @AWK@
+
+# Vern says that the first star is required around an Alpha make bug.
+CHECKS = *[0-9][0-9].*
+DISTFILES = Makefile.in get-them check-them stamp-checks incl.m4 foo
+
+all: stamp-checks
+
+stamp-checks: get-them ../doc/m4.texinfo
+ rm -f $(srcdir)/$(CHECKS)
+ cd $(srcdir) && AWK=$(AWK) ./get-them ../doc/m4.texinfo
+ touch $(srcdir)/stamp-checks
+
+install:
+
+uninstall:
+
+check: stamp-checks
+ PATH=`pwd`/../src:$$PATH; export PATH; \
+ cd $(srcdir) && ./check-them $(CHECKS)
+
+tags:
+
+mostlyclean:
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile
+
+realclean: distclean
+ rm -f $(CHECKS) stamp-checks
+
+dist: $(DISTFILES)
+ @echo "Copying distribution files"
+ @for file in $(DISTFILES); do \
+ ln $(srcdir)/$$file ../$(PRODUCT)-$(VERSION)/checks 2> /dev/null \
+ || cp -p $(srcdir)/$$file ../$(PRODUCT)-$(VERSION)/checks; \
+ done
+ @for file in $(srcdir)/$(CHECKS); do \
+ ln $$file ../$(PRODUCT)-$(VERSION)/checks \
+ || cp -p $$file ../$(PRODUCT)-$(VERSION)/checks; \
+ done
+
+Makefile: Makefile.in ../config.status
+ cd .. && CONFIG_FILES=checks/$@ CONFIG_HEADERS= ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/checks/check-them b/checks/check-them
new file mode 100755
index 00000000..5dd205b9
--- /dev/null
+++ b/checks/check-them
@@ -0,0 +1,51 @@
+#!/bin/sh
+# Check GNU m4 against examples from the manual source.
+# Copyright (C) 1992 Free Software Foundation, Inc.
+
+out=/tmp/m4-out.$$
+err=/tmp/m4-err.$$
+xout=/tmp/m4-xout.$$
+xerr=/tmp/m4-xerr.$$
+
+trap "rm -f $out $err $xout $xerr; exit 1" 1 2 15
+
+m4 --version
+
+for file
+do
+ echo "Checking $file"
+ m4 -d $file >$out 2>$err
+
+ sed -e '/^dnl @result{}/!d' -e 's///' $file > $xout
+
+ if cmp -s $out $xout; then
+ :
+ else
+ failed="$failed $file:out"
+ echo `sed -e 's/^dnl //' -e 1q $file`
+ echo "$file: stdout mismatch"
+ diff $xout $out
+ fi
+
+ sed -e '/^dnl @error{}/!d' -e 's///' $file > $xerr
+
+ if cmp -s $err $xerr; then
+ :
+ else
+ failed="$failed $file:err"
+ echo `sed -e 's/^dnl //' -e 1q $file`
+ echo "$file: stderr mismatch"
+ diff $xerr $err
+ fi
+
+done
+
+rm -f $out $err $xout $xerr
+
+echo
+if test -z "$failed"; then
+ echo "All checks successful"
+else
+ echo "Failed checks were:"
+ echo " $failed"
+fi
diff --git a/checks/foo b/checks/foo
new file mode 100644
index 00000000..5716ca59
--- /dev/null
+++ b/checks/foo
@@ -0,0 +1 @@
+bar
diff --git a/checks/get-them b/checks/get-them
new file mode 100755
index 00000000..84300f02
--- /dev/null
+++ b/checks/get-them
@@ -0,0 +1,68 @@
+#!/bin/sh
+# Extract all examples from the manual source.
+# Copyright (C) 1992 Free Software Foundation, Inc.
+
+# This script is for use with GNU awk.
+
+FILE=${1-/dev/null}
+
+$AWK '
+
+BEGIN {
+ node = "";
+ seq = -1;
+ count = 0;
+ file = "NONE";
+}
+
+/^@node / {
+ if (seq > 0)
+ printf(" -- %d file%s", seq, seq == 1 ? "" : "s");
+ if (seq >= 0)
+ printf("\n");
+
+ split($0, tmp, ",");
+ node = substr(tmp[1], 7);
+ if (length(node) > 11)
+ printf("Node: %s - truncated", node);
+ else
+ printf("Node: %s ", node);
+ gsub(" ", "_", node);
+ node = tolower(substr(node, 1, 11));
+ seq = 0;
+}
+
+/^@comment ignore$/ {
+ getline;
+ next;
+}
+
+/^@example$/, /^@end example$/ {
+ if (seq < 0)
+ next;
+ if ($0 ~ /^@example$/) {
+ if (count > 0)
+ close (file);
+ seq++;
+ count++;
+ file = sprintf("%02d.%s", count, node);
+ printf("dnl %s:%d: Origin of test\n", FILENAME, NR) > file;
+ next;
+ }
+ if ($0 ~ /^@end example$/) {
+ next;
+ }
+ if ($0 ~ /^\^D$/)
+ next;
+ if ($0 ~ /^@result\{\}/ || $0 ~ /^@error\{\}/)
+ prefix = "dnl ";
+ else
+ prefix = "";
+ gsub("@@", "@", $0);
+ printf("%s%s\n", prefix, $0) >> file;
+}
+
+END {
+ printf("\n");
+}
+' $FILE
diff --git a/checks/incl.m4 b/checks/incl.m4
new file mode 100644
index 00000000..ab9572eb
--- /dev/null
+++ b/checks/incl.m4
@@ -0,0 +1,3 @@
+Include file start
+foo
+Include file end
diff --git a/checks/stamp-checks b/checks/stamp-checks
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/checks/stamp-checks
diff --git a/config.guess b/config.guess
new file mode 100755
index 00000000..413ed41c
--- /dev/null
+++ b/config.guess
@@ -0,0 +1,883 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright (C) 1992, 93, 94, 95, 96, 1997 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Written by Per Bothner <bothner@cygnus.com>.
+# The master version of this file is at the FSF in /home/gd/gnu/lib.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub. If it succeeds, it prints the system name on stdout, and
+# exits with 0. Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit system type (host/target name).
+#
+# Only a few systems have been added to this list; please add others
+# (but try to keep the structure clean).
+#
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 8/24/94.)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ alpha:OSF1:*:*)
+ if test $UNAME_RELEASE = "V4.0"; then
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ fi
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ cat <<EOF >dummy.s
+ .globl main
+ .ent main
+main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ ${CC-cc} dummy.s -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+ fi
+ rm -f dummy.s dummy
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-cbm-sysv4
+ exit 0;;
+ amiga:NetBSD:*:*)
+ echo m68k-cbm-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ amiga:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc64:OpenBSD:*:*)
+ echo mips64el-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hkmips:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ pmax:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sgi:OpenBSD:*:*)
+ echo mips-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ wgrisc:OpenBSD:*:*)
+ echo mipsel-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit 0;;
+ arm32:NetBSD:*:*)
+ echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ SR2?01:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit 0;;
+ Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit 0 ;;
+ NILE:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit 0 ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit 0 ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit 0 ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:NetBSD:*:*)
+ echo m68k-atari-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ atari*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:NetBSD:*:*)
+ echo m68k-sun-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:NetBSD:*:*)
+ echo m68k-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme68k:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mvme88k:OpenBSD:*:*)
+ echo m88k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit 0 ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit 0 ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit 0 ;;
+ 2020:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit 0 ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ sed 's/^ //' << EOF >dummy.c
+ int main (argc, argv) int argc; char **argv; {
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy \
+ && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+ && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit 0 ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit 0 ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
+ -o ${TARGET_BINARY_INTERFACE}x = x ] ; then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit 0 ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit 0 ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit 0 ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit 0 ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit 0 ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i?86:AIX:*:*)
+ echo i386-ibm-aix
+ exit 0 ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ sed 's/^ //' << EOF >dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo rs6000-ibm-aix3.2.5
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit 0 ;;
+ *:AIX:*:4)
+ if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=4.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit 0 ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit 0 ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit 0 ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit 0 ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit 0 ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit 0 ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit 0 ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit 0 ;;
+ 9000/[3478]??:HP-UX:*:*)
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
+ 9000/8?? ) HP_ARCH=hppa1.0 ;;
+ esac
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit 0 ;;
+ 3050*:HI-UX:*:*)
+ sed 's/^ //' << EOF >dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ echo unknown-hitachi-hiuxwe2
+ exit 0 ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit 0 ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit 0 ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit 0 ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit 0 ;;
+ i?86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ CRAY*X-MP:*:*:*)
+ echo xmp-cray-unicos
+ exit 0 ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
+ exit 0 ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY-2:*:*:*)
+ echo cray2-cray-unicos
+ exit 0 ;;
+ F300:UNIX_System_V:*:*)
+ FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit 0 ;;
+ F301:UNIX_System_V:*:*)
+ echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
+ exit 0 ;;
+ hp3[0-9][05]:NetBSD:*:*)
+ echo m68k-hp-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ hp300:OpenBSD:*:*)
+ echo m68k-unknown-openbsd${UNAME_RELEASE}
+ exit 0 ;;
+ i?86:BSD/386:*:* | *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit 0 ;;
+ *:FreeBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit 0 ;;
+ *:NetBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ *:OpenBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+ exit 0 ;;
+ i*:CYGWIN*:*)
+ echo i386-pc-cygwin32
+ exit 0 ;;
+ i*:MINGW*:*)
+ echo i386-pc-mingw32
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin32
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
+ *:GNU:*:*)
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit 0 ;;
+ *:Linux:*:*)
+ # The BFD linker knows what the default object file format is, so
+ # first see if it will tell us.
+ ld_help_string=`ld --help 2>&1`
+ ld_supported_emulations=`echo $ld_help_string \
+ | sed -ne '/supported emulations:/!d
+ s/[ ][ ]*/ /g
+ s/.*supported emulations: *//
+ s/ .*//
+ p'`
+ case "$ld_supported_emulations" in
+ i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
+ i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
+ sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
+ elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;;
+ esac
+
+ if test "${UNAME_MACHINE}" = "alpha" ; then
+ sed 's/^ //' <<EOF >dummy.s
+ .globl main
+ .ent main
+ main:
+ .frame \$30,0,\$26,0
+ .prologue 0
+ .long 0x47e03d80 # implver $0
+ lda \$2,259
+ .long 0x47e20c21 # amask $2,$1
+ srl \$1,8,\$2
+ sll \$2,2,\$2
+ sll \$0,3,\$0
+ addl \$1,\$0,\$0
+ addl \$2,\$0,\$0
+ ret \$31,(\$26),1
+ .end main
+EOF
+ LIBC=""
+ ${CC-cc} dummy.s -o dummy 2>/dev/null
+ if test "$?" = 0 ; then
+ ./dummy
+ case "$?" in
+ 7)
+ UNAME_MACHINE="alpha"
+ ;;
+ 15)
+ UNAME_MACHINE="alphaev5"
+ ;;
+ 14)
+ UNAME_MACHINE="alphaev56"
+ ;;
+ 10)
+ UNAME_MACHINE="alphapca56"
+ ;;
+ 16)
+ UNAME_MACHINE="alphaev6"
+ ;;
+ esac
+
+ objdump --private-headers dummy | \
+ grep ld.so.1 > /dev/null
+ if test "$?" = 0 ; then
+ LIBC="libc1"
+ fi
+ fi
+ rm -f dummy.s dummy
+ echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
+ elif test "${UNAME_MACHINE}" = "mips" ; then
+ cat >dummy.c <<EOF
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __MIPSEB__
+ printf ("%s-unknown-linux-gnu\n", argv[1]);
+#endif
+#ifdef __MIPSEL__
+ printf ("%sel-unknown-linux-gnu\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ else
+ # Either a pre-BFD a.out linker (linux-gnuoldld)
+ # or one that does not give us useful --help.
+ # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout.
+ # If ld does not provide *any* "supported emulations:"
+ # that means it is gnuoldld.
+ echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:"
+ test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0
+
+ case "${UNAME_MACHINE}" in
+ i?86)
+ VENDOR=pc;
+ ;;
+ *)
+ VENDOR=unknown;
+ ;;
+ esac
+ # Determine whether the default compiler is a.out or elf
+ cat >dummy.c <<EOF
+#include <features.h>
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+#ifdef __ELF__
+# ifdef __GLIBC__
+# if __GLIBC__ >= 2
+ printf ("%s-${VENDOR}-linux-gnu\n", argv[1]);
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+# else
+ printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]);
+# endif
+#else
+ printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]);
+#endif
+ return 0;
+}
+EOF
+ ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
+ rm -f dummy.c dummy
+ fi ;;
+# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
+# are messed up and put the nodename in both sysname and nodename.
+ i?86:DYNIX/ptx:4*:*)
+ echo i386-sequent-sysv4
+ exit 0 ;;
+ i?86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit 0 ;;
+ i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ i?86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit 0 ;;
+ pc:*:*:*)
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i386.
+ echo i386-pc-msdosdjgpp
+ exit 0 ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit 0 ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit 0 ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit 0 ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit 0 ;;
+ M68*:*:R3V[567]*:*)
+ test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+ 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && echo i486-ncr-sysv4 && exit 0 ;;
+ m68*:LynxOS:2.*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit 0 ;;
+ i?86:LynxOS:2.*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit 0 ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit 0 ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit 0 ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit 0 ;;
+ PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit 0 ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit 0 ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ news*:NEWS-OS:*:6*)
+ echo mips-sony-newsos6
+ exit 0 ;;
+ R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+ /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
+ I don't know.... */
+ printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+ printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+ "4"
+#else
+ ""
+#endif
+ ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+ printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+ printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+ int version;
+ version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+ printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+ exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+ printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+ printf ("ns32k-encore-mach\n"); exit (0);
+#else
+ printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+ printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+ printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+ printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+ printf ("vax-dec-bsd\n"); exit (0);
+#else
+ printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+ printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+ exit (1);
+}
+EOF
+
+${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
+rm -f dummy.c dummy
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+ case `getsysinfo -f cpu_type` in
+ c1*)
+ echo c1-convex-bsd
+ exit 0 ;;
+ c2*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit 0 ;;
+ c34*)
+ echo c34-convex-bsd
+ exit 0 ;;
+ c38*)
+ echo c38-convex-bsd
+ exit 0 ;;
+ c4*)
+ echo c4-convex-bsd
+ exit 0 ;;
+ esac
+fi
+
+#echo '(Unable to guess system type)' 1>&2
+
+exit 1
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 00000000..c3e44e7e
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,129 @@
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define if on AIX 3.
+ System headers sometimes define this.
+ We just want to avoid a redefinition error message. */
+#ifndef _ALL_SOURCE
+#undef _ALL_SOURCE
+#endif
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have alloca, as a function or macro. */
+#undef HAVE_ALLOCA
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you don't have vprintf but do have _doprnt. */
+#undef HAVE_DOPRNT
+
+/* Define if you have the vprintf function. */
+#undef HAVE_VPRINTF
+
+/* Define if on MINIX. */
+#undef _MINIX
+
+/* Define if the system does not provide POSIX.1 features except
+ with this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void). */
+#undef RETSIGTYPE
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if the changeword(REGEXP) functionnality is wanted. */
+#undef ENABLE_CHANGEWORD
+
+/* Define to 1 if you have ecvt(3), fcvt(3) and gcvt(3), define to 2 if
+ these are declared in <stdlib.h>. */
+#undef HAVE_EFGCVT
+
+/* Define to 1 if #include <signal.h> declares struct sigcontext */
+#undef HAVE_SIGCONTEXT
+
+/* Define to the name of the distribution. */
+#undef PRODUCT
+
+/* Define to 1 if ANSI function prototypes are usable. */
+#undef PROTOTYPES
+
+/* Define to int if rlim_t is not defined in sys/resource.h */
+#undef rlim_t
+
+/* Define to struct sigaltstack if stack_t is not defined in sys/signal.h */
+#undef stack_t
+
+/* Define to 1 if using stack overflow detection. */
+#undef USE_STACKOVF
+
+/* Define to the version of the distribution. */
+#undef VERSION
+
+/* Define to 1 for better use of the debugging malloc library. See
+ site ftp.antaire.com in antaire/src, file dmalloc/dmalloc.tar.gz. */
+#undef WITH_DMALLOC
+
+/* Define if you have the ecvt function. */
+#undef HAVE_ECVT
+
+/* Define if you have the mkstemp function. */
+#undef HAVE_MKSTEMP
+
+/* Define if you have the sigaction function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the sigaltstack function. */
+#undef HAVE_SIGALTSTACK
+
+/* Define if you have the sigstack function. */
+#undef HAVE_SIGSTACK
+
+/* Define if you have the sigvec function. */
+#undef HAVE_SIGVEC
+
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
+
+/* Define if you have the tmpfile function. */
+#undef HAVE_TMPFILE
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <siginfo.h> header file. */
+#undef HAVE_SIGINFO_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
diff --git a/config.sub b/config.sub
new file mode 100755
index 00000000..213a6d47
--- /dev/null
+++ b/config.sub
@@ -0,0 +1,954 @@
+#! /bin/sh
+# Configuration validation subroutine script, version 1.1.
+# Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine. It does not imply ALL GNU software can.
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+if [ x$1 = x ]
+then
+ echo Configuration name missing. 1>&2
+ echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
+ echo "or $0 ALIAS" 1>&2
+ echo where ALIAS is a recognized configuration type. 1>&2
+ exit 1
+fi
+
+# First pass through any local machine types.
+case $1 in
+ *local*)
+ echo $1
+ exit 0
+ ;;
+ *)
+ ;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
+ os=
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco5)
+ os=sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
+ | arme[lb] | pyramid | mn10200 | mn10300 \
+ | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
+ | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
+ | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
+ | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
+ | mipstx39 | mipstx39el \
+ | sparc | sparclet | sparclite | sparc64 | v850)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[3456]86)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \
+ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
+ | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
+ | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
+ | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
+ | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
+ | sparc64-* | mips64-* | mipsel-* \
+ | mips64el-* | mips64orion-* | mips64orionel-* \
+ | mipstx39-* | mipstx39el-* \
+ | f301-*)
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-cbm
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-cbm
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-cbm
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ cray2)
+ basic_machine=cray2-cray
+ os=-unicos
+ ;;
+ [ctj]90-cray)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+# I'm not sure what "Sysv32" means. Should this be sysv3.2?
+ i[3456]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i[3456]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i[3456]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i[3456]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ mipsel*-linux*)
+ basic_machine=mipsel-unknown
+ os=-linux-gnu
+ ;;
+ mips*-linux*)
+ basic_machine=mips-unknown
+ os=-linux-gnu
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pentium | p5)
+ basic_machine=i586-intel
+ ;;
+ pentiumpro | p6)
+ basic_machine=i686-intel
+ ;;
+ pentium-* | p5-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ k5)
+ # We don't have specific support for AMD's K5 yet, so just call it a Pentium
+ basic_machine=i586-amd
+ ;;
+ nexen)
+ # We don't have specific support for Nexgen yet, so just call it a Pentium
+ basic_machine=i586-nexgen
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=rs6000-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ xmp)
+ basic_machine=xmp-cray
+ os=-unicos
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ mips)
+ if [ x$os = x-linux-gnu ]; then
+ basic_machine=mips-unknown
+ else
+ basic_machine=mips-mips
+ fi
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sparc)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
+ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -linux-gnu* | -uxpv*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ # This also exists in the configure program, but was not the
+ # default.
+ # os=-sunos4
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f301-fujitsu)
+ os=-uxpv
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -aix*)
+ vendor=ibm
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -vxsim* | -vxworks*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
diff --git a/configure b/configure
new file mode 100755
index 00000000..b8658a69
--- /dev/null
+++ b/configure
@@ -0,0 +1,2123 @@
+#!/bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.1
+# Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-changeword enable -W and changeword() builtin"
+ac_help="$ac_help
+ --with-dmalloc use dmalloc, as in dmalloc.tar.gz from
+ @/ftp.antaire.com:antaire/src/dmalloc."
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Initialize some other variables.
+subdirs=
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -build | --build | --buil | --bui | --bu | --b)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=PREFIX install architecture-dependent files in PREFIX
+ [same as prefix]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+--enable and --with options recognized:$ac_help
+EOF
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.1"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 unused; standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 unused; some systems may open it to /dev/tty
+# 4 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 4>/dev/null
+else
+ exec 4>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=src/m4.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} $CFLAGS $CPPFLAGS conftest.$ac_ext -c 1>&5 2>&5'
+ac_link='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext -o conftest $LIBS 1>&5 2>&5'
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $.
+ echo 's,\\,\\\\,g; s,\$,$$,g' > conftestsed
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+
+PRODUCT=m4
+VERSION=1.4
+cat >> confdefs.h <<EOF
+#define PRODUCT "$PRODUCT"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+
+for ac_prog in mawk gawk nawk awk
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_prog_AWK'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AWK="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AWK="$ac_cv_prog_AWK"
+if test -n "$AWK"; then
+ echo "$ac_t""$AWK" 1>&4
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+test -n "$AWK" && break
+done
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&4
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+echo "$ac_t""$ac_cv_prog_gcc" 1>&4
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ if test "${CFLAGS+set}" != set; then
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_prog_gcc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_gcc_g=yes
+else
+ ac_cv_prog_gcc_g=no
+fi
+rm -f conftest*
+
+fi
+ echo "$ac_t""$ac_cv_prog_gcc_g" 1>&4
+ if test $ac_cv_prog_gcc_g = yes; then
+ CFLAGS="-g -O"
+ else
+ CFLAGS="-O"
+ fi
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&4
+if test -z "$INSTALL"; then
+if eval "test \"`echo '${'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ case "$ac_dir" in
+ ''|.|/etc|/usr/sbin|/usr/etc|/sbin|/usr/afsws/bin|/usr/ucb) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ for ac_prog in ginstall installbsd scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ # OSF/1 installbsd also uses dspmsg, but is usable.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_ifs"
+ # As a last resort, use the slow shell script.
+ test -z "$ac_cv_path_install" && ac_cv_path_install="$ac_install_sh"
+fi
+ INSTALL="$ac_cv_path_install"
+fi
+echo "$ac_t""$INSTALL" 1>&4
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether ${MAKE-make} sets \$MAKE""... $ac_c" 1>&4
+set dummy ${MAKE-make}; ac_make=$2
+if eval "test \"`echo '${'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&4
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&4
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&4
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '${'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 683 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 697 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+fi
+CPP="$ac_cv_prog_CPP"
+echo "$ac_t""$CPP" 1>&4
+
+echo $ac_n "checking for AIX""... $ac_c" 1>&4
+cat > conftest.$ac_ext <<EOF
+#line 722 "configure"
+#include "confdefs.h"
+#ifdef _AIX
+ yes
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "yes" >/dev/null 2>&1; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&4; cat >> confdefs.h <<\EOF
+#define _ALL_SOURCE 1
+EOF
+
+else
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&4
+fi
+rm -f conftest*
+
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&4
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&4
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&4
+ ISC=
+fi
+
+ac_safe=`echo "minix/config.h" | tr './\055' '___'`
+echo $ac_n "checking for minix/config.h""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 769 "configure"
+#include "confdefs.h"
+#include <minix/config.h>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ MINIX=yes
+else
+ echo "$ac_t""no" 1>&4
+MINIX=
+fi
+
+if test "$MINIX" = yes; then
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define _POSIX_1_SOURCE 2
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define _MINIX 1
+EOF
+
+fi
+
+echo $ac_n "checking for ${CC-cc} option to accept ANSI C""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_prog_cc_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ ac_cv_prog_cc_stdc=no
+ac_save_CFLAGS="$CFLAGS"
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX -qlanglvl=ansi
+# Ultrix and OSF/1 -std1
+# HP-UX -Aa -D_HPUX_SOURCE
+# SVR4 -Xc
+for ac_arg in "" -qlanglvl=ansi -std1 "-Aa -D_HPUX_SOURCE" -Xc
+do
+ CFLAGS="$ac_save_CFLAGS $ac_arg"
+ cat > conftest.$ac_ext <<EOF
+#line 824 "configure"
+#include "confdefs.h"
+#if !defined(__STDC__) || __STDC__ != 1
+choke me
+#endif
+
+int main() { return 0; }
+int t() {
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+; return 0; }
+EOF
+if eval $ac_compile; then
+ rm -rf conftest*
+ ac_cv_prog_cc_stdc="$ac_arg"; break
+fi
+rm -f conftest*
+
+done
+CFLAGS="$ac_save_CFLAGS"
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_stdc" 1>&4
+case "x$ac_cv_prog_cc_stdc" in
+ x|xno) ;;
+ *) CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+
+echo $ac_n "checking for function prototypes""... $ac_c" 1>&4
+if test "$ac_cv_prog_cc_stdc" != no; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define PROTOTYPES 1
+EOF
+
+ U= ANSI2KNR=
+else
+ echo "$ac_t""no" 1>&4
+ U=_ ANSI2KNR=ansi2knr
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 873 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero;
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if eval $ac_compile; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_c_const" 1>&4
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+
+for ac_hdr in limits.h memory.h siginfo.h string.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | tr './\055' '___'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 950 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./\055' '[A-Z]___'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+done
+
+# If we cannot run a trivial program, we must be cross compiling.
+echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_c_cross'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_cross=yes
+else
+cat > conftest.$ac_ext <<EOF
+#line 987 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ ac_cv_c_cross=no
+else
+ ac_cv_c_cross=yes
+fi
+fi
+rm -fr conftest*
+fi
+cross_compiling=$ac_cv_c_cross
+echo "$ac_t""$ac_cv_c_cross" 1>&4
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1008 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1030 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1048 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ ac_cv_header_stdc=no
+else
+cat > conftest.$ac_ext <<EOF
+#line 1069 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+fi
+rm -fr conftest*
+fi
+fi
+echo "$ac_t""$ac_cv_header_stdc" 1>&4
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1103 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+extern void (*signal ()) ();
+int main() { return 0; }
+int t() {
+int i;
+; return 0; }
+EOF
+if eval $ac_compile; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_signal" 1>&4
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1137 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "size_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&4
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+
+for ac_func in mkstemp sigaction sigaltstack sigstack sigvec strerror tmpfile
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1171 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+/* Override any gcc2 internal prototype to avoid an error. */
+char $ac_func();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ ac_tr_func=HAVE_`echo $ac_func | tr '[a-z]' '[A-Z]'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+done
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1220 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() { return 0; }
+int t() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&4
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_alloca'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1251 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+int main() { return 0; }
+int t() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ ac_cv_func_alloca=yes
+else
+ rm -rf conftest*
+ ac_cv_func_alloca=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_func_alloca" 1>&4
+if test $ac_cv_func_alloca = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.o
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1309 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_os_cray" 1>&4
+if test $ac_cv_os_cray = yes; then
+echo $ac_n "checking for _getb67""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func__getb67'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1336 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+/* Override any gcc2 internal prototype to avoid an error. */
+char _getb67();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub__getb67) || defined (__stub____getb67)
+choke me
+#else
+_getb67();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func__getb67=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func__getb67=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'_getb67`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define CRAY_STACKSEG_END _getb67
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+echo $ac_n "checking for GETB67""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_GETB67'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1379 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+/* Override any gcc2 internal prototype to avoid an error. */
+char GETB67();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_GETB67) || defined (__stub___GETB67)
+choke me
+#else
+GETB67();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_GETB67=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_GETB67=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'GETB67`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define CRAY_STACKSEG_END GETB67
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+echo $ac_n "checking for getb67""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_getb67'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1422 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+/* Override any gcc2 internal prototype to avoid an error. */
+char getb67();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_getb67) || defined (__stub___getb67)
+choke me
+#else
+getb67();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_getb67=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_getb67=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'getb67`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define CRAY_STACKSEG_END getb67
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+fi
+
+fi
+
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+cat > conftest.$ac_ext <<EOF
+#line 1476 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ ac_cv_c_stack_direction=1
+else
+ ac_cv_c_stack_direction=-1
+fi
+fi
+rm -fr conftest*
+fi
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&4
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+echo $ac_n "checking for vprintf""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_vprintf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1516 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+/* Override any gcc2 internal prototype to avoid an error. */
+char vprintf();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_vprintf) || defined (__stub___vprintf)
+choke me
+#else
+vprintf();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define HAVE_VPRINTF 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+if test "$ac_cv_func_vprintf" != yes; then
+echo $ac_n "checking for _doprnt""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func__doprnt'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1562 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+/* Override any gcc2 internal prototype to avoid an error. */
+char _doprnt();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+_doprnt();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define HAVE_DOPRNT 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+fi
+
+for ac_func in strtol
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1611 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+/* Override any gcc2 internal prototype to avoid an error. */
+char $ac_func();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ :
+else
+ echo "$ac_t""no" 1>&4
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+done
+
+echo $ac_n "checking ecvt declaration""... $ac_c" 1>&4
+cat > conftest.$ac_ext <<EOF
+#line 1653 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "ecvt" >/dev/null 2>&1; then
+ rm -rf conftest*
+ echo "$ac_t""yes" 1>&4; cat >> confdefs.h <<\EOF
+#define HAVE_EFGCVT 2
+EOF
+
+else
+ rm -rf conftest*
+ echo "$ac_t""no" 1>&4; for ac_func in ecvt
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1673 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+/* Override any gcc2 internal prototype to avoid an error. */
+char $ac_func();
+
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ ac_tr_func=HAVE_`echo $ac_func | tr '[a-z]' '[A-Z]'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+done
+
+fi
+rm -f conftest*
+
+
+echo $ac_n "checking if stack overflow is detectable""... $ac_c" 1>&4
+# 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
+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
+ cat > conftest.$ac_ext <<EOF
+#line 1729 "configure"
+#include "confdefs.h"
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <signal.h>
+int main() { return 0; }
+int t() {
+struct rlimit r; int i; 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
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ use_stackovf=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+echo "$ac_t""$use_stackovf" 1>&4
+if test "$use_stackovf" = yes; then
+ cat >> confdefs.h <<\EOF
+#define USE_STACKOVF 1
+EOF
+
+ STACKOVF=stackovf.${U}o
+
+ cat > conftest.$ac_ext <<EOF
+#line 1760 "configure"
+#include "confdefs.h"
+#include <sys/resource.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "rlim_t" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define rlim_t int
+EOF
+
+fi
+rm -f conftest*
+
+ cat > conftest.$ac_ext <<EOF
+#line 1777 "configure"
+#include "confdefs.h"
+#include <signal.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "stack_t" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define stack_t struct sigaltstack
+EOF
+
+fi
+rm -f conftest*
+
+ cat > conftest.$ac_ext <<EOF
+#line 1794 "configure"
+#include "confdefs.h"
+#include <signal.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "sigcontext" >/dev/null 2>&1; then
+ rm -rf conftest*
+ cat >> confdefs.h <<\EOF
+#define HAVE_SIGCONTEXT 1
+EOF
+
+fi
+rm -f conftest*
+
+fi
+
+echo $ac_n "checking if changeword is wanted""... $ac_c" 1>&4
+# Check whether --enable-changeword or --disable-changeword was given.
+enableval="$enable_changeword"
+if test -n "$enableval"; then
+ if test "$enableval" = yes; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define ENABLE_CHANGEWORD 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+
+echo $ac_n "checking if malloc debugging is wanted""... $ac_c" 1>&4
+# Check whether --with-dmalloc or --without-dmalloc was given.
+withval="$with_dmalloc"
+if test -n "$withval"; then
+ if test "$withval" = yes; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define WITH_DMALLOC 1
+EOF
+
+ LIBS="$LIBS -ldmalloc"
+ LDFLAGS="$LDFLAGS -g"
+else
+ echo "$ac_t""no" 1>&4
+fi
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+
+trap '' 1 2 15
+if test -w $cache_file; then
+echo "updating cache $cache_file"
+cat > $cache_file <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# Ultrix sh set writes to stderr and can't be redirected directly.
+(set) 2>&1 |
+ sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/: \${\1='\2'}/p" \
+ >> $cache_file
+else
+echo "not updating unwritable cache $cache_file"
+fi
+
+trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#!/bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.1"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr Makefile doc/Makefile lib/Makefile src/Makefile \
+checks/Makefile examples/Makefile config.h conftest*; exit 1' 1 2 15
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@PRODUCT@%$PRODUCT%g
+s%@VERSION@%$VERSION%g
+s%@AWK@%$AWK%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@RANLIB@%$RANLIB%g
+s%@CPP@%$CPP%g
+s%@U@%$U%g
+s%@ANSI2KNR@%$ANSI2KNR%g
+s%@ALLOCA@%$ALLOCA%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@STACKOVF@%$STACKOVF%g
+
+CEOF
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile doc/Makefile lib/Makefile src/Makefile \
+checks/Makefile examples/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust relative srcdir, etc. for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/$ac_dir"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
+fi; done
+rm -f conftest.subs
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+CONFIG_HEADERS=${CONFIG_HEADERS-"config.h"}
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ cp $ac_given_srcdir/$ac_file_in conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+# Maximum number of lines to put in a single here document.
+ac_max_here_lines=12
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+
+test -z "$CONFIG_HEADERS" || date > stamp-h
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 00000000..4db026fa
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,88 @@
+# Configure template for GNU m4.
+# Copyright (C) 1991, 1993, 1994 Free Software Foundation, Inc.
+# Process this file with autoconf to produce a configure script.
+
+undefine([changeword])
+
+AC_INIT(src/m4.c)
+AC_CONFIG_HEADER(config.h)
+AC_ARG_PROGRAM
+
+PRODUCT=m4
+VERSION=1.4
+AC_DEFINE_UNQUOTED(PRODUCT, "$PRODUCT")
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
+AC_SUBST(PRODUCT)
+AC_SUBST(VERSION)
+
+AC_PROG_AWK
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_MAKE_SET
+AC_PROG_RANLIB
+
+AC_AIX
+AC_ISC_POSIX
+AC_MINIX
+fp_C_PROTOTYPES
+AC_C_CONST
+
+AC_CHECK_HEADERS(limits.h memory.h siginfo.h string.h unistd.h)
+AC_HEADER_STDC
+AC_TYPE_SIGNAL
+AC_TYPE_SIZE_T
+
+AC_CHECK_FUNCS(mkstemp sigaction sigaltstack sigstack sigvec strerror tmpfile)
+AC_FUNC_ALLOCA
+AC_FUNC_VPRINTF
+AC_REPLACE_FUNCS(strtol)
+AC_MSG_CHECKING(ecvt declaration)
+AC_EGREP_HEADER(ecvt, stdlib.h,
+ [AC_MSG_RESULT(yes); AC_DEFINE(HAVE_EFGCVT, 2)],
+ [AC_MSG_RESULT(no); AC_CHECK_FUNCS(ecvt)])
+
+AC_MSG_CHECKING(if stack overflow is detectable)
+# 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
+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_TRY_LINK([#include <sys/time.h>
+#include <sys/resource.h>
+#include <signal.h>],
+ [struct rlimit r; int i; 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],
+ use_stackovf=yes)
+ fi
+fi
+AC_MSG_RESULT($use_stackovf)
+if test "$use_stackovf" = yes; then
+ AC_DEFINE(USE_STACKOVF)
+ STACKOVF=stackovf.${U}o
+ AC_SUBST(STACKOVF)
+ AC_EGREP_HEADER(rlim_t, sys/resource.h, , AC_DEFINE(rlim_t, int))
+ AC_EGREP_HEADER(stack_t, signal.h, , AC_DEFINE(stack_t, struct sigaltstack))
+ AC_EGREP_HEADER(sigcontext, signal.h, AC_DEFINE(HAVE_SIGCONTEXT))
+fi
+
+AC_MSG_CHECKING(if changeword is wanted)
+AC_ARG_ENABLE(changeword,
+[ --enable-changeword enable -W and changeword() builtin],
+[if test "$enableval" = yes; then
+ AC_MSG_RESULT(yes)
+ AC_DEFINE(ENABLE_CHANGEWORD)
+else
+ AC_MSG_RESULT(no)
+fi], [AC_MSG_RESULT(no)])
+
+fp_WITH_DMALLOC
+
+AC_OUTPUT(Makefile doc/Makefile lib/Makefile src/Makefile \
+checks/Makefile examples/Makefile,
+[test -z "$CONFIG_HEADERS" || date > stamp-h])
diff --git a/doc/Makefile.am b/doc/Makefile.am
new file mode 100644
index 00000000..ff3bdaf9
--- /dev/null
+++ b/doc/Makefile.am
@@ -0,0 +1 @@
+info_TEXINFOS = m4.texinfo
diff --git a/doc/Makefile.in b/doc/Makefile.in
new file mode 100644
index 00000000..d0e15763
--- /dev/null
+++ b/doc/Makefile.in
@@ -0,0 +1,92 @@
+# Makefile for GNU m4 documentation.
+# Copyright (C) 1994 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 2, 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, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+PRODUCT = @PRODUCT@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MAKEINFO = makeinfo
+TEXI2DVI = texi2dvi
+
+prefix = @prefix@
+infodir = $(prefix)/info
+
+.SUFFIXES:
+
+DISTFILES = Makefile.in m4.texinfo texinfo.tex \
+stamp-vti version.texi m4.info m4.info-1 m4.info-2 m4.info-3
+
+all: m4.info
+
+info: m4.info
+
+m4.info: m4.texinfo version.texi
+ cd $(srcdir) && $(MAKEINFO) m4.texinfo
+
+dvi: m4.dvi
+
+m4.dvi: m4.texinfo version.texi
+ $(TEXI2DVI) $(srcdir)/m4.texinfo
+
+version.texi: stamp-vti
+stamp-vti: m4.texinfo ../configure.in
+ echo "@set EDITION $(VERSION)" > version.tmp
+ echo "@set UPDATED `date '+%B %Y'`" >> version.tmp
+ echo "@set VERSION $(VERSION)" >> version.tmp
+ if cmp -s version.tmp $(srcdir)/version.texi; then rm version.tmp; \
+ else mv version.tmp $(srcdir)/version.texi; fi
+ date > $(srcdir)/stamp-vti
+
+install: all
+ $(srcdir)/../mkinstalldirs $(infodir)
+ cd $(srcdir) && for file in m4.info*; do \
+ $(INSTALL_DATA) $$file $(infodir)/$$file; \
+ done
+
+uninstall:
+ rm -f $(infodir)/m4.info*
+
+mostlyclean:
+ rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.log *.pg *.toc *.tp *.vr
+ rm -f *.tmp
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile
+
+realclean: distclean
+ rm -f stamp-vti version.texi m4.info*
+
+dist: $(DISTFILES)
+ @echo "Copying distribution files"
+ @for file in $(DISTFILES); do \
+ ln $(srcdir)/$$file ../$(PRODUCT)-$(VERSION)/doc 2> /dev/null \
+ || cp -p $(srcdir)/$$file ../$(PRODUCT)-$(VERSION)/doc; \
+ done
+
+Makefile: ../config.status Makefile.in
+ cd .. && CONFIG_FILES=doc/$@ CONFIG_HEADERS= ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/doc/helptoman.pl b/doc/helptoman.pl
new file mode 100644
index 00000000..f0039978
--- /dev/null
+++ b/doc/helptoman.pl
@@ -0,0 +1,249 @@
+#!/usr/bin/perl -w
+
+# Generate a short man page from --help and --version output.
+# Copyright 1997, 98 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 2, 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+require 5.003;
+
+use strict;
+use Getopt::Long;
+use POSIX 'strftime';
+
+my $RCS_Id = '$Id$';
+my $this_program = 'help2man';
+my $this_version = '0.0';
+
+if ($RCS_Id =~ /\$Id:\s+(\S+)\s+(\S+)/)
+{
+ $this_version = $2;
+ ($this_program = $1) =~ s/(\.pl)?,v$//;
+}
+
+my $version_info = <<EOT;
+$this_program $this_version
+
+Copyright (C) 1997, 98 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.
+EOT
+
+my $help_info = <<EOT;
+`$this_program' generates a man page out of `--help' and `--version' output.
+
+Usage: $this_program [OPTION]... EXECUTABLE
+
+ --name=STRING use `STRING' as the description for the NAME paragraph
+ --help print this help, then exit
+ --version print $this_program program version number, then exit
+
+EXECUTABLE should accept `--help' and `version' options.
+EOT
+
+my ($name, $opt_help, $opt_version);
+
+# Parse options.
+GetOptions (
+ 'name=s' => \$name,
+ help => \$opt_help,
+ version => \$opt_version,
+) or die $help_info;
+
+print $help_info and exit if $opt_help;
+print $version_info and exit if $opt_version;
+
+die $help_info unless @ARGV == 1;
+
+# Turn off localisation of executable's ouput.
+@ENV{qw(LANGUAGE LANG LC_ALL)} = qw(C C C);
+
+# Grab help and version paragraphs from executable
+my @help = split /\n\n+/, `$ARGV[0] --help 2>/dev/null`
+ or die "$this_program: can't get `--help' info from $ARGV[0]\n";
+
+my @version = split /\n\n+/, `$ARGV[0] --version 2>/dev/null`
+ or die "$this_program: can't get `--version' info from $ARGV[0]\n";
+
+my $date = strftime "%B %Y", localtime;
+my $program = $ARGV[0]; $program =~ s!.*/!!;
+my $package = $program;
+my $version;
+
+# The first line of the --version information is assumed to be in one
+# of the following formats:
+#
+# <version>
+# <program> <version>
+# GNU <program> <version>
+# <program> (GNU <package>) <version>
+# <program> - GNU <package> <version>
+#
+
+$_ = shift @version;
+
+if (/^(\S+)\s+\((GNU\s+[^)]+)\)\s+(.*)/ ||
+ /^(\S+)\s+-\s*(GNU\s+\S+)\s+(.*)/)
+{
+ $program = $1;
+ $package = $2;
+ $version = $3;
+}
+elsif (/^(GNU\s+)?(\S+)\s+(.*)/)
+{
+ $program = $2;
+ $package = $1 ? "$1$2" : $2;
+ $version = $3;
+}
+else
+{
+ $version = $_;
+}
+
+# Default description for NAME paragraph
+$name ||= "short documentation for $program $version";
+
+# Man pages traditionally have the page title in caps.
+my $PROGRAM = uc $program;
+
+# Header.
+print <<EOT;
+.\" DO NOT MODIFY THIS FILE! It was generated by $this_program $this_version.
+.TH $PROGRAM 1 "$date" "$package $version" "GNU User's Manual"
+.SH NAME
+$program \\- $name
+EOT
+
+my $accumulate = 1;
+my @description = ();
+
+sub convert_option;
+
+# Output converted --help information.
+for (@help)
+{
+ chomp;
+
+ if (s/^Usage:\s+\S+\s+(.*)\n?//)
+ {
+ # Turn the usage clause into a synopsis.
+ print ".SH SYNOPSIS\n.B $program\n";
+
+ my $syn = $1;
+ $syn =~ s/(([][]|\.\.+)+)/\\fR$1\\fI/g;
+ s/^/\\fI/ unless $syn =~ s/^\\fR//;
+
+ print "$syn\\fR\n";
+
+ # Dump any accumulated description text.
+ $accumulate = 0;
+ print ".SH DESCRITION\n";
+ print @description;
+
+ next unless $_;
+ }
+
+ # Accumulate text if the synopsis has not been produced yet.
+ if ($accumulate)
+ {
+ push @description, ".PP\n" if @description;
+ push @description, "$_\n";
+ next;
+ }
+
+ # Catch bug report text.
+ if (/^Report bugs /)
+ {
+ print ".SH BUGS\n$_\n";
+ next;
+ }
+
+ # Special case for tar 1.12: --label=NAME\nPATTERN.
+ s{(\n[ \t]*)(-V,[ \t]+--label=NAME.*)\n[ \t]+PATTERN[ \t]+}
+ {$1$2$1\\&...=PATTERN };
+
+ # Convert options.
+ s/(\s)(-[][\w=-]+|\\&\S+)/$1.convert_option $2/ge;
+
+ # Option subsections have second line indented.
+ print qq(.SS "$1"\n) if s/^(\S.*)\n(\s)/$2/;
+
+ # Lines indented more than about 10 spaces may be assumed to be
+ # continuations of the previous line.
+ s/\n {10,}/ /g;
+
+ # Indented paragraph.
+ if (/^\s/)
+ {
+ for (split /\n/)
+ {
+ s/^\s+//;
+ s/([^,])\s+/$1\n/;
+ print ".TP\n$_\n";
+ }
+ }
+ # Anything else.
+ else
+ {
+ print ".PP\n$_\n";
+ }
+}
+
+# Refer to the real documentation.
+
+print <<EOT;
+.SH SEE ALSO
+The full documentation for
+.B $program
+is maintained as a Texinfo manual. If the
+.B info
+and
+.B $program
+programs are properly installed at your site, the command
+.IP
+.B info $program
+.PP
+should allow you to access the manual as an hypertext.
+EOT
+
+# Output converted --version information.
+for (@version)
+{
+ chomp;
+
+ if (/^Copyright\s+\(C/) { print ".SH COPYRIGHT\n" }
+ elsif (/^Written\s+by/) { print ".SH AUTHOR\n" }
+ else { print ".PP\n"; }
+
+ print "$_\n";
+}
+
+exit;
+
+# Convert option dashes to \- to stop nroff from hyphenating 'em, and
+# embolden. Option arguments get italicised.
+sub convert_option
+{
+ my $option = '\fB' . shift;
+
+ $option =~ s/-/\\-/g;
+ unless ($option =~ s/\[=(.*)\]$/\\fR[=\\fI$1\\fR]/)
+ {
+ $option =~ s/=(.)/\\fR=\\fI$1/;
+ $option .= '\fR';
+ }
+
+ $option;
+}
diff --git a/doc/m4.1 b/doc/m4.1
new file mode 100644
index 00000000..beb6a584
--- /dev/null
+++ b/doc/m4.1
@@ -0,0 +1,121 @@
+." DO NOT MODIFY THIS FILE! It was generated by helptoman 1.1.1.1.
+.TH M4 1 "October 1998" "GNU m4 1.4h" "GNU User's Manual"
+.SH NAME
+m4 \- short documentation for m4 1.4h
+.SH SYNOPSIS
+.B m4
+[\fIOPTION\fR]...\fI \fR[\fIFILE\fR]...\fI\fR
+.SH DESCRITION
+.PP
+Mandatory or optional arguments to long options are mandatory or optional
+for short options too.
+.SS "Operation modes:"
+.TP
+\fB\-\-help\fR
+display this help and exit
+.TP
+\fB\-\-version\fR
+output version information and exit
+.TP
+\fB\-e\fR, \fB\-\-interactive\fR
+unbuffer output, ignore interrupts
+.TP
+\fB\-E\fR, \fB\-\-fatal\-warnings\fR
+stop execution after first warning
+.TP
+\fB\-Q\fR, \fB\-\-quiet\fR, \fB\-\-silent\fR
+suppress some warnings for builtins
+.TP
+\fB\-P\fR, \fB\-\-prefix\-builtins\fR
+force a `m4_' prefix to all builtins
+.SS "Preprocessor features:"
+.TP
+\fB\-I\fR, \fB\-\-include\fR=\fIDIRECTORY\fR
+search this directory second for includes
+.TP
+\fB\-D\fR, \fB\-\-define=NAME\fR[=\fIVALUE\fR]
+enter NAME has having VALUE, or empty
+.TP
+\fB\-U\fR, \fB\-\-undefine\fR=\fINAME\fR
+delete builtin NAME
+.TP
+\fB\-s\fR, \fB\-\-synclines\fR
+generate `#line NO "FILE"' lines
+.SS "Limits control:"
+.TP
+\fB\-G\fR, \fB\-\-traditional\fR
+suppress all GNU extensions
+.TP
+\fB\-H\fR, \fB\-\-hashsize\fR=\fIPRIME\fR
+set symbol lookup hash table size
+.TP
+\fB\-L\fR, \fB\-\-nesting\-limit\fR=\fINUMBER\fR
+change artificial nesting limit
+.SS "Frozen state files:"
+.TP
+\fB\-F\fR, \fB\-\-freeze\-state\fR=\fIFILE\fR
+produce a frozen state on FILE at end
+.TP
+\fB\-R\fR, \fB\-\-reload\-state\fR=\fIFILE\fR
+reload a frozen state from FILE at start
+.SS "Debugging:"
+.TP
+\fB\-d\fR, \fB\-\-debug\fR=\fI[FLAGS]\fR
+set debug level (no FLAGS implies `aeq')
+.TP
+\fB\-t\fR, \fB\-\-trace\fR=\fINAME\fR
+trace NAME when it will be defined
+.TP
+\fB\-l\fR, \fB\-\-arglength\fR=\fINUM\fR
+restrict macro tracing size
+.TP
+\fB\-o\fR, \fB\-\-error\-output\fR=\fIFILE\fR
+redirect debug and trace output
+.SS "FLAGS is any of:"
+.TP
+t
+trace for all macro calls, not only traceon'ed
+.TP
+a
+show actual arguments
+.TP
+e
+show expansion
+.TP
+q
+quote values as necessary, with a or e flag
+.TP
+c
+show before collect, after collect and after call
+.TP
+x
+add a unique macro call id, useful with c flag
+.TP
+f
+say current input file name
+.TP
+l
+say current input line number
+.TP
+p
+show results of path searches
+.TP
+i
+show changes in input files
+.TP
+V
+shorthand for all of the above flags
+.PP
+If no FILE or if FILE is `-', standard input is read.
+.SH SEE ALSO
+The full documentation for
+.B m4
+is maintained as a Texinfo manual. If the
+.B info
+and
+.B m4
+programs are properly installed at your site, the command
+.IP
+.B info m4
+.PP
+should allow you to access the manual as an hypertext.
diff --git a/doc/m4.info b/doc/m4.info
new file mode 100644
index 00000000..d3db9c3e
--- /dev/null
+++ b/doc/m4.info
@@ -0,0 +1,112 @@
+This is Info file m4.info, produced by Makeinfo-1.55 from the input
+file m4.texinfo.
+
+START-INFO-DIR-ENTRY
+* m4: (m4). A powerful macro processor.
+END-INFO-DIR-ENTRY
+
+ This file documents the GNU `m4' utility.
+
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994 Free Software
+Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+Indirect:
+m4.info-1: 959
+m4.info-2: 50733
+m4.info-3: 97497
+
+Tag Table:
+(Indirect)
+Node: Top959
+Node: Preliminaries6959
+Node: Intro7684
+Node: History9292
+Node: Invoking m410213
+Node: Bugs17007
+Node: Manual18275
+Node: Syntax19641
+Node: Names20228
+Node: Quoted strings20602
+Node: Other tokens21186
+Node: Comments21403
+Node: Macros22065
+Node: Invocation22558
+Node: Inhibiting Invocation23369
+Node: Macro Arguments26514
+Node: Quoting Arguments27778
+Node: Macro expansion28583
+Node: Definitions29246
+Node: Define30023
+Node: Arguments30834
+Node: Pseudo Arguments32315
+Node: Undefine34166
+Node: Defn34828
+Node: Pushdef35985
+Node: Indir37821
+Node: Builtin38583
+Node: Conditionals39027
+Node: Ifdef39734
+Node: Ifelse40503
+Node: Loops42269
+Node: Debugging45542
+Node: Dumpdef46121
+Node: Trace46969
+Node: Debug Levels48348
+Node: Debug Output50733
+Node: Input Control51253
+Node: Dnl51790
+Node: Changequote52916
+Node: Changecom54280
+Node: Changeword55564
+Node: M4wrap58767
+Node: File Inclusion59969
+Node: Include60285
+Node: Search Path62213
+Node: Diversions63000
+Node: Divert64237
+Node: Undivert65369
+Node: Divnum67304
+Node: Cleardiv67849
+Node: Text handling68885
+Node: Len69605
+Node: Index70003
+Node: Regexp70588
+Node: Substr71679
+Node: Translit72299
+Node: Patsubst73742
+Node: Format75833
+Node: Arithmetic77322
+Node: Incr77767
+Node: Eval78271
+Node: UNIX commands81270
+Node: Syscmd81741
+Node: Esyscmd82454
+Node: Sysval83400
+Node: Maketemp83807
+Node: Miscellaneous84864
+Node: Errprint85233
+Node: M4exit86224
+Node: Frozen files87010
+Node: Compatibility91906
+Node: Extensions92524
+Node: Incompatibilities94892
+Node: Other Incompat95334
+Node: Concept index97497
+Node: Macro index104371
+
+End Tag Table
diff --git a/doc/m4.info-1 b/doc/m4.info-1
new file mode 100644
index 00000000..d829eb0a
--- /dev/null
+++ b/doc/m4.info-1
@@ -0,0 +1,1495 @@
+This is Info file m4.info, produced by Makeinfo-1.55 from the input
+file m4.texinfo.
+
+START-INFO-DIR-ENTRY
+* m4: (m4). A powerful macro processor.
+END-INFO-DIR-ENTRY
+
+ This file documents the GNU `m4' utility.
+
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994 Free Software
+Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: m4.info, Node: Top, Next: Preliminaries, Prev: (dir), Up: (dir)
+
+GNU `m4'
+********
+
+ GNU `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). `m4' also has builtin functions for including files, running
+shell commands, doing arithmetic, etc. Autoconf needs GNU `m4' for
+generating `configure' scripts, but not for running them.
+
+ GNU `m4' was originally written by Ren'e Seindal, with subsequent
+changes by Franc,ois Pinard and other volunteers on the Internet. All
+names and email addresses can be found in the file `THANKS' from the
+GNU `m4' distribution.
+
+ This is release 1.4. It is now to be considered stable, future
+releases are only meant to fix bugs, increase speed, or improve
+documentation. However...
+
+ An experimental feature, which would improve `m4' usefulness, allows
+for changing the syntax for what is a "word" in `m4'. You should use:
+ ./configure --enable-changeword
+
+if you want this feature compiled in. The current implementation slows
+down `m4' considerably and is hardly acceptable. So, it might go away,
+do not count on it yet.
+
+* Menu:
+
+* Preliminaries:: Introduction and preliminaries
+* Syntax:: Lexical and syntactic conventions
+
+* Macros:: How to invoke macros
+* Definitions:: How to define new macros
+* Conditionals:: Conditionals and loops
+
+* Debugging:: How to debug macros and input
+
+* Input Control:: Input control
+* File Inclusion:: File inclusion
+* Diversions:: Diverting and undiverting output
+
+* Text handling:: Macros for text handling
+* Arithmetic:: Macros for doing arithmetic
+* UNIX commands:: Macros for running UNIX commands
+* Miscellaneous:: Miscellaneous builtin macros
+* Frozen files:: Fast loading of frozen states
+
+* Compatibility:: Compatibility with other versions of m4
+* Concept index:: Index for many concepts
+* Macro index:: Index for all m4 macros
+
+ -- The Detailed Node Listing --
+
+Introduction and preliminaries
+
+* Intro:: Introduction to `m4'
+* History:: Historical references
+
+* Invoking m4:: Invoking `m4'
+* Bugs:: Problems and bugs
+* Manual:: Using this manual
+
+Lexical and syntactic conventions
+
+* Names:: Macro names
+* Quoted strings:: Quoting input to m4
+* Other tokens:: Other kinds of input tokens
+* Comments:: Comments in m4 input
+
+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:: Pseudo arguments to macros
+* Undefine:: Deleting a macro
+* Defn:: Renaming macros
+* Pushdef:: Temporarily redefining macros
+
+* Indir:: Indirect call of macros
+* Builtin:: Indirect call of builtins
+
+Conditionals, loops and recursion
+
+* Ifdef:: Testing if a macro is defined
+* Ifelse:: If-else construct, or multibranch
+* Loops:: Loops and recursion in m4
+
+How to debug macros and input
+
+* Dumpdef:: Displaying macro definitions
+* Trace:: Tracing macro calls
+* Debug Levels:: Controlling debugging output
+* Debug Output:: Saving debugging output
+
+Input control
+
+* Dnl:: Deleting whitespace in input
+* Changequote:: Changing the quote characters
+* Changecom:: Changing the comment delimiters
+* Changeword:: Changing the lexical structure of words
+* M4wrap:: Saving input 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
+* Cleardiv:: Discarding diverted text
+
+Macros for text handling
+
+* Len:: Calculating length of strings
+* Index:: 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
+
+Running UNIX commands
+
+* Syscmd:: Executing simple commands
+* Esyscmd:: Reading the output of commands
+* Sysval:: Exit codes
+* Maketemp:: Making names for temporary files
+
+Miscellaneous builtin macros
+
+* Errprint:: Printing error messages
+* M4exit:: Exiting from m4
+
+Compatibility with other versions of `m4'
+
+* Extensions:: Extensions in GNU m4
+* Incompatibilities:: Facilities in System V m4 not in GNU m4
+* Other Incompat:: Other incompatibilities
+
+
+File: m4.info, Node: Preliminaries, Next: Syntax, Prev: Top, Up: Top
+
+Introduction and preliminaries
+******************************
+
+ This first chapter explains what is GNU `m4', where `m4' comes from,
+how to read and use this documentation, how to call the `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 `m4'
+language.
+
+* Menu:
+
+* Intro:: Introduction to `m4'
+* History:: Historical references
+* Invoking m4:: Invoking `m4'
+* Bugs:: Problems and bugs
+* Manual:: Using this manual
+
+
+File: m4.info, Node: Intro, Next: History, Prev: Preliminaries, Up: Preliminaries
+
+Introduction to `m4'
+====================
+
+ `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.
+
+ 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'. GNU `m4' is mostly
+compatible with the System V, Release 3 version, except for some minor
+differences. *Note Compatibility:: for more details.
+
+ 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.
+
+
+File: m4.info, Node: History, Next: Invoking m4, Prev: Intro, Up: Preliminaries
+
+Historical references
+=====================
+
+ The historical notes included here are fairly incomplete, and not
+authoritative at all. Please knowledgeable users help us to more
+properly write this section.
+
+ `GPM' has been an important ancestor of `m4'. See C. Stratchey: "A
+General Purpose Macro generator", Computer Journal 8,3 (1965), pp. 225
+ff. `GPM' is also succintly described into David Gries classic
+"Compiler Construction for Digital Computers".
+
+ While `GPM' was *pure*, `m4' was meant to deal more with the true
+intricacies of real life: macros could be recognized with being
+pre-announced, skipping whitespace or end-of-lines was made easier,
+more constructs were builtin instead of derived, etc.
+
+ Originally, `m4' was the engine for Rational FORTRAN preprocessor,
+that is, the `ratfor' equivalent of `cpp'.
+
+
+File: m4.info, Node: Invoking m4, Next: Bugs, Prev: History, Up: Preliminaries
+
+Invoking `m4'
+=============
+
+ The format of the `m4' command is:
+
+ `m4' [OPTION...] [MACRO-DEFINITIONS...] [INPUT-FILE...]
+
+ All options begin with `-', or if long option names are used, with a
+`--'. A long option name need not be written completely, and
+unambigous prefix is sufficient. `m4' understands the following
+options:
+
+`--version'
+ Print the version number of the program on standard output, then
+ immediately exit `m4' without reading any INPUT-FILES.
+
+`--help'
+ Print an help summary on standard output, then immediately exit
+ `m4' without reading any INPUT-FILES.
+
+`-G'
+`--traditional'
+ Suppress all the extensions made in this implementation, compared
+ to the System V version. *Note Compatibility::, for a list of
+ these.
+
+`-E'
+`--fatal-warnings'
+ Stop execution and exit `m4' once the first warning has been
+ issued, considering all of them to be fatal.
+
+`-dFLAGS'
+`--debug=FLAGS'
+ Set the debug-level according to the flags FLAGS. The debug-level
+ controls the format and amount of information presented by the
+ debugging functions. *Note Debug Levels:: for more details on the
+ format and meaning of FLAGS.
+
+`-lNUM'
+`--arglength=NUM'
+ Restrict the size of the output generated by macro tracing. *Note
+ Debug Levels:: for more details.
+
+`-oFILE'
+`--error-output=FILE'
+ Redirect debug and trace output to the named file. Error messages
+ are still printed on the standard error output. *Note Debug
+ Output:: for more details.
+
+`-IDIR'
+`--include=DIR'
+ Make `m4' search DIR for included files that are not found in the
+ current working directory. *Note Search Path:: for more details.
+
+`-e'
+`--interactive'
+ Makes this invocation of `m4' interactive. This means that all
+ output will be unbuffered, and interrupts will be ignored.
+
+`-s'
+`--synclines'
+ Generate synchronisation lines, for use by the C preprocessor or
+ other similar tools. This is useful, for example, when `m4' is
+ used as a front end to a compiler. Source file name and line
+ number information is conveyed by directives of the form `#line
+ LINENUM "FILENAME"', which are inserted as needed into the middle
+ of the input. Such directives mean that the following line
+ originated or was expanded from the contents of input file
+ FILENAME at line LINENUM. The `"FILENAME"' part is often omitted
+ when the file name did not change from the previous directive.
+
+ Synchronisation directives are always given on complete lines per
+ themselves. When a synchronisation discrepancy occurs in the
+ middle of an output line, the associated synchronisation directive
+ is delayed until the beginning of the next generated line.
+
+`-P'
+`--prefix-builtins'
+ Internally modify *all* builtin macro names so they all start with
+ the prefix `m4_'. For example, using this option, one should write
+ `m4_define' instead of `define', and `m4___file__' instead of
+ `__file__'.
+
+`-WREGEXP'
+`--word-regexp=REGEXP'
+ Use an alternative syntax for macro names. This experimental
+ option might not be present on all GNU `m4' implementations.
+ (*note Changeword::.).
+
+`-HN'
+`--hashsize=N'
+ Make the internal hash table for symbol lookup be N entries big.
+ The number should be prime. The default is 509 entries. It
+ should not be necessary to increase this value, unless you define
+ an excessive number of macros.
+
+`-LN'
+`--nesting-limit=N'
+ Artificially limit the nesting of macro calls to N levels,
+ stopping program execution if this limit is ever exceeded. When
+ not specified, nesting is limited to 250 levels.
+
+ The precise effect of this option might be more correctly
+ associated with textual nesting than dynamic recursion. It has
+ been useful when some complex `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.
+
+ This option does *not* have the ability to break endless
+ rescanning loops, while these do not necessarily consume much
+ memory or stack space. Through clever usage of rescanning loops,
+ one can request complex, time-consuming computations to `m4' with
+ useful results. Putting limitations in this area would break `m4'
+ power. There are many pathological cases: `define(`a', `a')a' is
+ only the simplest example (but *note Compatibility::.). Expecting
+ GNU `m4' to detect these would be a little like expecting a
+ compiler system to detect and diagnose endless loops: it is a
+ quite *hard* problem in general, if not undecidable!
+
+`-Q'
+`--quiet'
+`--silent'
+ Suppress warnings about missing or superflous arguments in macro
+ calls.
+
+`-B'
+`-S'
+`-T'
+ These options are present for compatibility with System V `m4', but
+ do nothing in this implementation.
+
+`-NN'
+`--diversions=N'
+ These options are present only for compatibility with previous
+ versions of GNU `m4', and were controlling the number of possible
+ diversions which could be used at the same time. They do nothing,
+ because there is no fixed limit anymore.
+
+ Macro definitions and deletions can be made on the command line, by
+using the `-D' and `-U' options. They have the following format:
+
+`-DNAME'
+`-DNAME=VALUE'
+`--define=NAME'
+`--define=NAME=VALUE'
+ This enters NAME into the symbol table, before any input files are
+ read. If `=VALUE' is missing, the value is taken to be the empty
+ string. The VALUE can be any string, and the macro can be defined
+ to take arguments, just as if it was defined from within the input.
+
+`-UNAME'
+`--undefine=NAME'
+ This deletes any predefined meaning NAME might have. Obviously,
+ only predefined macros can be deleted in this way.
+
+`-tNAME'
+`--trace=NAME'
+ This enters NAME into the symbol table, as undefined but traced.
+ The macro will consequently be traced from the point it is defined.
+
+`-FFILE'
+`--freeze-state FILE'
+ Once execution is finished, write out the frozen state on the
+ specified FILE (*note Frozen files::.).
+
+`-RFILE'
+`--reload-state FILE'
+ Before execution starts, recover the internal state from the
+ specified frozen FILE (*note Frozen files::.).
+
+ The remaining arguments on the command line are taken to be input
+file names. If no names are present, the standard input is read. A
+file name of `-' is taken to mean the standard input.
+
+ The input files are read in the sequence given. The standard input
+can only be read once, so the filename `-' should only appear once on
+the command line.
+
+
+File: m4.info, Node: Bugs, Next: Manual, Prev: Invoking m4, Up: Preliminaries
+
+Problems and bugs
+=================
+
+ 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 `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 (Internet)
+`bug-gnu-utils@prep.ai.mit.edu' or (UUCP)
+`mit-eddie!prep.ai.mit.edu!bug-gnu-utils'. Please include the version
+number of `m4' you are using. You can get this information with the
+command `m4 --version'.
+
+ 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.
+
+
+File: m4.info, Node: Manual, Prev: Bugs, Up: Preliminaries
+
+Using this manual
+=================
+
+ This manual contains a number of examples of `m4' input and output,
+and a simple notation is used to distinguish input, output and error
+messages from `m4'. Examples are set out from the normal text, and
+shown in a fixed width font, like this
+
+ This is an example of an example!
+
+ To distinguish input from output, all output from `m4' is prefixed
+by the string `=>', and all error messages by the string `error-->'.
+Thus
+
+ Example of input line
+ =>Output line from m4
+ error-->and an error message
+
+ As each of the predefined macros in `m4' is described, a prototype
+call of the macro will be shown, giving descriptive names to the
+arguments, e.g.,
+
+ regexp(STRING, REGEXP, opt REPLACEMENT)
+
+ All macro arguments in `m4' are strings, but some are given special
+interpretation, e.g., as numbers, filenames, regular expressions, etc.
+
+ The `opt' before the third argument shows that this argument is
+optional--if it is left out, it is taken to be the empty string. An
+ellipsis (`...') last in the argument list indicates that any number of
+arguments may follow.
+
+ This document consistently writes and uses "builtin", without an
+hyphen, as if it were an English word. This is how the `builtin'
+primitive is spelled within `m4'.
+
+
+File: m4.info, Node: Syntax, Next: Macros, Prev: Preliminaries, Up: Top
+
+Lexical and syntactic conventions
+*********************************
+
+ As `m4' reads its input, it separates it into "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 `m4' can also contain
+comments.
+
+* Menu:
+
+* Names:: Macro names
+* Quoted strings:: Quoting input to m4
+* Other tokens:: Other kinds of input tokens
+* Comments:: Comments in m4 input
+
+
+File: m4.info, Node: Names, Next: Quoted strings, Prev: Syntax, Up: Syntax
+
+Names
+=====
+
+ A name is any sequence of letters, digits, and the character `_'
+(underscore), where the first character is not a digit. If a name has
+a macro definition, it will be subject to macro expansion (*note
+Macros::.).
+
+ Examples of legal names are: `foo', `_tmp', and `name01'.
+
+
+File: m4.info, Node: Quoted strings, Next: Other tokens, Prev: Names, Up: Syntax
+
+Quoted strings
+==============
+
+ A quoted string is a sequence of characters surrounded by the quotes
+``' and `'', where the number of start and end quotes within the string
+balances. The value of a string token is the text, with one level of
+quotes stripped off. Thus
+
+ `'
+
+ is the empty string, and
+
+ ``quoted''
+
+ is the string
+
+ `quoted'
+
+ The quote characters can be changed at any time, using the builtin
+macro `changequote'. *Note Changequote:: for more information.
+
+
+File: m4.info, Node: Other tokens, Next: Comments, Prev: Quoted strings, Up: Syntax
+
+Other tokens
+============
+
+ Any character, that is neither a part of a name, nor of a quoted
+string, is a token by itself.
+
+
+File: m4.info, Node: Comments, Prev: Other tokens, Up: Syntax
+
+Comments
+========
+
+ Comments in `m4' are normally delimited by the characters `#' and
+newline. All characters between the comment delimiters are ignored,
+but the entire comment (including the delimiters) is passed through to
+the output--comments are *not* discarded by `m4'.
+
+ Comments cannot be nested, so the first newline after a `#' ends the
+comment. The commenting effect of the begin comment character can be
+inhibited by quoting it.
+
+ The comment delimiters can be changed to any string at any time,
+using the builtin macro `changecom'. *Note Changecom:: for more
+information.
+
+
+File: m4.info, Node: Macros, Next: Definitions, Prev: Syntax, Up: Top
+
+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
+
+
+File: m4.info, Node: Invocation, Next: Inhibiting Invocation, Prev: Macros, Up: Macros
+
+Macro invocation
+================
+
+ Macro invocations has one of the forms
+
+ name
+
+which is a macro invocation without any arguments, or
+
+ name(arg1, arg2, ..., argN)
+
+which is a macro invocation with 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 *must* follow the 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 *must* be
+left out. The macro call
+
+ name()
+
+is a macro call with one argument, which is the empty string, not a call
+with no arguments.
+
+
+File: m4.info, Node: Inhibiting Invocation, Next: Macro Arguments, Prev: Invocation, Up: Macros
+
+Preventing macro invocation
+===========================
+
+ An innovation of the `m4' language, compared to some of its
+predecessors (like Stratchey's `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
+`m4' offers several mechanisms or techniques for inhibiting the
+recognition of names as macro calls.
+
+ First of all, many builtin macros cannot meaningfully be called
+without arguments. 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
+`include' or `eval'. Later in this document, the sentence "This macro
+is recognized only when given arguments" refers to this specific
+provision.
+
+ There is also a command call option (`--prefix-builtins', or `-P')
+which requires all builtin macro names to be prefixed by `m4_' for them
+to be recognized. The option has no effect whatsoever on user defined
+macros. For example, with this option, one has to write `m4_dnl' and
+even `m4_m4exit'.
+
+ If your version of GNU `m4' has the `changeword' feature compiled
+in, there it offers far more flexibility in specifying the syntax of
+macro names, both builtin or user-defined. *Note Changeword:: for more
+information on this experimental feature.
+
+ Of course, the simplest way to prevent a name to be 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. It is also
+possible to quote the empty string, but this works only *inside* the
+name. For example:
+
+ `divert'
+ `d'ivert
+ di`ver't
+ div`'ert
+
+all yield the string `divert'. While in both:
+
+ `'divert
+ divert`'
+
+the `divert' builtin macro will be called.
+
+ The output of macro evaluations is always rescanned. The following
+example would yield the string `de', exactly as if `m4' has been given
+`substr(abcde, 3, 2)' as input:
+
+ define(`x', `substr(ab')
+ define(`y', `cde, 3, 2)')
+ x`'y
+
+ 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 `dnl' macro to be recognized as such:
+
+ define(`macro', `di$1')
+ macro(v)`'dnl
+
+Without the quotes, this would rather yield the string `divdnl'
+followed by an end of line.
+
+ Quoting may prevent recognizing as a macro name the concatenation of
+a macro expansion with the surrounding characters. In this example:
+
+ define(`macro', `di$1')
+ macro(v)`ert'
+
+the input will produce the string `divert'. If the quote was removed,
+the `divert' builtin would be called instead.
+
+
+File: m4.info, Node: Macro Arguments, Next: Quoting Arguments, Prev: Inhibiting Invocation, Up: Macros
+
+Macro arguments
+===============
+
+ 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. If
+there are too many arguments, the excess arguments are ignored.
+
+ Normally `m4' will issue warnings if a builtin macro is called with
+an inappropriate number of arguments, but it can be suppressed with the
+`-Q' command line option. For user defined macros, there is no check
+of the number of arguments given.
+
+ 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 FOO
+expands to `, b, c', the macro call
+
+ bar(a foo, d)
+
+ is a macro call with four arguments, which are `a ', `b', `c' and
+`d'. To understand why the first argument contains whitespace,
+remember that leading unquoted whitespace is never part of an argument,
+but trailing whitespace always is.
+
+
+File: m4.info, Node: Quoting Arguments, Next: Macro expansion, Prev: Macro Arguments, Up: Macros
+
+Quoting macro arguments
+=======================
+
+ Each argument has leading unquoted whitespace removed. Within each
+argument, all unquoted parentheses must match. For example, if FOO is
+a macro,
+
+ foo(() (`(') `(')
+
+ is a macro call, with one argument, whose value is `() (() ('.
+
+ 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:
+
+ foo(`() (() (')
+
+ It is, however, in certain cases necessary 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.
+
+
+File: m4.info, Node: Macro expansion, Prev: Quoting Arguments, Up: Macros
+
+Macro expansion
+===============
+
+ 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 FOO expands to `bar', and BAR
+expands to `Hello world', the input
+
+ foo
+
+will expand first to `bar', and when this is reread and expanded, into
+`Hello world'.
+
+
+File: m4.info, Node: Definitions, Next: Conditionals, Prev: Macros, Up: Top
+
+How to define 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, which can be brought back at a later time.
+
+* Menu:
+
+* Define:: Defining a new macro
+* Arguments:: Arguments to macros
+* Pseudo Arguments:: Pseudo arguments to macros
+* Undefine:: Deleting a macro
+* Defn:: Renaming macros
+* Pushdef:: Temporarily redefining macros
+
+* Indir:: Indirect call of macros
+* Builtin:: Indirect call of builtins
+
+
+File: m4.info, Node: Define, Next: Arguments, Prev: Definitions, Up: Definitions
+
+Defining a macro
+================
+
+ The normal way to define or redefine macros is to use the builtin
+`define':
+
+ define(NAME [, EXPANSION])
+
+which defines NAME to expand to EXPANSION. If EXPANSION is not given,
+it is taken to be empty.
+
+ The expansion of `define' is void.
+
+ The following example defines the macro FOO to expand to the text
+`Hello World.'.
+
+ define(`foo', `Hello world.')
+ =>
+ foo
+ =>Hello world.
+
+ 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 `dnl'. *Note Dnl::,
+for details.
+
+ The macro `define' is recognized only with parameters.
+
+
+File: m4.info, Node: Arguments, Next: Pseudo Arguments, Prev: Define, Up: Definitions
+
+Arguments to macros
+===================
+
+ Macros can have arguments. The Nth argument is denoted by `$n' in
+the expansion text, and is replaced by the Nth actual argument, when
+the macro is expanded. Here is a example of a macro with two
+arguments. It simply exchanges the order of the two arguments.
+
+ define(`exch', `$2, $1')
+ =>
+ exch(arg1, arg2)
+ =>arg2, arg1
+
+ This can be used, for example, if you like the arguments to `define'
+to be reversed.
+
+ define(`exch', `$2, $1')
+ =>
+ define(exch(``expansion text'', ``macro''))
+ =>
+ macro
+ =>expansion text
+
+ *Note Quoting Arguments::, for an explanation of the double quotes.
+
+ GNU `m4' allows the number following the `$' to consist of one or
+more digits, allowing macros to have any number of arguments. This is
+not so in UNIX implementations of `m4', which only recognize one digit.
+
+ As a special case, the zero'th argument, `$0', is always the name of
+the macro being expanded.
+
+ define(`test', ``Macro name: $0'')
+ =>
+ test
+ =>Macro name: test
+
+ If you want quoted text to appear as part of the expansion text,
+remember that quotes can be nested in quoted strings. Thus, in
+
+ define(`foo', `This is macro `foo'.')
+ =>
+ foo
+ =>This is macro foo.
+
+The `foo' in the expansion text is *not* expanded, since it is a quoted
+string, and not a name.
+
+
+File: m4.info, Node: Pseudo Arguments, Next: Undefine, Prev: Arguments, Up: Definitions
+
+Special arguments to macros
+===========================
+
+ 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 `$#' in
+the expansion text. Thus, a macro to display the number of arguments
+given can be
+
+ define(`nargs', `$#')
+ =>
+ nargs
+ =>0
+ nargs()
+ =>1
+ nargs(arg1, arg2, arg3)
+ =>3
+
+ The notation `$*' can be used in the expansion text to denote all
+the actual arguments, unquoted, with commas in between. For example
+
+ define(`echo', `$*')
+ =>
+ echo(arg1, arg2, arg3 , arg4)
+ =>arg1,arg2,arg3 ,arg4
+
+ Often each argument should be quoted, and the notation `$@' handles
+that. It is just like `$*', except that it quotes each argument. A
+simple example of that is:
+
+ define(`echo', `$@')
+ =>
+ echo(arg1, arg2, arg3 , arg4)
+ =>arg1,arg2,arg3 ,arg4
+
+ Where did the quotes go? Of course, they were eaten, when the
+expanded text were reread by `m4'. To show the difference, try
+
+ define(`echo1', `$*')
+ =>
+ define(`echo2', `$@')
+ =>
+ define(`foo', `This is macro `foo'.')
+ =>
+ echo1(foo)
+ =>This is macro This is macro foo..
+ echo2(foo)
+ =>This is macro foo.
+
+*Note Trace::, if you do not understand this.
+
+ A `$' sign in the expansion text, that is not followed by anything
+`m4' understands, is simply copied to the macro expansion, as any other
+text is.
+
+ define(`foo', `$$$ hello $$$')
+ =>
+ foo
+ =>$$$ hello $$$
+
+ If you want a macro to expand to something like `$12', put a pair of
+quotes after the `$'. This will prevent `m4' from interpreting the `$'
+sign as a reference to an argument.
+
+
+File: m4.info, Node: Undefine, Next: Defn, Prev: Pseudo Arguments, Up: Definitions
+
+Deleting a macro
+================
+
+ A macro definition can be removed with `undefine':
+
+ undefine(NAME)
+
+which removes the macro NAME. The macro name must necessarily be
+quoted, since it will be expanded otherwise.
+
+ The expansion of `undefine' is void.
+
+ foo
+ =>foo
+ define(`foo', `expansion text')
+ =>
+ foo
+ =>expansion text
+ undefine(`foo')
+ =>
+ foo
+ =>foo
+
+ It is not an error for NAME to have no macro definition. In that
+case, `undefine' does nothing.
+
+ The macro `undefine' is recognized only with parameters.
+
+
+File: m4.info, Node: Defn, Next: Pushdef, Prev: Undefine, Up: Definitions
+
+Renaming macros
+===============
+
+ It is possible to rename an already defined macro. To do this, you
+need the builtin `defn':
+
+ defn(NAME)
+
+which expands to the *quoted definition* of NAME. If the argument is
+not a defined macro, the expansion is void.
+
+ If NAME is a user-defined macro, the quoted definition is simply the
+quoted expansion text. If, instead, NAME is a builtin, the expansion
+is a special token, which points to the builtin's internal definition.
+This token is only meaningful as the second argument to `define' (and
+`pushdef'), and is ignored in any other context.
+
+ Its normal use is best understood through an example, which shows
+how to rename `undefine' to `zap':
+
+ define(`zap', defn(`undefine'))
+ =>
+ zap(`undefine')
+ =>
+ undefine(`zap')
+ =>undefine(zap)
+
+ In this way, `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 macro `defn' is recognized only with parameters.
+
+
+File: m4.info, Node: Pushdef, Next: Indir, Prev: Defn, Up: Definitions
+
+Temporarily redefining macros
+=============================
+
+ It is possible to redefine a macro temporarily, reverting to the
+previous definition at a later time. This is done with the builtins
+`pushdef' and `popdef':
+
+ pushdef(NAME [, EXPANSION])
+ popdef(NAME)
+
+which are quite analogous to `define' and `undefine'.
+
+ These macros work in a stack-like fashion. A macro is temporarily
+redefined with `pushdef', which replaces an existing definition of
+NAME, while saving the previous definition, before the new one is
+installed. If there is no previous definition, `pushdef' behaves
+exactly like `define'.
+
+ If a macro has several definitions (of which only one is accessible),
+the topmost definition can be removed with `popdef'. If there is no
+previous definition, `popdef' behaves like `undefine'.
+
+ define(`foo', `Expansion one.')
+ =>
+ foo
+ =>Expansion one.
+ pushdef(`foo', `Expansion two.')
+ =>
+ foo
+ =>Expansion two.
+ popdef(`foo')
+ =>
+ foo
+ =>Expansion one.
+ popdef(`foo')
+ =>
+ foo
+ =>foo
+
+ If a macro with several definitions is redefined with `define', the
+topmost definition is *replaced* with the new definition. If it is
+removed with `undefine', *all* the definitions are removed, and not
+only the topmost one.
+
+ define(`foo', `Expansion one.')
+ =>
+ foo
+ =>Expansion one.
+ pushdef(`foo', `Expansion two.')
+ =>
+ foo
+ =>Expansion two.
+ define(`foo', `Second expansion two.')
+ =>
+ foo
+ =>Second expansion two.
+ undefine(`foo')
+ =>
+ foo
+ =>foo
+
+ It is possible to temporarily redefine a builtin with `pushdef' and
+`defn'.
+
+ The macros `pushdef' and `popdef' are recognized only with
+parameters.
+
+
+File: m4.info, Node: Indir, Next: Builtin, Prev: Pushdef, Up: Definitions
+
+Indirect call of macros
+=======================
+
+ Any macro can be called indirectly with `indir':
+
+ indir(NAME, ...)
+
+which results in a call to the macro NAME, which is passed the rest of
+the arguments. This can be used to call macros with "illegal" names
+(`define' allows such names to be defined):
+
+ define(`$$internal$macro', `Internal macro (name `$0')')
+ =>
+ $$internal$macro
+ =>$$internal$macro
+ indir(`$$internal$macro')
+ =>Internal macro (name $$internal$macro)
+
+ The point is, here, that larger macro packages can have private
+macros defined, that will not be called by accident. They can *only* be
+called through the builtin `indir'.
+
+
+File: m4.info, Node: Builtin, Prev: Indir, Up: Definitions
+
+Indirect call of builtins
+=========================
+
+ Builtin macros can be called indirectly with `builtin':
+
+ builtin(NAME, ...)
+
+which results in a call to the builtin NAME, which is passed the rest
+of the arguments. This can be used, if NAME has been given another
+definition that has covered the original.
+
+ The macro `builtin' is recognized only with parameters.
+
+
+File: m4.info, Node: Conditionals, Next: Debugging, Prev: Definitions, Up: Top
+
+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. E.g., 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
+* Loops:: Loops and recursion in m4
+
+
+File: m4.info, Node: Ifdef, Next: Ifelse, Prev: Conditionals, Up: Conditionals
+
+Testing macro definitions
+=========================
+
+ There are two different builtin conditionals in `m4'. The first is
+`ifdef':
+
+ ifdef(NAME, STRING-1, opt STRING-2)
+
+which makes it possible to test whether a macro is defined or not. If
+NAME is defined as a macro, `ifdef' expands to STRING-1, otherwise to
+STRING-2. If STRING-2 is omitted, it is taken to be the empty string
+(according to the normal rules).
+
+ ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+ =>foo is not defined
+ define(`foo', `')
+ =>
+ ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+ =>foo is defined
+
+ The macro `ifdef' is recognized only with parameters.
+
+
+File: m4.info, Node: Ifelse, Next: Loops, Prev: Ifdef, Up: Conditionals
+
+Comparing strings
+=================
+
+ The other conditional, `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:
+
+ ifelse(COMMENT)
+ ifelse(STRING-1, STRING-2, EQUAL, opt NOT-EQUAL)
+ ifelse(STRING-1, STRING-2, EQUAL, ...)
+
+Used with only one argument, the `ifelse' simply discards it and
+produces no output. This is a common `m4' idiom for introducing a
+block comment, as an alternative to repeatedly using `dnl'. This
+special usage is recognized by GNU `m4', so that in this case, the
+warning about missing arguments is never triggered.
+
+ If called with three or four arguments, `ifelse' expands into EQUAL,
+if STRING-1 and STRING-2 are equal (character for character), otherwise
+it expands to NOT-EQUAL.
+
+ ifelse(foo, bar, `true')
+ =>
+ ifelse(foo, foo, `true')
+ =>true
+ ifelse(foo, bar, `true', `false')
+ =>false
+ ifelse(foo, foo, `true', `false')
+ =>true
+
+ However, `ifelse' can take more than four arguments. If given more
+than four arguments, `ifelse' works like a `case' or `switch' statement
+in traditional programming languages. If STRING-1 and STRING-2 are
+equal, `ifelse' expands into EQUAL, otherwise the procedure is repeated
+with the first three arguments discarded. This calls for an example:
+
+ ifelse(foo, bar, `third', gnu, gnats, `sixth', `seventh')
+ =>seventh
+
+ Naturally, the normal case will be slightly more advanced than these
+examples. A common use of `ifelse' is in macros implementing loops of
+various kinds.
+
+ The macro `ifelse' is recognized only with parameters.
+
+
+File: m4.info, Node: Loops, Prev: Ifelse, Up: Conditionals
+
+Loops and recursion
+===================
+
+ There is no direct support for loops in `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.
+
+ Loops can be programmed using recursion and the conditionals
+described previously.
+
+ There is a builtin macro, `shift', which can, among other things, be
+used for iterating through the actual arguments to a macro:
+
+ shift(...)
+
+It takes any number of arguments, and expands to all but the first
+argument, separated by commas, with each argument quoted.
+
+ shift(bar)
+ =>
+ shift(foo, bar, baz)
+ =>bar,baz
+
+ An example of the use of `shift' is this macro, which reverses the
+order of its arguments:
+
+ define(`reverse', `ifelse($#, 0, , $#, 1, ``$1'',
+ `reverse(shift($@)), `$1'')')
+ =>
+ reverse
+ =>
+ reverse(foo)
+ =>foo
+ reverse(foo, bar, gnats, and gnus)
+ =>and gnus, gnats, bar, foo
+
+ While not a very interesting macro, it does show how simple loops
+can be made with `shift', `ifelse' and recursion.
+
+ Here is an example of a loop macro that implements a simple forloop.
+It can, for example, be used for simple counting:
+
+ forloop(`i', 1, 8, `i ')
+ =>1 2 3 4 5 6 7 8
+
+ The arguments are a name for the iteration variable, the starting
+value, the final value, and the text to be expanded for each iteration.
+With this macro, the macro `i' is defined only within the loop. After
+the loop, it retains whatever value it might have had before.
+
+ For-loops can be nested, like
+
+ forloop(`i', 1, 4, `forloop(`j', 1, 8, `(i, j) ')
+ ')
+ =>(1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (1, 6) (1, 7) (1, 8)
+ =>(2, 1) (2, 2) (2, 3) (2, 4) (2, 5) (2, 6) (2, 7) (2, 8)
+ =>(3, 1) (3, 2) (3, 3) (3, 4) (3, 5) (3, 6) (3, 7) (3, 8)
+ =>(4, 1) (4, 2) (4, 3) (4, 4) (4, 5) (4, 6) (4, 7) (4, 8)
+ =>
+
+ The implementation of the `forloop' macro is fairly straightforward.
+The `forloop' macro itself is simply a wrapper, which saves the
+previous definition of the first argument, calls the internal macro
+`_forloop', and re-establishes the saved definition of the first
+argument.
+
+ The macro `_forloop' expands the fourth argument once, and tests to
+see if it is finished. If it has not finished, it increments the
+iteration variable (using the predefined macro `incr', *note Incr::.),
+and recurses.
+
+ Here is the actual implementation of `forloop':
+
+ 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')')')
+
+ Notice the careful use of quotes. Only three macro arguments are
+unquoted, each for its own reason. Try to find out *why* these three
+arguments are left unquoted, and see what happens if they are quoted.
+
+ Now, even though these two macros are useful, they are still not
+robust enough for general use. They lack even basic error handling of
+cases like start value less than final value, and the first argument
+not being a name. Correcting these errors are left as an exercise to
+the reader.
+
+
+File: m4.info, Node: Debugging, Next: Input Control, Prev: Conditionals, Up: Top
+
+How to debug macros and input
+*****************************
+
+ When writing macros for `m4', most of the time they woould not work
+as intended (as is the case with most programming languages). There is
+a little support for macro debugging in `m4'.
+
+* Menu:
+
+* Dumpdef:: Displaying macro definitions
+* Trace:: Tracing macro calls
+* Debug Levels:: Controlling debugging output
+* Debug Output:: Saving debugging output
+
+
+File: m4.info, Node: Dumpdef, Next: Trace, Prev: Debugging, Up: Debugging
+
+Displaying macro definitions
+============================
+
+ If you want to see what a name expands into, you can use the builtin
+`dumpdef':
+
+ dumpdef(...)
+
+which accepts any number of arguments. If called without any arguments,
+it displays the definitions of all known names, otherwise it displays
+the definitions of the names given. The output is printed directly on
+the standard error output.
+
+ The expansion of `dumpdef' is void.
+
+ define(`foo', `Hello world.')
+ =>
+ dumpdef(`foo')
+ error-->foo: `Hello world.'
+ =>
+ dumpdef(`define')
+ error-->define: <define>
+ =>
+
+ The last example shows how builtin macros definitions are displayed.
+
+ *Note Debug Levels:: for information on controlling the details of
+the display.
+
+
+File: m4.info, Node: Trace, Next: Debug Levels, Prev: Dumpdef, Up: Debugging
+
+Tracing macro calls
+===================
+
+ It is possible to trace macro calls and expansions through the
+builtins `traceon' and `traceoff':
+
+ traceon(...)
+ traceoff(...)
+
+When called without any arguments, `traceon' and `traceoff' will turn
+tracing on and off, respectively, for all defined macros. When called
+with arguments, only the named macros are affected.
+
+ The expansion of `traceon' and `traceoff' is void.
+
+ 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 directly on the standard error output.
+
+ define(`foo', `Hello World.')
+ =>
+ define(`echo', `$@')
+ =>
+ traceon(`foo', `echo')
+ =>
+ foo
+ error-->m4trace: -1- foo -> `Hello World.'
+ =>Hello World.
+ echo(gnus, and gnats)
+ error-->m4trace: -1- echo(`gnus', `and gnats') -> ``gnus',`and gnats''
+ =>gnus,and gnats
+
+ 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.
+
+ *Note Debug Levels:: for information on controlling the details of
+the display.
+
+
+File: m4.info, Node: Debug Levels, Next: Debug Output, Prev: Trace, Up: Debugging
+
+Controlling debugging output
+============================
+
+ The `-d' option to `m4' controls the amount of details presented,
+when using the macros described in the preceding sections.
+
+ The FLAGS following the option can be one or more of the following:
+
+`t'
+ Trace all macro calls made in this invocation of `m4'.
+
+`a'
+ Show the actual arguments in each macro call. This applies to all
+ macro calls if the `t' flag is used, otherwise only the macros
+ covered by calls of `traceon'.
+
+`e'
+ Show the expansion of each macro call, if it is not void. This
+ applies to all macro calls if the `t' flag is used, otherwise only
+ the macros covered by calls of `traceon'.
+
+`q'
+ Quote actual arguments and macro expansions in the display with the
+ current quotes.
+
+`c'
+ Show several trace lines for each macro call. A line is shown
+ when the macro is seen, but before the arguments are collected; a
+ second line when the arguments have been collected and a third
+ line after the call has completed.
+
+`x'
+ Add a unique `macro call id' to each line of the trace output.
+ This is useful in connection with the `c' flag above.
+
+`f'
+ Show the name of the current input file in each trace output line.
+
+`l'
+ Show the the current input line number in each trace output line.
+
+`p'
+ Print a message when a named file is found through the path search
+ mecanism (*note Search Path::.), giving the actual filename used.
+
+`i'
+ Print a message each time the current input file is changed,
+ giving file name and input line number.
+
+`V'
+ A shorthand for all of the above flags.
+
+ If no flags are specified with the `-d' option, the default is
+`aeq'. The examples in the previous two sections assumed the default
+flags.
+
+ There is a builtin macro `debugmode', which allows on-the-fly
+control of the debugging output format:
+
+ debugmode(opt FLAGS)
+
+The argument FLAGS should be a subset of the letters listed above. As
+special cases, if the argument starts with a `+', the flags are added
+to the current debug flags, and if it starts with a `-', they are
+removed. If no argument is present, the debugging flags are set to
+zero (as if no `-d' was given), and with an empty argument the flags
+are reset to the default.
+
diff --git a/doc/m4.info-2 b/doc/m4.info-2
new file mode 100644
index 00000000..aedf6a64
--- /dev/null
+++ b/doc/m4.info-2
@@ -0,0 +1,1468 @@
+This is Info file m4.info, produced by Makeinfo-1.55 from the input
+file m4.texinfo.
+
+START-INFO-DIR-ENTRY
+* m4: (m4). A powerful macro processor.
+END-INFO-DIR-ENTRY
+
+ This file documents the GNU `m4' utility.
+
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994 Free Software
+Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: m4.info, Node: Debug Output, Prev: Debug Levels, Up: Debugging
+
+Saving debugging output
+=======================
+
+ Debug and tracing output can be redirected to files using either the
+`-o' option to `m4', or with the builtin macro `debugfile':
+
+ debugfile(opt FILENAME)
+
+will send all further debug and trace output to FILENAME. If FILENAME
+is empty, debug and trace output are discarded and if `debugfile' is
+called without any arguments, debug and trace output are sent to the
+standard error output.
+
+
+File: m4.info, Node: Input Control, Next: File Inclusion, Prev: Debugging, Up: Top
+
+Input control
+*************
+
+ This chapter describes various builtin macros for controlling the
+input to `m4'.
+
+* Menu:
+
+* Dnl:: Deleting whitespace in input
+* Changequote:: Changing the quote characters
+* Changecom:: Changing the comment delimiters
+* Changeword:: Changing the lexical structure of words
+* M4wrap:: Saving input until end of input
+
+
+File: m4.info, Node: Dnl, Next: Changequote, Prev: Input Control, Up: Input Control
+
+Deleting whitespace in input
+============================
+
+ The builtin `dnl' reads and discards all characters, up to and
+including the first newline:
+
+ dnl
+
+and it is often used in connection with `define', to remove the newline
+that follow the call to `define'. Thus
+
+ define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
+ foo
+ =>Macro foo.
+
+ The input up to and including the next newline is discarded, as
+opposed to the way comments are treated (*note Comments::.).
+
+ Usually, `dnl' is immediately followed by an end of line or some
+other whitespace. GNU `m4' will produce a warning diagnostic if `dnl'
+is followed by an open parenthesis. In this case, `dnl' will collect
+and process all arguments, looking for a matching close parenthesis.
+All predictable side effects resulting from this collection will take
+place. `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.
+
+
+File: m4.info, Node: Changequote, Next: Changecom, Prev: Dnl, Up: Input Control
+
+Changing the quote characters
+=============================
+
+ The default quote delimiters can be changed with the builtin
+`changequote':
+
+ changequote(opt START, opt END)
+
+where START is the new start-quote delimiter and END is the new
+end-quote delimiter. If any of the arguments are missing, the default
+quotes (``' and `'') are used instead of the void arguments.
+
+ The expansion of `changequote' is void.
+
+ changequote([, ])
+ =>
+ define([foo], [Macro [foo].])
+ =>
+ foo
+ =>Macro foo.
+
+ If no single character is appropriate, START and END can be of any
+length.
+
+ changequote([[, ]])
+ =>
+ define([[foo]], [[Macro [[[foo]]].]])
+ =>
+ foo
+ =>Macro [foo].
+
+ Changing the quotes to the empty strings will effectively disable the
+quoting mechanism, leaving no way to quote text.
+
+ define(`foo', `Macro `FOO'.')
+ =>
+ changequote(, )
+ =>
+ foo
+ =>Macro `FOO'.
+ `foo'
+ =>`Macro `FOO'.'
+
+ There is no way in `m4' to quote a string containing an unmatched
+left quote, except using `changequote' to change the current quotes.
+
+ Neither quote string should start with a letter or `_' (underscore),
+as they will be confused with names in the input. Doing so disables
+the quoting mechanism.
+
+
+File: m4.info, Node: Changecom, Next: Changeword, Prev: Changequote, Up: Input Control
+
+Changing comment delimiters
+===========================
+
+ The default comment delimiters can be changed with the builtin macro
+`changecom':
+
+ changecom(opt START, opt END)
+
+where START is the new start-comment delimiter and END is the new
+end-comment delimiter. If any of the arguments are void, the default
+comment delimiters (`#' and newline) are used instead of the void
+arguments. The comment delimiters can be of any length.
+
+ The expansion of `changecom' is void.
+
+ define(`comment', `COMMENT')
+ =>
+ # A normal comment
+ =># A normal comment
+ changecom(`/*', `*/')
+ =>
+ # Not a comment anymore
+ =># Not a COMMENT anymore
+ But: /* this is a comment now */ while this is not a comment
+ =>But: /* this is a comment now */ while this is not a COMMENT
+
+ 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 start comment delimiter.
+
+ Calling `changecom' without any arguments disables the commenting
+mechanism completely.
+
+ define(`comment', `COMMENT')
+ =>
+ changecom
+ =>
+ # Not a comment anymore
+ =># Not a COMMENT anymore
+
+
+File: m4.info, Node: Changeword, Next: M4wrap, Prev: Changecom, Up: Input Control
+
+Changing the lexical structure of words
+=======================================
+
+ The macro `changeword' and all associated functionnality is
+ experimental. It is only available if the `--enable-changeword'
+ option was given to `configure', at GNU `m4' installation time.
+ The functionnality might change or even go away in the future.
+ *Do not rely on it*. Please direct your comments about it the
+ same way you would do for bugs.
+
+ A file being processed by `m4' is split into quoted strings, words
+(potential macro names) and simple tokens (any other single character).
+Initially a word is defined by the following regular expression:
+
+ [_a-zA-Z][_a-zA-Z0-9]*
+
+ Using `changeword', you can change this regular expression. Relaxing
+`m4''s lexical rules might be useful (for example) if you wanted to
+apply translations to a file of numbers:
+
+ changeword(`[_a-zA-Z0-9]+')
+ define(1, 0)
+ =>1
+
+ Tightening the lexical rules is less useful, because it will
+generally make some of the builtins unavailable. You could use it to
+prevent accidental call of builtins, for example:
+
+ define(`_indir', defn(`indir'))
+ changeword(`_[_a-zA-Z0-9]*')
+ esyscmd(foo)
+ _indir(`esyscmd', `ls')
+
+ Because `m4' constructs its words a character at a time, there is a
+restriction on the regular expressions that may be passed to
+`changeword'. This is that if your regular expression accepts `foo',
+it must also accept `f' and `fo'.
+
+ `changeword' has another function. If the regular expression
+supplied contains any bracketed subexpressions, then text outside the
+first of these is discarded before symbol lookup. So:
+
+ changecom(`/*', `*/')
+ changeword(`#\([_a-zA-Z0-9]*\)')
+ #esyscmd(ls)
+
+ `m4' now requires a `#' mark at the beginning of every macro
+invocation, so one can use `m4' to preprocess shell scripts without
+getting `shift' commands swallowed, and plain text without losing
+various common words.
+
+ `m4''s macro substitution is based on text, while TeX's is based on
+tokens. `changeword' can throw this difference into relief. For
+example, here is the same idea represented in TeX and `m4'. First, the
+TeX version:
+
+ \def\a{\message{Hello}}
+ \catcode`\@=0
+ \catcode`\\=12
+ =>@a
+ =>@bye
+
+Then, the `m4' version:
+
+ define(a, `errprint(`Hello')')
+ changeword(`@\([_a-zA-Z0-9]*\)')
+ =>@a
+
+ In the TeX example, the first line defines a macro `a' to print the
+message `Hello'. The second line defines @ to be usable instead of \
+as an escape character. The third line defines \ to be a normal
+printing character, not an escape. The fourth line invokes the macro
+`a'. So, when TeX is run on this file, it displays the message `Hello'.
+
+ When the `m4' example is passed through `m4', it outputs
+`errprint(Hello)'. The reason for this is that TeX does lexical
+analysis of macro definition when the macro is *defined*. `m4' just
+stores the text, postponing the lexical analysis until the macro is
+*used*.
+
+ You should note that using `changeword' will slow `m4' down by a
+factor of about seven.
+
+
+File: m4.info, Node: M4wrap, Prev: Changeword, Up: Input Control
+
+Saving input
+============
+
+ 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 `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 `m4wrap':
+
+ m4wrap(STRING, ...)
+
+which stores STRING and the rest of the arguments in a safe place, to
+be reread when end of input is reached.
+
+ define(`cleanup', `This is the `cleanup' actions.
+ ')
+ =>
+ m4wrap(`cleanup')
+ =>
+ This is the first and last normal input line.
+ =>This is the first and last normal input line.
+ ^D
+ =>This is the cleanup actions.
+
+ The saved input is only reread when the end of normal input is seen,
+and not if `m4exit' is used to exit `m4'.
+
+ It is safe to call `m4wrap' from saved text, but then the order in
+which the saved text is reread is undefined. If `m4wrap' is not used
+recursively, the saved pieces of text are reread in the opposite order
+in which they were saved (LIFO--last in, first out).
+
+
+File: m4.info, Node: File Inclusion, Next: Diversions, Prev: Input Control, Up: Top
+
+File inclusion
+**************
+
+ `m4' allows you to include named files at any point in the input.
+
+* Menu:
+
+* Include:: Including named files
+* Search Path:: Searching for include files
+
+
+File: m4.info, Node: Include, Next: Search Path, Prev: File Inclusion, Up: File Inclusion
+
+Including named files
+=====================
+
+ There are two builtin macros in `m4' for including files:
+
+ include(FILENAME)
+ sinclude(FILENAME)
+
+both of which cause the file named FILENAME to be read by `m4'. When
+the end of the file is reached, input is resumed from the previous
+input file.
+
+ The expansion of `include' and `sinclude' is therefore the contents
+of FILENAME.
+
+ It is an error for an `include'd file not to exist. If you do not
+want error messages about non-existent files, `sinclude' can be used to
+include a file, if it exists, expanding to nothing if it does not.
+
+ include(`no-such-file')
+ =>
+ error-->30.include:2: m4: Cannot open no-such-file: No such file or directory
+ sinclude(`no-such-file')
+ =>
+
+ Assume in the following that the file `incl.m4' contains the lines:
+ Include file start
+ foo
+ Include file end
+
+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 `m4' and
+macro calls in the file will be expanded:
+
+ define(`foo', `FOO')
+ =>
+ include(`incl.m4')
+ =>Include file start
+ =>FOO
+ =>Include file end
+ =>
+
+ The fact that `include' and `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 `bar' to expand to the contents of
+`incl.m4':
+
+ define(`bar', include(`incl.m4'))
+ =>
+ This is `bar': >>>bar<<<
+ =>This is bar: >>>Include file start
+ =>foo
+ =>Include file end
+ =><<<
+
+ This use of `include' is not trivial, though, as files can contain
+quotes, commas and parentheses, which can interfere with the way the
+`m4' parser works.
+
+ The builtin macros `include' and `sinclude' are recognized only when
+given arguments.
+
+
+File: m4.info, Node: Search Path, Prev: Include, Up: File Inclusion
+
+Searching for include files
+===========================
+
+ GNU `m4' allows included files to be found in other directories than
+the current working directory.
+
+ If a file is not found in the current working directory, and the file
+name is not absolute, the file will be looked for in a specified search
+path. First, the directories specified with the `-I' option will be
+searched, in the order found on the command line. Second, if the
+`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 `p'
+debug flag (*note Debug Levels::.) can help isolate the problem.
+
+
+File: m4.info, Node: Diversions, Next: Text handling, Prev: File Inclusion, Up: Top
+
+Diverting and undiverting output
+********************************
+
+ Diversions are a way of temporarily saving output. The output of
+`m4' can at any time be diverted to a temporary file, and be reinserted
+into the output stream, "undiverted", again at a later time.
+
+ Numbered diversions are counted from 0 upwards, diversion number 0
+being the normal output stream. The number of simultaneous diversions
+is limited mainly by the memory used to describe them, because GNU `m4'
+tries to keep diversions in memory. However, there is a limit to the
+overall memory usable by all diversions taken altogether (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. So, it is
+theoretically possible that the number of diversions be limited by the
+number of available file descriptors.
+
+* Menu:
+
+* Divert:: Diverting output
+* Undivert:: Undiverting output
+* Divnum:: Diversion numbers
+* Cleardiv:: Discarding diverted text
+
+
+File: m4.info, Node: Divert, Next: Undivert, Prev: Diversions, Up: Diversions
+
+Diverting output
+================
+
+ Output is diverted using `divert':
+
+ divert(opt NUMBER)
+
+where NUMBER is the diversion to be used. If NUMBER is left out, it is
+assumed to be zero.
+
+ The expansion of `divert' is void.
+
+ When all the `m4' input will have been processed, all existing
+diversions are automatically undiverted, in numerical order.
+
+ divert(1)
+ This text is diverted.
+ divert
+ =>
+ This text is not diverted.
+ =>This text is not diverted.
+ ^D
+ =>
+ =>This text is diverted.
+
+ Several calls of `divert' with the same argument do not overwrite
+the previous diverted text, but append to it.
+
+ If output is diverted to a non-existent 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 how to avoid them.
+
+ divert(-1)
+ define(`foo', `Macro `foo'.')
+ define(`bar', `Macro `bar'.')
+ divert
+ =>
+
+ This is a common programming idiom in `m4'.
+
+
+File: m4.info, Node: Undivert, Next: Divnum, Prev: Divert, Up: Diversions
+
+Undiverting output
+==================
+
+ Diverted text can be undiverted explicitly using the builtin
+`undivert':
+
+ undivert(opt NUMBER, ...)
+
+which undiverts the diversions given by the arguments, in the order
+given. If no arguments are supplied, all diversions are undiverted, in
+numerical order.
+
+ The expansion of `undivert' is void.
+
+ divert(1)
+ This text is diverted.
+ divert
+ =>
+ This text is not diverted.
+ =>This text is not diverted.
+ undivert(1)
+ =>
+ =>This text is diverted.
+ =>
+
+ Notice the last two blank lines. One of them comes from the newline
+following `undivert', the other from the newline that followed the
+`divert'! A diversion often starts with a blank line like this.
+
+ When diverted text is undiverted, it is *not* reread by `m4', but
+rather copied directly to the current output, and it is therefore not
+an error to undivert into a diversion.
+
+ When a diversion has been undiverted, the diverted text is discarded,
+and it is not possible to bring back diverted text more than once.
+
+ divert(1)
+ This text is diverted first.
+ divert(0)undivert(1)dnl
+ =>
+ =>This text is diverted first.
+ undivert(1)
+ =>
+ divert(1)
+ This text is also diverted but not appended.
+ divert(0)undivert(1)dnl
+ =>
+ =>This text is also diverted but not appended.
+
+ Attempts to undivert the current diversion are silently ignored.
+
+ GNU `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 `include' (*note
+Include::.). To illustrate the difference, assume the file `foo'
+contains the word `bar':
+
+ define(`bar', `BAR')
+ =>
+ undivert(`foo')
+ =>bar
+ =>
+ include(`foo')
+ =>BAR
+ =>
+
+
+File: m4.info, Node: Divnum, Next: Cleardiv, Prev: Undivert, Up: Diversions
+
+Diversion numbers
+=================
+
+ The builtin `divnum':
+
+ divnum
+
+expands to the number of the current diversion.
+
+ Initial divnum
+ =>Initial 0
+ divert(1)
+ Diversion one: divnum
+ divert(2)
+ Diversion two: divnum
+ divert
+ =>
+ ^D
+ =>
+ =>Diversion one: 1
+ =>
+ =>Diversion two: 2
+
+ The last call of `divert' without argument is necessary, since the
+undiverted text would otherwise be diverted itself.
+
+
+File: m4.info, Node: Cleardiv, Prev: Divnum, Up: Diversions
+
+Discarding diverted text
+========================
+
+ 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 `m4' with `divert(-1)'
+followed by an explicit `undivert':
+
+ divert(1)
+ Diversion one: divnum
+ divert(2)
+ Diversion two: divnum
+ divert(-1)
+ undivert
+ ^D
+
+No output is produced at all.
+
+ Clearing selected diversions can be done with the following macro:
+
+ define(`cleardivert',
+ `pushdef(`_num', divnum)divert(-1)undivert($@)divert(_num)popdef(`_num')')
+ =>
+
+ It is called just like `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.)
+
+
+File: m4.info, Node: Text handling, Next: Arithmetic, Prev: Diversions, Up: Top
+
+Macros for text handling
+************************
+
+ There are a number of builtins in `m4' for manipulating text in
+various ways, extracting substrings, searching, substituting, and so on.
+
+* Menu:
+
+* Len:: Calculating length of strings
+* Index:: 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)
+
+
+File: m4.info, Node: Len, Next: Index, Prev: Text handling, Up: Text handling
+
+Calculating length of strings
+=============================
+
+ The length of a string can be calculated by `len':
+
+ len(STRING)
+
+which expands to the length of STRING, as a decimal number.
+
+ len()
+ =>0
+ len(`abcdef')
+ =>6
+
+ The builtin macro `len' is recognized only when given arguments.
+
+
+File: m4.info, Node: Index, Next: Regexp, Prev: Len, Up: Text handling
+
+Searching for substrings
+========================
+
+ Searching for substrings is done with `index':
+
+ index(STRING, SUBSTRING)
+
+which expands to the index of the first occurrence of SUBSTRING in
+STRING. The first character in STRING has index 0. If SUBSTRING does
+not occur in STRING, `index' expands to `-1'.
+
+ index(`gnus, gnats, and armadillos', `nat')
+ =>7
+ index(`gnus, gnats, and armadillos', `dag')
+ =>-1
+
+ The builtin macro `index' is recognized only when given arguments.
+
+
+File: m4.info, Node: Regexp, Next: Substr, Prev: Index, Up: Text handling
+
+Searching for regular expressions
+=================================
+
+ Searching for regular expressions is done with the builtin `regexp':
+
+ regexp(STRING, REGEXP, opt REPLACEMENT)
+
+which searches for REGEXP in STRING. The syntax for regular
+expressions is the same as in GNU Emacs. *Note Syntax of Regular
+Expressions: (emacs)Regexps.
+
+ If REPLACEMENT is omitted, `regexp' expands to the index of the
+first match of REGEXP in STRING. If REGEXP does not match anywhere in
+STRING, it expands to -1.
+
+ regexp(`GNUs not Unix', `\<[a-z]\w+')
+ =>5
+ regexp(`GNUs not Unix', `\<Q\w*')
+ =>-1
+
+ If REPLACEMENT is supplied, `regexp' changes the expansion to this
+argument, with `\N' substituted by the text matched by the Nth
+parenthesized sub-expression of REGEXP, `\&' being the text the entire
+regular expression matched.
+
+ regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
+ =>*** Unix *** nix ***
+
+ The builtin macro `regexp' is recognized only when given arguments.
+
+
+File: m4.info, Node: Substr, Next: Translit, Prev: Regexp, Up: Text handling
+
+Extracting substrings
+=====================
+
+ Substrings are extracted with `substr':
+
+ substr(STRING, FROM, opt LENGTH)
+
+which expands to the substring of STRING, which starts at index FROM,
+and extends for LENGTH characters, or to the end of STRING, if LENGTH
+is omitted. The starting index of a string is always 0.
+
+ substr(`gnus, gnats, and armadillos', 6)
+ =>gnats, and armadillos
+ substr(`gnus, gnats, and armadillos', 6, 5)
+ =>gnats
+
+ The builtin macro `substr' is recognized only when given arguments.
+
+
+File: m4.info, Node: Translit, Next: Patsubst, Prev: Substr, Up: Text handling
+
+Translating characters
+======================
+
+ Character translation is done with `translit':
+
+ translit(STRING, CHARS, REPLACEMENT)
+
+which expands to STRING, with each character that occurs in CHARS
+translated into the character from REPLACEMENT with the same index.
+
+ If REPLACEMENT is shorter than CHARS, the excess characters are
+deleted from the expansion. If REPLACEMENT is omitted, all characters
+in STRING, that are present in CHARS are deleted from the expansion.
+
+ Both CHARS and REPLACEMENT can contain character-ranges, e.g., `a-z'
+(meaning all lowercase letters) or `0-9' (meaning all digits). To
+include a dash `-' in CHARS or REPLACEMENT, place it first or last.
+
+ 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., `9-0'
+means the string `9876543210'.
+
+ translit(`GNUs not Unix', `A-Z')
+ =>s not nix
+ translit(`GNUs not Unix', `a-z', `A-Z')
+ =>GNUS NOT UNIX
+ translit(`GNUs not Unix', `A-Z', `z-a')
+ =>tmfs not fnix
+
+ 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.
+
+ The builtin macro `translit' is recognized only when given arguments.
+
+
+File: m4.info, Node: Patsubst, Next: Format, Prev: Translit, Up: Text handling
+
+Substituting text by regular expression
+=======================================
+
+ Global substitution in a string is done by `patsubst':
+
+ patsubst(STRING, REGEXP, opt REPLACEMENT)
+
+which searches STRING for matches of REGEXP, and substitutes
+REPLACEMENT for each match. The syntax for regular expressions is the
+same as in GNU Emacs.
+
+ The parts of STRING that are not covered by any match of REGEXP are
+copied to the expansion. Whenever a match is found, the search
+proceeds from the end of the match, so a character from STRING will
+never be substituted twice. If 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, REPLACEMENT is inserted into the
+expansion, with `\N' substituted by the text matched by the Nth
+parenthesized sub-expression of REGEXP, `\&' being the text the entire
+regular expression matched.
+
+ The REPLACEMENT argument can be omitted, in which case the text
+matched by REGEXP is deleted.
+
+ patsubst(`GNUs not Unix', `^', `OBS: ')
+ =>OBS: GNUs not Unix
+ patsubst(`GNUs not Unix', `\<', `OBS: ')
+ =>OBS: GNUs OBS: not OBS: Unix
+ patsubst(`GNUs not Unix', `\w*', `(\&)')
+ =>(GNUs)() (not)() (Unix)
+ patsubst(`GNUs not Unix', `\w+', `(\&)')
+ =>(GNUs) (not) (Unix)
+ patsubst(`GNUs not Unix', `[A-Z][a-z]+')
+ =>GN not
+
+ Here is a slightly more realistic example, which capitalizes
+individual word or whole sentences, by substituting calls of the macros
+`upcase' and `downcase' into the strings.
+
+ define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
+ define(`downcase', `translit(`$*', `A-Z', `a-z')')dnl
+ define(`capitalize1',
+ `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')dnl
+ define(`capitalize',
+ `patsubst(`$1', `\w+', `capitalize1(`\&')')')dnl
+ capitalize(`GNUs not Unix')
+ =>Gnus Not Unix
+
+ The builtin macro `patsubst' is recognized only when given arguments.
+
+
+File: m4.info, Node: Format, Prev: Patsubst, Up: Text handling
+
+Formatted output
+================
+
+ Formatted output can be made with `format':
+
+ format(FORMAT-STRING, ...)
+
+which works much like the C function `printf'. The first argument is a
+format string, which can contain `%' specifications, and the expansion
+of `format' is the formatted string.
+
+ Its use is best described by a few examples:
+
+ define(`foo', `The brown fox jumped over the lazy dog')
+ =>
+ format(`The string "%s" is %d characters long', foo, len(foo))
+ =>The string "The brown fox jumped over the lazy dog" is 38 characters long
+
+ Using the `forloop' macro defined in *Note Loops::, this example
+shows how `format' can be used to produce tabular output.
+
+ forloop(`i', 1, 10, `format(`%6d squared is %10d
+ ', i, eval(i**2))')
+ => 1 squared is 1
+ => 2 squared is 4
+ => 3 squared is 9
+ => 4 squared is 16
+ => 5 squared is 25
+ => 6 squared is 36
+ => 7 squared is 49
+ => 8 squared is 64
+ => 9 squared is 81
+ => 10 squared is 100
+
+ The builtin `format' is modeled after the ANSI C `printf' function,
+and supports the normal `%' specifiers: `c', `s', `d', `o', `x', `X',
+`u', `e', `E' and `f'; it supports field widths and precisions, and the
+modifiers `+', `-', ` ', `0', `#', `h' and `l'. For more details on
+the functioning of `printf', see the C Library Manual.
+
+
+File: m4.info, Node: Arithmetic, Next: UNIX commands, Prev: Text handling, Up: Top
+
+Macros for doing arithmetic
+***************************
+
+ Integer arithmetic is included in `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
+
+
+File: m4.info, Node: Incr, Next: Eval, Prev: Arithmetic, Up: Arithmetic
+
+Decrement and increment operators
+=================================
+
+ Increment and decrement of integers are supported using the builtins
+`incr' and `decr':
+
+ incr(NUMBER)
+ decr(NUMBER)
+
+which expand to the numerical value of NUMBER, incremented, or
+decremented, respectively, by one.
+
+ incr(4)
+ =>5
+ decr(7)
+ =>6
+
+ The builtin macros `incr' and `decr' are recognized only when given
+arguments.
+
+
+File: m4.info, Node: Eval, Prev: Incr, Up: Arithmetic
+
+Evaluating integer expressions
+==============================
+
+ Integer expressions are evaluated with `eval':
+
+ eval(EXPRESSION, opt RADIX, opt WIDTH)
+
+which expands to the value of EXPRESSION.
+
+ Expressions can contain the following operators, listed in order of
+decreasing precedence.
+
+`-'
+ Unary minus
+
+`**'
+ Exponentiation
+
+`* / %'
+ Multiplication, division and modulo
+
+`+ -'
+ Addition and subtraction
+
+`<< >>'
+ Shift left or right
+
+`== != > >= < <='
+ Relational operators
+
+`!'
+ Logical negation
+
+`~'
+ Bitwise negation
+
+`&'
+ Bitwise and
+
+`^'
+ Bitwise exclusive-or
+
+`|'
+ Bitwise or
+
+`&&'
+ Logical and
+
+`||'
+ Logical or
+
+ All operators, except exponentiation, are left associative.
+
+ Note that many `m4' implementations use `^' as an alternate operator
+for the exponentiation, while many others use `^' for the bitwise
+exclusive-or. GNU `m4' changed its behavior: it used to exponentiate
+for `^', it now computes the bitwise exclusive-or.
+
+ Numbers without special prefix are given decimal. A simple `0'
+prefix introduces an octal number. `0x' introduces an hexadecimal
+number. `0b' introduces a binary number. `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 any radix, the digits are `0',
+`1', `2', .... Beyond `9', the digits are `a', `b' ... up to `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 `1', and a false
+relation return `0'.
+
+ Here are a few examples of use of `eval'.
+
+ eval(-3 * 5)
+ =>-15
+ eval(index(`Hello world', `llo') >= 0)
+ =>1
+ define(`square', `eval(($1)**2)')
+ =>
+ square(9)
+ =>81
+ square(square(5)+1)
+ =>676
+ define(`foo', `666')
+ =>
+ eval(`foo'/6)
+ error-->51.eval:14: m4: Bad expression in eval: foo/6
+ =>
+ eval(foo/6)
+ =>111
+
+ As the second to last example shows, `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 `eval'.
+
+ If RADIX is specified, it specifies the radix to be used in the
+expansion. The default radix is 10. The result of `eval' is always
+taken to be signed. The WIDTH argument specifies a minimum output
+width. The result is zero-padded to extend the expansion to the
+requested width.
+
+ eval(666, 10)
+ =>666
+ eval(666, 11)
+ =>556
+ eval(666, 6)
+ =>3030
+ eval(666, 6, 10)
+ =>0000003030
+ eval(-666, 6, 10)
+ =>-000003030
+
+ Take note that RADIX cannot be larger than 36.
+
+ The builtin macro `eval' is recognized only when given arguments.
+
+
+File: m4.info, Node: UNIX commands, Next: Miscellaneous, Prev: Arithmetic, Up: Top
+
+Running UNIX commands
+*********************
+
+ There are a few builtin macros in `m4' that allow you to run UNIX
+commands from within `m4'.
+
+* Menu:
+
+* Syscmd:: Executing simple commands
+* Esyscmd:: Reading the output of commands
+* Sysval:: Exit codes
+* Maketemp:: Making names for temporary files
+
+
+File: m4.info, Node: Syscmd, Next: Esyscmd, Prev: UNIX commands, Up: UNIX commands
+
+Executing simple commands
+=========================
+
+ Any shell command can be executed, using `syscmd':
+
+ syscmd(SHELL-COMMAND)
+
+which executes SHELL-COMMAND as a shell command.
+
+ The expansion of `syscmd' is void, *not* the output from
+SHELL-COMMAND! Output or error messages from SHELL-COMMAND are not
+read by `m4'. *Note Esyscmd:: if you need to process the command
+output.
+
+ Prior to executing the command, `m4' flushes its output buffers.
+The default standard input, output and error of SHELL-COMMAND are the
+same as those of `m4'.
+
+ The builtin macro `syscmd' is recognized only when given arguments.
+
+
+File: m4.info, Node: Esyscmd, Next: Sysval, Prev: Syscmd, Up: UNIX commands
+
+Reading the output of commands
+==============================
+
+ If you want `m4' to read the output of a UNIX command, use `esyscmd':
+
+ esyscmd(SHELL-COMMAND)
+
+which expands to the standard output of the shell command SHELL-COMMAND.
+
+ Prior to executing the command, `m4' flushes its output buffers.
+The default standard input and error output of SHELL-COMMAND are the
+same as those of `m4'. The error output of SHELL-COMMAND is not a part
+of the expansion: it will appear along with the error output of `m4'.
+
+ Assume you are positioned into the `checks' directory of GNU `m4'
+distribution, then:
+
+ define(`vice', `esyscmd(grep Vice ../COPYING)')
+ =>
+ vice
+ => Ty Coon, President of Vice
+ =>
+
+ Note how the expansion of `esyscmd' has a trailing newline.
+
+ The builtin macro `esyscmd' is recognized only when given arguments.
+
+
+File: m4.info, Node: Sysval, Next: Maketemp, Prev: Esyscmd, Up: UNIX commands
+
+Exit codes
+==========
+
+ To see whether a shell command succeeded, use `sysval':
+
+ sysval
+
+which expands to the exit status of the last shell command run with
+`syscmd' or `esyscmd'.
+
+ syscmd(`false')
+ =>
+ ifelse(sysval, 0, zero, non-zero)
+ =>non-zero
+ syscmd(`true')
+ =>
+ sysval
+ =>0
+
+
+File: m4.info, Node: Maketemp, Prev: Sysval, Up: UNIX commands
+
+Making names for temporary files
+================================
+
+ Commands specified to `syscmd' or `esyscmd' might need a temporary
+file, for output or for some other purpose. There is a builtin macro,
+`maketemp', for making temporary file names:
+
+ maketemp(TEMPLATE)
+
+which expands to a name of a non-existent file, made from the string
+TEMPLATE, which should end with the string `XXXXXX'. The six `X''s are
+then replaced, usually with something that includes the process id of
+the `m4' process, in order to make the filename unique.
+
+ maketemp(`/tmp/fooXXXXXX')
+ =>/tmp/fooa07346
+ maketemp(`/tmp/fooXXXXXX')
+ =>/tmp/fooa07346
+
+ As seen in the example, several calls of `maketemp' might expand to
+the same string, since the selection criteria is whether the file exists
+or not. If a file has not been created before the next call, the two
+macro calls might expand to the same name.
+
+ The builtin macro `maketemp' is recognized only when given arguments.
+
+
+File: m4.info, Node: Miscellaneous, Next: Frozen files, Prev: UNIX commands, Up: Top
+
+Miscellaneous builtin macros
+****************************
+
+ This chapter describes various builtins, that do not really belong in
+any of the previous chapters.
+
+* Menu:
+
+* Errprint:: Printing error messages
+* M4exit:: Exiting from m4
+
+
+File: m4.info, Node: Errprint, Next: M4exit, Prev: Miscellaneous, Up: Miscellaneous
+
+Printing error messages
+=======================
+
+ You can print error messages using `errprint':
+
+ errprint(MESSAGE, ...)
+
+which simply prints MESSAGE and the rest of the arguments on the
+standard error output.
+
+ The expansion of `errprint' is void.
+
+ errprint(`Illegal arguments to forloop
+ ')
+ error-->Illegal arguments to forloop
+ =>
+
+ A trailing newline is *not* printed automatically, so it must be
+supplied as part of the argument, as in the example. (BSD flavored
+`m4''s do append a trailing newline on each `errprint' call).
+
+ To make it possible to specify the location of the error, two
+utility builtins exist:
+
+ __file__
+ __line__
+
+which expands to the quoted name of the current input file, and the
+current input line number in that file.
+
+ errprint(`m4:'__file__:__line__: `Input error
+ ')
+ error-->m4:56.errprint:2: Input error
+ =>
+
+
+File: m4.info, Node: M4exit, Prev: Errprint, Up: Miscellaneous
+
+Exiting from `m4'
+=================
+
+ If you need to exit from `m4' before the entire input has been read,
+you can use `m4exit':
+
+ m4exit(opt CODE)
+
+which causes `m4' to exit, with exit code CODE. If CODE is left out,
+the exit code is zero.
+
+ define(`fatal_error', `errprint(`m4: '__file__: __line__`: fatal error: $*
+ ')m4exit(1)')
+ =>
+ fatal_error(`This is a BAD one, buster')
+ error-->m4: 57.m4exit: 5: fatal error: This is a BAD one, buster
+
+ After this macro call, `m4' will exit with exit code 1. This macro
+is only intended for error exits, since the normal exit procedures are
+not followed, e.g., diverted text is not undiverted, and saved text
+(*note M4wrap::.) is not reread.
+
+
+File: m4.info, Node: Frozen files, Next: Compatibility, Prev: Miscellaneous, Up: Top
+
+Fast loading of frozen states
+*****************************
+
+ Some bigger `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 `m4' invocation prior to the user's
+input file, or else, `include''d from this input file.
+
+ Reading the common base of a big application, over and over again,
+may be time consuming. GNU `m4' offers some machinery to speed up the
+start of an application using lengthy common bases. Presume the user
+repeatedly uses:
+
+ m4 base.m4 input.m4
+
+with a varying contents of `input.m4', but a rather fixed contents for
+`base.m4'. Then, the user might rather execute:
+
+ m4 -F base.m4f base.m4
+
+once, and further execute, as often as needed:
+
+ m4 -R base.m4f input.m4
+
+with the varying input. The first call, containing the `-F' option,
+only reads and executes file `base.m4', so defining various application
+macros and computing other initializations. Only once the input file
+`base.m4' has been completely processed, GNU `m4' produces on
+`base.m4f' a "frozen" file, that is, a file which contains a kind of
+snapshot of the `m4' internal state.
+
+ Later calls, containing the `-R' option, are able to reload the
+internal state of `m4''s memory, from `base.m4f', *prior* to reading
+any other input files. By this mean, instead of starting with a virgin
+copy of `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 `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 `m4'
+invocation. It is not possible to recover two frozen files at once.
+However, frozen files may be updated incrementally, through using `-R'
+and `-F' options simultaneously. For example, if some care is taken,
+the command:
+
+ m4 file1.m4 file2.m4 file3.m4 file4.m4
+
+could be broken down in the following sequence, accumulating the same
+output:
+
+ m4 -F file1.m4f file1.m4
+ m4 -R file1.m4f -F file2.m4f file2.m4
+ m4 -R file2.m4f -F file3.m4f file3.m4
+ m4 -R file3.m4f file4.m4
+
+ Some care is necessary because not every effort has been made for
+this to work in all cases. In particular, the trace attribute of
+macros is not handled, nor the current setting of `changeword'. Also,
+interactions for some options of `m4' being used in one call and not
+for the next, have not been fully analyzed yet. On the other end, you
+may be confident that stacks of `pushdef''ed definitions are handled
+correctly, so are `undefine''d or renamed builtins, changed strings for
+quotes or comments.
+
+ When an `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 `include' file (*note
+Search Path::.).
+
+ Frozen files are sharable across architectures. It is safe to write
+a frozen file one one machine and read it on another, given that the
+second machine uses the same, or a newer version of GNU `m4'. These
+are simple (editable) text files, made up of directives, each starting
+with a capital letter and ending with a newline (NL). Wherever a
+directive is expected, the character `#' introduces a comment line,
+empty lines are also ignored. In the following descriptions, LENGTHs
+always refer to corresponding STRINGs. Numbers are always expressed in
+decimal. The directives are:
+
+`V NUMBER NL'
+ Confirms the format of the file. NUMBER should be 1.
+
+`C LENGTH1 , LENGTH2 NL STRING1 STRING2 NL'
+ Uses STRING1 and STRING2 as the beginning comment and end comment
+ strings.
+
+`Q LENGTH1 , LENGTH2 NL STRING1 STRING2 NL'
+ Uses STRING1 and STRING2 as the beginning quote and end quote
+ strings.
+
+`F LENGTH1 , LENGTH2 NL STRING1 STRING2 NL'
+ Defines, through `pushdef', a definition for STRING1 expanding to
+ the function whose builtin name is STRING2.
+
+`T LENGTH1 , LENGTH2 NL STRING1 STRING2 NL'
+ Defines, though `pushdef', a definition for STRING1 expanding to
+ the text given by STRING2.
+
+`D NUMBER, LENGTH NL STRING NL'
+ Selects diversion NUMBER, making it current, then copy STRING in
+ the current diversion. NUMBER may be a negative number for a
+ non-existing diversion. To merely specify an active selection,
+ use this command with an empty STRING. With 0 as the diversion
+ NUMBER, STRING will be issued on standard output at reload time,
+ however this may not be produced from within `m4'.
+
+
+File: m4.info, Node: Compatibility, Next: Concept index, Prev: Frozen files, Up: Top
+
+Compatibility with other versions of `m4'
+*****************************************
+
+ This chapter describes the differences between this implementation of
+`m4', and the implementation found under UNIX, notably System V,
+Release 3.
+
+ There are also differences in BSD flavors of `m4'. No attempt is
+made to summarize these here.
+
+* Menu:
+
+* Extensions:: Extensions in GNU m4
+* Incompatibilities:: Facilities in System V m4 not in GNU m4
+* Other Incompat:: Other incompatibilities
+
+
+File: m4.info, Node: Extensions, Next: Incompatibilities, Prev: Compatibility, Up: Compatibility
+
+Extensions in GNU `m4'
+======================
+
+ This version of `m4' contains a few facilities, that do not exist in
+System V `m4'. These extra facilities are all suppressed by using the
+`-G' command line option, unless overridden by other command line
+options.
+
+ * In the `$'N notation for macro arguments, N can contain several
+ digits, while the System V `m4' only accepts one digit. This
+ allows macros in GNU `m4' to take any number of arguments, and not
+ only nine (*note Arguments::.).
+
+ * Files included with `include' and `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 `-I' option and the
+ `M4PATH' environment variable (*note Search Path::.).
+
+ * Arguments to `undivert' can be non-numeric, in which case the named
+ file will be included uninterpreted in the output (*note
+ Undivert::.).
+
+ * Formatted output is supported through the `format' builtin, which
+ is modeled after the C library function `printf' (*note Format::.).
+
+ * Searches and text substitution through regular expressions are
+ supported by the `regexp' (*note Regexp::.) and `patsubst' (*note
+ Patsubst::.) builtins.
+
+ * The output of shell commands can be read into `m4' with `esyscmd'
+ (*note Esyscmd::.).
+
+ * There is indirect access to any builtin macro with `builtin'
+ (*note Builtin::.).
+
+ * Macros can be called indirectly through `indir' (*note Indir::.).
+
+ * The name of the current input file and the current input line
+ number are accessible through the builtins `__file__' and
+ `__line__' (*note Errprint::.).
+
+ * The format of the output from `dumpdef' and macro tracing can be
+ controlled with `debugmode' (*note Debug Levels::.).
+
+ * The destination of trace and debug output can be controlled with
+ `debugfile' (*note Debug Output::.).
+
+ In addition to the above extensions, GNU `m4' implements the
+following command line options: `-F', `-G', `-I', `-L', `-R', `-V',
+`-W', `-d', `-l', `-o' and `-t'. *Note Invoking m4::, for a
+description of these options.
+
+ Also, the debugging and tracing facilities in GNU `m4' are much more
+extensive than in most other versions of `m4'.
+
+
+File: m4.info, Node: Incompatibilities, Next: Other Incompat, Prev: Extensions, Up: Compatibility
+
+Facilities in System V `m4' not in GNU `m4'
+===========================================
+
+ The version of `m4' from System V contains a few facilities that
+have not been implemented in GNU `m4' yet.
+
+ * System V `m4' supports multiple arguments to `defn'. This is not
+ implemented in GNU `m4'. Its usefulness is unclear to me.
+
+
+File: m4.info, Node: Other Incompat, Prev: Incompatibilities, Up: Compatibility
+
+Other incompatibilities
+=======================
+
+ There are a few other incompatibilities between this implementation
+of `m4', and the System V version.
+
+ * GNU `m4' implements sync lines differently from System V `m4',
+ when text is being diverted. GNU `m4' outputs the sync lines when
+ the text is being diverted, and System V `m4' when the diverted
+ text is being brought back.
+
+ The problem is which lines and filenames should be attached to
+ text that is being, or has been, diverted. System V `m4' regards
+ all the diverted text as being generated by the source line
+ containing the `undivert' call, whereas GNU `m4' regards the
+ diverted text as being generated at the time it is diverted.
+
+ I expect the sync line option to be used mostly when using `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 were made, and not where it was inserted again.
+
+ * GNU `m4' makes no attempt at prohiting autoreferential definitions
+ like:
+
+ define(`x', `x')
+ define(`x', `x ')
+
+ There is nothing inherently wrong with defining `x' to return `x'.
+ The wrong thing is to expand `x' unquoted. In `m4', one might
+ use macros to hold strings, as we do for variables in other
+ programming languages, further checking them with:
+
+ ifelse(defn(`HOLDER'), `VALUE', ...)
+
+ In cases like this one, an interdiction for a macro to hold its own
+ name would be a useless limitation. Of course, this leave more
+ rope for the GNU `m4' user to hang himself! Rescanning hangs may
+ be avoided through careful programming, a little like for endless
+ loops in traditional programming languages.
+
+ * GNU `m4' without `-G' option will define the macro `__gnu__' to
+ expand to the empty string.
+
+ On UNIX systems, GNU `m4' without the `-G' option will define the
+ macro `__unix__', otherwise the macro `unix'. Both will expand to
+ the empty string.
+
diff --git a/doc/m4.info-3 b/doc/m4.info-3
new file mode 100644
index 00000000..c21385ea
--- /dev/null
+++ b/doc/m4.info-3
@@ -0,0 +1,227 @@
+This is Info file m4.info, produced by Makeinfo-1.55 from the input
+file m4.texinfo.
+
+START-INFO-DIR-ENTRY
+* m4: (m4). A powerful macro processor.
+END-INFO-DIR-ENTRY
+
+ This file documents the GNU `m4' utility.
+
+ Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994 Free Software
+Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: m4.info, Node: Concept index, Next: Macro index, Prev: Compatibility, Up: Top
+
+Concept index
+*************
+
+* Menu:
+
+* Arguments to macros: Arguments.
+* arguments to macros: Macro Arguments.
+* arguments to macros, special: Pseudo Arguments.
+* arguments, quoted macro: Quoting Arguments.
+* arithmetic: Arithmetic.
+* builtins, indirect call of: Builtin.
+* call of builtins, indirect: Builtin.
+* call of macros, indirect: Indir.
+* changing comment delimiters: Changecom.
+* changing the quote delimiters: Changequote.
+* characters, translating: Translit.
+* command line, filenames on the: Invoking m4.
+* command line, macro definitions on the: Invoking m4.
+* command line, options: Invoking m4.
+* commands, exit code from UNIX: Sysval.
+* commands, running UNIX: UNIX commands.
+* comment delimiters, changing: Changecom.
+* comments: Comments.
+* comments, copied to output: Changecom.
+* comparing strings: Ifelse.
+* compatibility: Compatibility.
+* conditionals: Ifdef.
+* controlling debugging output: Debug Levels.
+* counting loops: Loops.
+* debugging output, controlling: Debug Levels.
+* debugging output, saving: Debug Output.
+* decrement operator: Incr.
+* defining new macros: Definitions.
+* definitions, displaying macro: Dumpdef.
+* deleting macros: Undefine.
+* deleting whitespace in input: Dnl.
+* discarding diverted text: Cleardiv.
+* displaying macro definitions: Dumpdef.
+* diversion numbers: Divnum.
+* diverted text, discarding: Cleardiv.
+* diverting output to files: Divert.
+* dumping into frozen file: Frozen files.
+* error messages, printing: Errprint.
+* evaluation, of integer expressions: Eval.
+* executing UNIX commands: UNIX commands.
+* exit code from UNIX commands: Sysval.
+* exiting from m4: M4exit.
+* expansion of macros: Macro expansion.
+* expansion, tracing macro: Trace.
+* expressions, evaluation of integer: Eval.
+* extracting substrings: Substr.
+* fast loading of frozen files: Frozen files.
+* file inclusion: Undivert.
+* file inclusion: File Inclusion.
+* filenames, on the command line: Invoking m4.
+* files, diverting output to: Divert.
+* files, names of temporary: Maketemp.
+* forloops: Loops.
+* formatted output: Format.
+* frozen files for fast loading: Frozen files.
+* GNU extensions: Extensions.
+* GNU extensions: Frozen files.
+* GNU extensions: Esyscmd.
+* GNU extensions: Format.
+* GNU extensions: Patsubst.
+* GNU extensions: Regexp.
+* GNU extensions: Undivert.
+* GNU extensions: Search Path.
+* GNU extensions: Debug Output.
+* GNU extensions: Debug Levels.
+* GNU extensions: Builtin.
+* GNU extensions: Indir.
+* GNU extensions: Arguments.
+* included files, search path for: Search Path.
+* inclusion, of files: Undivert.
+* inclusion, of files: File Inclusion.
+* increment operator: Incr.
+* indirect call of builtins: Builtin.
+* indirect call of macros: Indir.
+* initialization, frozen states: Frozen files.
+* input tokens: Syntax.
+* input, saving: M4wrap.
+* integer arithmetic: Arithmetic.
+* integer expression evaluation: Eval.
+* length of strings: Len.
+* lexical structure of words: Changeword.
+* loops: Loops.
+* loops, counting: Loops.
+* macro definitions, on the command line: Invoking m4.
+* macro expansion, tracing: Trace.
+* macro invocation: Invocation.
+* macros, arguments to: Arguments.
+* macros, arguments to: Macro Arguments.
+* macros, displaying definitions: Dumpdef.
+* macros, expansion of: Macro expansion.
+* macros, how to define new: Definitions.
+* macros, how to delete: Undefine.
+* macros, how to rename: Defn.
+* macros, indirect call of: Indir.
+* macros, quoted arguments to: Quoting Arguments.
+* macros, recursive: Loops.
+* macros, special arguments to: Pseudo Arguments.
+* macros, temporary redefinition of: Pushdef.
+* messages, printing error: Errprint.
+* multibranches: Ifelse.
+* names: Names.
+* options, command line: Invoking m4.
+* output, diverting to files: Divert.
+* output, formatted: Format.
+* output, saving debugging: Debug Output.
+* pattern substitution: Patsubst.
+* printing error messages: Errprint.
+* quote delimiters, changing the: Changequote.
+* quoted macro arguments: Quoting Arguments.
+* quoted string: Quoted strings.
+* recursive macros: Loops.
+* redefinition of macros, temporary: Pushdef.
+* regular expressions: Patsubst.
+* regular expressions: Regexp.
+* reloading a frozen file: Frozen files.
+* renaming macros: Defn.
+* running UNIX commands: UNIX commands.
+* saving debugging output: Debug Output.
+* saving input: M4wrap.
+* search path for included files: Search Path.
+* special arguments to macros: Pseudo Arguments.
+* strings, length of: Len.
+* substitution by regular expression: Patsubst.
+* substrings, extracting: Substr.
+* temporary filenames: Maketemp.
+* temporary redefinition of macros: Pushdef.
+* tokens: Syntax.
+* tracing macro expansion: Trace.
+* translating characters: Translit.
+* undefining macros: Undefine.
+* UNIX commands, exit code from: Sysval.
+* UNIX commands, running: UNIX commands.
+* words, lexical structure of: Changeword.
+
+
+File: m4.info, Node: Macro index, Prev: Concept index, Up: Top
+
+Macro index
+***********
+
+ References are exclusively to the places where a builtin is
+introduced the first time. Names starting and ending with `__' have
+these characters removed in the index.
+
+* Menu:
+
+* builtin: Builtin.
+* changecom: Changecom.
+* changequote: Changequote.
+* changeword: Changeword.
+* debugfile: Debug Output.
+* debugmode: Debug Levels.
+* decr: Incr.
+* define: Define.
+* defn: Defn.
+* divert: Divert.
+* divnum: Divnum.
+* dnl: Dnl.
+* dumpdef: Dumpdef.
+* errprint: Errprint.
+* esyscmd: Esyscmd.
+* eval: Eval.
+* file: Errprint.
+* format: Format.
+* gnu: Other Incompat.
+* ifdef: Ifdef.
+* ifelse: Ifelse.
+* include: Include.
+* incr: Incr.
+* index: Index.
+* indir: Indir.
+* len: Len.
+* line: Errprint.
+* m4exit: M4exit.
+* m4wrap: M4wrap.
+* maketemp: Maketemp.
+* patsubst: Patsubst.
+* popdef: Pushdef.
+* pushdef: Pushdef.
+* regexp: Regexp.
+* shift: Loops.
+* sinclude: Include.
+* substr: Substr.
+* syscmd: Syscmd.
+* sysval: Sysval.
+* traceoff: Trace.
+* traceon: Trace.
+* translit: Translit.
+* undefine: Undefine.
+* undivert: Undivert.
+* unix: Other Incompat.
+
+
diff --git a/doc/m4.texinfo b/doc/m4.texinfo
new file mode 100644
index 00000000..5d3f36bf
--- /dev/null
+++ b/doc/m4.texinfo
@@ -0,0 +1,3415 @@
+\input texinfo
+@c %**start of header
+@setfilename m4.info
+@settitle GNU macro processor
+@finalout
+@c %**end of header
+
+@include version.texi
+
+@ifinfo
+@set Francois Franc,ois
+@end ifinfo
+@tex
+@set Francois Fran\noexpand\ptexc cois
+@end tex
+
+@ifinfo
+@format
+START-INFO-DIR-ENTRY
+* m4: (m4). A powerful macro processor.
+END-INFO-DIR-ENTRY
+@end format
+@end ifinfo
+
+@ifinfo
+This file documents the GNU @code{m4} utility.
+
+Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end ifinfo
+
+@titlepage
+@title GNU m4, version @value{VERSION}
+@subtitle A powerful macro processor
+@subtitle Edition @value{EDITION}, @value{UPDATED}
+@author by Ren@'e Seindal
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1989, 90, 91, 92, 93, 94 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end titlepage
+
+@ifinfo
+@node Top, Preliminaries, (dir), (dir)
+@top GNU @code{m4}
+
+@c @item @b{@code{m4}} @value{hfillkludge} (UtilD, UtilT, SrcCD)
+@c
+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 @value{Francois} Pinard and other volunteers
+on the Internet. All names and email addresses can be found in the
+file @file{THANKS} from the GNU @code{m4} distribution.
+
+This is release @value{VERSION}. It is now to be considered stable,
+future releases are only meant to fix bugs, increase speed, or improve
+documentation. However@dots{}
+
+An experimental feature, which would improve @code{m4} usefulness,
+allows for changing the syntax for what is a @dfn{word} in @code{m4}.
+You should use:
+@comment ignore
+@example
+./configure --enable-changeword
+@end example
+@noindent
+if you want this feature compiled in. The current implementation
+slows down @code{m4} considerably and is hardly acceptable. So, it
+might go away, do not count on it yet.
+
+@menu
+* Preliminaries:: Introduction and preliminaries
+* Syntax:: Lexical and syntactic conventions
+
+* Macros:: How to invoke macros
+* Definitions:: How to define new macros
+* Conditionals:: Conditionals and loops
+
+* Debugging:: How to debug macros and input
+
+* Input Control:: Input control
+* File Inclusion:: File inclusion
+* Diversions:: Diverting and undiverting output
+
+* Text handling:: Macros for text handling
+* Arithmetic:: Macros for doing arithmetic
+* UNIX commands:: Macros for running UNIX commands
+* Miscellaneous:: Miscellaneous builtin macros
+* Frozen files:: Fast loading of frozen states
+
+* Compatibility:: Compatibility with other versions of m4
+* Concept index:: Index for many concepts
+* Macro index:: Index for all m4 macros
+
+ --- The Detailed Node Listing ---
+
+Introduction and preliminaries
+
+* Intro:: Introduction to @code{m4}
+* History:: Historical references
+
+* Invoking m4:: Invoking @code{m4}
+* Bugs:: Problems and bugs
+* Manual:: Using this manual
+
+Lexical and syntactic conventions
+
+* Names:: Macro names
+* Quoted strings:: Quoting input to m4
+* Other tokens:: Other kinds of input tokens
+* Comments:: Comments in m4 input
+
+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:: Pseudo arguments to macros
+* Undefine:: Deleting a macro
+* Defn:: Renaming macros
+* Pushdef:: Temporarily redefining macros
+
+* Indir:: Indirect call of macros
+* Builtin:: Indirect call of builtins
+
+Conditionals, loops and recursion
+
+* Ifdef:: Testing if a macro is defined
+* Ifelse:: If-else construct, or multibranch
+* Loops:: Loops and recursion in m4
+
+How to debug macros and input
+
+* Dumpdef:: Displaying macro definitions
+* Trace:: Tracing macro calls
+* Debug Levels:: Controlling debugging output
+* Debug Output:: Saving debugging output
+
+Input control
+
+* Dnl:: Deleting whitespace in input
+* Changequote:: Changing the quote characters
+* Changecom:: Changing the comment delimiters
+* Changeword:: Changing the lexical structure of words
+* M4wrap:: Saving input 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
+* Cleardiv:: Discarding diverted text
+
+Macros for text handling
+
+* Len:: Calculating length of strings
+* Index:: 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
+
+Running UNIX commands
+
+* Syscmd:: Executing simple commands
+* Esyscmd:: Reading the output of commands
+* Sysval:: Exit codes
+* Maketemp:: Making names for temporary files
+
+Miscellaneous builtin macros
+
+* Errprint:: Printing error messages
+* M4exit:: Exiting from m4
+
+Compatibility with other versions of @code{m4}
+
+* Extensions:: Extensions in GNU m4
+* Incompatibilities:: Facilities in System V m4 not in GNU m4
+* Other Incompat:: Other incompatibilities
+@end menu
+
+@end ifinfo
+
+@node Preliminaries, Syntax, Top, Top
+@chapter Introduction and preliminaries
+
+This first chapter explains what is GNU @code{m4}, 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.
+
+@menu
+* Intro:: Introduction to @code{m4}
+* History:: Historical references
+* Invoking m4:: Invoking @code{m4}
+* Bugs:: Problems and bugs
+* Manual:: Using this manual
+@end menu
+
+@node Intro, History, Preliminaries, Preliminaries
+@section Introduction to @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 UNIX commands, doing integer
+arithmetic, manipulating text in various ways, 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.
+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 @code{m4} for
+@emph{generating} the @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 3 version, except for some minor differences.
+@xref{Compatibility} for more details.
+
+Some people found @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 @code{m4} sets of 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, Invoking m4, Intro, Preliminaries
+@section Historical references
+
+The historical notes included here are fairly incomplete, and not
+authoritative at all. Please knowledgeable users help us to more
+properly write this section.
+
+@code{GPM} has been an important ancestor of @code{m4}. See
+C. Stratchey: ``A General Purpose Macro generator'', Computer Journal
+8,3 (1965), pp. 225 ff. @code{GPM} is also succintly described into
+David Gries classic ``Compiler Construction for Digital Computers''.
+
+While @code{GPM} was @emph{pure}, @code{m4} was meant to deal more
+with the true intricacies of real life: macros could be recognized
+with being pre-announced, skipping whitespace or end-of-lines was
+made easier, more constructs were builtin instead of derived, etc.
+
+Originally, @code{m4} was the engine for Rational FORTRAN preprocessor,
+that is, the @code{ratfor} equivalent of @code{cpp}.
+
+@node Invoking m4, Bugs, History, Preliminaries
+@section Invoking @code{m4}
+
+The format of the @code{m4} command is:
+
+@comment ignore
+@example
+@code{m4} [@var{option}@dots{}] [@var{macro-definitions}@dots{}] [@var{input-file}@dots{}]
+@end example
+
+@cindex command line, options
+@cindex options, command line
+All options begin with @samp{-}, or if long option names are used, with
+a @samp{--}. A long option name need not be written completely, and
+unambigous prefix is sufficient. @code{m4} understands the following
+options:
+
+@table @code
+@item --version
+Print the version number of the program on standard output, then
+immediately exit @code{m4} without reading any @var{input-files}.
+
+@item --help
+Print an help summary on standard output, then immediately exit
+@code{m4} without reading any @var{input-files}.
+
+@item -G
+@itemx --traditional
+Suppress all the extensions made in this implementation, compared to the
+System V version. @xref{Compatibility}, for a list of these.
+
+@item -E
+@itemx --fatal-warnings
+Stop execution and exit @code{m4} once the first warning has been
+issued, considering all of them to be fatal.
+
+@item -d@var{flags}
+@itemx --debug=@var{flags}
+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{Debug Levels} for more details on the format and
+meaning of @var{flags}.
+
+@item -l@var{num}
+@itemx --arglength=@var{num}
+Restrict the size of the output generated by macro tracing. @xref{Debug
+Levels} for more details.
+
+@item -o@var{file}
+@itemx --error-output=@var{file}
+Redirect debug and trace output to the named file. Error messages are
+still printed on the standard error output. @xref{Debug Output} for
+more details.
+
+@item -I@var{dir}
+@itemx --include=@var{dir}
+Make @code{m4} search @var{dir} for included files that are not found in
+the current working directory. @xref{Search Path} for more details.
+
+@item -e
+@itemx --interactive
+Makes this invocation of @code{m4} interactive. This means that all
+output will be unbuffered, and interrupts will be ignored.
+
+@item -s
+@itemx --synclines
+Generate synchronisation lines, for use by the C preprocessor or other
+similar tools. This 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{filename}"}, which are inserted as needed into the middle of the
+input. Such directives mean that the following line originated or was
+expanded from the contents of input file @var{filename} at line
+@var{linenum}. The @samp{"@var{filename}"} part is often omitted when
+the file name did not change from the previous directive.
+
+Synchronisation directives are always given on complete lines per
+themselves. When a synchronisation discrepancy occurs in the middle of
+an output line, the associated synchronisation directive is delayed
+until the beginning of the next generated line.
+
+@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{m4___file__}
+instead of @samp{__file__}.
+
+@item -W@var{REGEXP}
+@itemx --word-regexp=@var{REGEXP}
+Use an alternative syntax for macro names. This experimental
+option might not be present on all GNU @code{m4} implementations.
+(@pxref{Changeword}).
+
+@item -H@var{n}
+@itemx --hashsize=@var{n}
+Make the internal hash table for symbol lookup be @var{n} entries big.
+The number should be prime. The default is 509 entries. It should not
+be necessary to increase this value, unless you define an excessive
+number of macros.
+
+@item -L@var{n}
+@itemx --nesting-limit=@var{n}
+Artificially limit the nesting of macro calls to @var{n} levels,
+stopping program execution if this limit is ever exceeded. When not
+specified, nesting is limited to 250 levels.
+
+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.
+
+This option does @emph{not} have the ability to break endless
+rescanning loops, while these do not necessarily consume much memory
+or stack space. Through clever usage of rescanning loops, one can
+request complex, time-consuming computations to @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 -Q
+@itemx --quiet
+@itemx --silent
+Suppress warnings about missing or superflous arguments in macro calls.
+
+@item -B
+@itemx -S
+@itemx -T
+These options are present for compatibility with System V @code{m4}, but
+do nothing in this implementation.
+
+@item -N@var{n}
+@itemx --diversions=@var{n}
+These options are present only for compatibility with previous
+versions of GNU @code{m4}, and were controlling the number of possible
+diversions which could be used at the same time. They do nothing,
+because there is no fixed limit anymore.
+
+@end table
+
+@cindex macro definitions, on the command line
+@cindex command line, macro definitions on the
+Macro definitions and deletions can be made on the command line, by
+using the @samp{-D} and @samp{-U} options. They have the following
+format:
+
+@table @code
+@item -D@var{name}
+@itemx -D@var{name}=@var{value}
+@itemx --define=@var{name}
+@itemx --define=@var{name}=@var{value}
+This enters @var{name} into the symbol table, before any input files are
+read. 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.
+
+@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.
+
+@item -t@var{name}
+@itemx --trace=@var{name}
+This enters @var{name} into the symbol table, as undefined but traced.
+The macro will consequently be traced from the point it is defined.
+
+@item -F@var{file}
+@itemx --freeze-state @var{file}
+Once execution is finished, write out the frozen state on the specified
+@var{file} (@pxref{Frozen files}).
+
+@item -R@var{file}
+@itemx --reload-state @var{file}
+Before execution starts, recover the internal state from the specified
+frozen @var{file} (@pxref{Frozen files}).
+
+@end table
+
+@cindex command line, filenames on the
+@cindex filenames, on the command line
+The remaining arguments on the command line are taken to be input file
+names. If no names are present, the standard input is read. A file
+name of @file{-} is taken to mean the standard input.
+
+The input files are read in the sequence given. The standard input can
+only be read once, so the filename @file{-} should only appear once on
+the command line.
+
+@node Bugs, Manual, Invoking m4, Preliminaries
+@section Problems and bugs
+
+If you have problems with GNU @code{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 (Internet)
+@file{bug-gnu-utils@@prep.ai.mit.edu} or (UUCP)
+@file{mit-eddie!prep.ai.mit.edu!bug-gnu-utils}. Please include the
+version number of @code{m4} you are using. You can get this information
+with the command @samp{m4 --version}.
+
+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, , Bugs, Preliminaries
+@section Using this manual
+
+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{}}. Thus
+
+@comment ignore
+@example
+Example of input line
+@result{}Output line from m4
+@error{}and an error message
+@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.,
+
+@comment ignore
+@example
+regexp(@var{string}, @var{regexp}, opt @var{replacement})
+@end example
+
+All macro arguments in @code{m4} are strings, but some are given special
+interpretation, e.g., as numbers, filenames, regular expressions, etc.
+
+The @samp{opt} before the third argument shows that this argument is
+optional---if it is left out, it is taken to be the empty string. An
+ellipsis (@samp{...}) last in the argument list indicates that any
+number of arguments may follow.
+
+This document consistently writes and uses @dfn{builtin}, without an
+hyphen, as if it were an English word. This is how the @code{builtin}
+primitive is spelled within @code{m4}.
+
+@node Syntax, Macros, Preliminaries, Top
+@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.
+
+@menu
+* Names:: Macro names
+* Quoted strings:: Quoting input to m4
+* Other tokens:: Other kinds of input tokens
+* Comments:: Comments in m4 input
+@end menu
+
+@node Names, Quoted strings, Syntax, Syntax
+@section Names
+
+@cindex names
+A name is any sequence of letters, digits, and the character @kbd{_}
+(underscore), where the first character is not a digit. If a
+name has a macro definition, it will be subject to macro expansion
+(@pxref{Macros}).
+
+Examples of legal names are: @samp{foo}, @samp{_tmp}, and @samp{name01}.
+
+@node Quoted strings, Other tokens, Names, Syntax
+@section Quoted strings
+
+@cindex quoted string
+A quoted string is a sequence of characters surrounded by the quotes
+@kbd{`} and @kbd{'}, where the number of start and end quotes within the
+string balances. The value of a string token is the text, with one
+level of quotes stripped off. Thus
+
+@comment ignore
+@example
+`'
+@end example
+
+is the empty string, and
+
+@comment ignore
+@example
+`@w{}`quoted'@w{}'
+@end example
+
+is the string
+
+@comment ignore
+@example
+`quoted'
+@end example
+
+The quote characters can be changed at any time, using the builtin macro
+@code{changequote}. @xref{Changequote} for more information.
+
+@node Other tokens, Comments, Quoted strings, Syntax
+@section Other tokens
+
+Any character, that is neither a part of a name, nor of a quoted string,
+is a token by itself.
+
+@node Comments, , Other tokens, Syntax
+@section Comments
+
+@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---comments are @emph{not} discarded by @code{m4}.
+
+Comments cannot be nested, so the first newline after a @samp{#} ends
+the comment. The commenting effect of the begin comment character
+can be inhibited by quoting it.
+
+The comment delimiters can be changed to any string at any time, using
+the builtin macro @code{changecom}. @xref{Changecom} for more
+information.
+
+@c FIXME: more examples would be useful here --ADR
+
+@node Macros, Definitions, Syntax, Top
+@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, Inhibiting Invocation, Macros, Macros
+@section Macro invocation
+
+@cindex macro invocation
+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, ..., 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, Macro Arguments, Invocation, Macros
+@section Preventing macro invocation
+
+An innovation of the @code{m4} language, compared to some of its
+predecessors (like Stratchey'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.
+
+First of all, many builtin macros cannot meaningfully be called
+without arguments. 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 when given arguments'' refers to this
+specific provision.
+
+There is also a command call option (@code{--prefix-builtins}, or
+@code{-P}) which requires all builtin macro names to be prefixed
+by @samp{m4_} for them to be recognized. 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}.
+
+If your version of GNU @code{m4} has the @code{changeword} feature
+compiled in, there it offers far more flexibility in specifying the
+syntax of macro names, both builtin or user-defined. @xref{Changeword}
+for more information on this experimental feature.
+
+Of course, the simplest way to prevent a name to be 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. It is also possible
+to quote the empty string, but this works only @emph{inside} the name.
+For example:
+
+@comment ignore
+@example
+`divert'
+`d'ivert
+di`ver't
+div`'ert
+@end example
+
+@noindent
+all yield the string @samp{divert}. While in both:
+
+@comment ignore
+@example
+`'divert
+divert`'
+@end example
+
+@noindent
+the @code{divert} builtin macro will be called.
+
+The output of macro evaluations is always rescanned. The following
+example would yield the string @samp{de}, exactly as if @code{m4}
+has been given @w{@samp{substr(abcde, 3, 2)}} as input:
+
+@comment ignore
+@example
+define(`x', `substr(ab')
+define(`y', `cde, 3, 2)')
+x`'y
+@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 @code{dnl} macro to be recognized as such:
+
+@comment ignore
+@example
+define(`macro', `di$1')
+macro(v)`'dnl
+@end example
+
+@noindent
+Without the quotes, this would rather yield the string @samp{divdnl}
+followed by an end of line.
+
+Quoting may prevent recognizing as a macro name the concatenation of a
+macro expansion with the surrounding characters. In this example:
+
+@comment ignore
+@example
+define(`macro', `di$1')
+macro(v)`ert'
+@end example
+
+@noindent
+the input will produce the string @samp{divert}. If the quote was
+removed, the @code{divert} builtin would be called instead.
+
+@node Macro Arguments, Quoting Arguments, Inhibiting Invocation, Macros
+@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. If
+there are too many arguments, the excess arguments are ignored.
+
+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 @samp{-Q} command line option. For user defined macros, there is no
+check of the number of arguments given.
+
+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
+
+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 leading unquoted whitespace is never part
+of an argument, but trailing whitespace always is.
+
+@node Quoting Arguments, Macro expansion, Macro Arguments, Macros
+@section Quoting macro arguments
+
+@cindex quoted macro arguments
+@cindex macros, quoted arguments to
+@cindex arguments, quoted macro
+Each argument has leading unquoted whitespace removed. Within each
+argument, all unquoted parentheses must match. For example, if
+@var{foo} is a macro,
+
+@comment ignore
+@example
+foo(() (`(') `(')
+@end example
+
+is a macro call, with one argument, whose value is @samp{()@w{ }(()@w{ }(}.
+
+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
+
+It is, however, in certain cases necessary 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.
+
+@node Macro expansion, , Quoting Arguments, Macros
+@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 ignore
+@example
+foo
+@end example
+
+@noindent
+will expand first to @samp{bar}, and when this is reread and
+expanded, into @samp{Hello world}.
+
+@node Definitions, Conditionals, Macros, Top
+@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, which can be brought back at a later time.
+
+@menu
+* Define:: Defining a new macro
+* Arguments:: Arguments to macros
+* Pseudo Arguments:: Pseudo arguments to macros
+* Undefine:: Deleting a macro
+* Defn:: Renaming macros
+* Pushdef:: Temporarily redefining macros
+
+* Indir:: Indirect call of macros
+* Builtin:: Indirect call of builtins
+@end menu
+
+@node Define, Arguments, Definitions, Definitions
+@section Defining a macro
+
+@findex define
+The normal way to define or redefine macros is to use the builtin
+@code{define}:
+
+@comment ignore
+@example
+define(@var{name} [, @var{expansion}])
+@end example
+
+@noindent which 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 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 macro @code{define} is recognized only with parameters.
+
+@node Arguments, Pseudo Arguments, Define, Definitions
+@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. Here is a example of a macro with
+two arguments. It simply exchanges the order of the two arguments.
+
+@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.
+
+@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.
+
+As a special case, the zero'th 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, Undefine, Arguments, Definitions
+@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. Thus, a macro to display the number of arguments
+given can be
+
+@example
+define(`nargs', `$#')
+@result{}
+nargs
+@result{}0
+nargs()
+@result{}1
+nargs(arg1, arg2, arg3)
+@result{}3
+@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..
+echo2(foo)
+@result{}This is macro foo.
+@end example
+
+@noindent
+@xref{Trace}, if you do not understand this.
+
+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
+
+If you want a macro to expand to something like @samp{$12}, put a pair
+of quotes after the @code{$}. This will prevent @code{m4} from
+interpreting the @code{$} sign as a reference to an argument.
+
+@node Undefine, Defn, Pseudo Arguments, Definitions
+@section Deleting a macro
+
+@cindex macros, how to delete
+@cindex deleting macros
+@cindex undefining macros
+@findex undefine
+A macro definition can be removed with @code{undefine}:
+
+@comment ignore
+@example
+undefine(@var{name})
+@end example
+
+@noindent
+which removes the macro @var{name}. The macro name must necessarily be
+quoted, since it will be expanded otherwise.
+
+The expansion of @code{undefine} is void.
+
+@example
+foo
+@result{}foo
+define(`foo', `expansion text')
+@result{}
+foo
+@result{}expansion text
+undefine(`foo')
+@result{}
+foo
+@result{}foo
+@end example
+
+It is not an error for @var{name} to have no macro definition. In that
+case, @code{undefine} does nothing.
+
+The macro @code{undefine} is recognized only with parameters.
+
+@node Defn, Pushdef, Undefine, Definitions
+@section Renaming macros
+
+@cindex macros, how to rename
+@cindex renaming macros
+@findex defn
+It is possible to rename an already defined macro. To do this, you need
+the builtin @code{defn}:
+
+@comment ignore
+@example
+defn(@var{name})
+@end example
+
+@noindent
+which expands to the @emph{quoted definition} of @var{name}. If the
+argument is not a defined macro, the expansion is void.
+
+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 is only meaningful as the second argument to
+@code{define} (and @code{pushdef}), and is ignored in any other context.
+
+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 macro @code{defn} is recognized only with parameters.
+
+@node Pushdef, Indir, Defn, Definitions
+@section Temporarily redefining macros
+
+@cindex macros, temporary redefinition of
+@cindex temporary redefinition of macros
+@cindex redefinition of macros, temporary
+It is possible to redefine a macro temporarily, reverting to the
+previous definition at a later time.
+@findex popdef
+@findex pushdef
+This is done with the builtins @code{pushdef} and @code{popdef}:
+
+@comment ignore
+@example
+pushdef(@var{name} [, @var{expansion}])
+popdef(@var{name})
+@end example
+
+@noindent
+which are quite 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}.
+
+@example
+define(`foo', `Expansion one.')
+@result{}
+foo
+@result{}Expansion one.
+pushdef(`foo', `Expansion two.')
+@result{}
+foo
+@result{}Expansion two.
+popdef(`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.
+
+@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
+
+It is possible to temporarily redefine a builtin with @code{pushdef}
+and @code{defn}.
+
+The macros @code{pushdef} and @code{popdef} are recognized only with
+parameters.
+
+@node Indir, Builtin, Pushdef, Definitions
+@section Indirect call of macros
+
+@cindex indirect call of macros
+@cindex call of macros, indirect
+@cindex macros, indirect call of
+@cindex GNU extensions
+@findex indir
+Any macro can be called indirectly with @code{indir}:
+
+@comment ignore
+@example
+indir(@var{name}, ...)
+@end example
+@noindent
+which results in a call to the macro @var{name}, which is passed the
+rest of the arguments. This can be used to call macros with ``illegal''
+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}.
+
+@c FIXME: Why indir does not require at least one parameter?
+
+@node Builtin, , Indir, Definitions
+@section Indirect call of builtins
+
+@cindex indirect call of builtins
+@cindex call of builtins, indirect
+@cindex builtins, indirect call of
+@cindex GNU extensions
+@findex builtin
+Builtin macros can be called indirectly with @code{builtin}:
+
+@comment ignore
+@example
+builtin(@var{name}, ...)
+@end example
+@noindent
+which results in a call to the builtin @var{name}, which is passed the
+rest of the arguments. This can be used, if @var{name} has been given
+another definition that has covered the original.
+
+The macro @code{builtin} is recognized only with parameters.
+
+@node Conditionals, Debugging, Definitions, Top
+@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. E.g., 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
+* Loops:: Loops and recursion in m4
+@end menu
+
+@node Ifdef, Ifelse, Conditionals, Conditionals
+@section Testing macro definitions
+
+@cindex conditionals
+@findex ifdef
+There are two different builtin conditionals in @code{m4}. The first is
+@code{ifdef}:
+
+@comment ignore
+@example
+ifdef(@var{name}, @var{string-1}, opt @var{string-2})
+@end example
+
+@noindent
+which makes it possible to test whether a macro is defined or not. 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).
+
+@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
+@end example
+
+The macro @code{ifdef} is recognized only with parameters.
+
+@node Ifelse, Loops, Ifdef, Conditionals
+@section Comparing strings
+
+@cindex comparing strings
+@findex ifelse
+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:
+
+@comment ignore
+@example
+ifelse(@var{comment})
+ifelse(@var{string-1}, @var{string-2}, @var{equal}, opt @var{not-equal})
+ifelse(@var{string-1}, @var{string-2}, @var{equal}, ...)
+@end example
+
+@noindent
+Used with only one argument, the @code{ifelse} simply discards it and
+produces no output. This 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.
+
+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}.
+
+@example
+ifelse(foo, bar, `true')
+@result{}
+ifelse(foo, foo, `true')
+@result{}true
+ifelse(foo, bar, `true', `false')
+@result{}false
+ifelse(foo, foo, `true', `false')
+@result{}true
+@end example
+
+@cindex multibranches
+However, @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}, otherwise
+the procedure is repeated with the first three arguments discarded. This
+calls for an example:
+
+@example
+ifelse(foo, bar, `third', gnu, gnats, `sixth', `seventh')
+@result{}seventh
+@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.
+
+The macro @code{ifelse} is recognized only with parameters.
+
+@node Loops, , Ifelse, Conditionals
+@section Loops and recursion
+
+@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.
+
+@findex shift
+There is a builtin macro, @code{shift}, which can, among other things,
+be used for iterating through the actual arguments to a macro:
+
+@comment ignore
+@example
+shift(...)
+@end example
+
+@noindent
+It takes any number of arguments, and expands to all but the first
+argument, separated by commas, with each argument quoted.
+
+@example
+shift(bar)
+@result{}
+shift(foo, bar, baz)
+@result{}bar,baz
+@end example
+
+An example of the use of @code{shift} is this macro, which reverses the
+order of its arguments:
+
+@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.
+
+@cindex forloops
+@cindex loops, counting
+@cindex counting loops
+Here is an example of a loop macro that implements a simple forloop. It
+can, for example, be used for simple counting:
+
+@comment ignore
+@example
+forloop(`i', 1, 8, `i ')
+@result{}1 2 3 4 5 6 7 8
+@end example
+
+The arguments are a name for the iteration variable, the starting value,
+the final value, and the text to be expanded for each iteration. With
+this macro, the macro @code{i} is defined only within the loop. After
+the loop, it retains whatever value it might have had before.
+
+For-loops can be nested, like
+
+@comment ignore
+@example
+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{_forloop}, and re-establishes the saved definition of
+the first argument.
+
+The macro @code{_forloop} expands the fourth argument once, and tests
+to see if it is finished. If it has not finished, it increments
+the iteration variable (using the predefined macro @code{incr},
+@pxref{Incr}), and recurses.
+
+Here is the actual implementation of @code{forloop}:
+
+@comment ignore
+@example
+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')')')
+@end example
+
+Notice the careful use of quotes. Only three macro arguments are
+unquoted, each for its own reason. Try to find out @emph{why} these
+three arguments are left unquoted, and see what happens if they are
+quoted.
+
+Now, even though these two macros are useful, they are still not robust
+enough for general use. They lack even basic error handling of cases
+like start value less than final value, and the first argument not being
+a name. Correcting these errors are left as an exercise to the reader.
+
+@node Debugging, Input Control, Conditionals, Top
+@chapter How to debug macros and input
+
+When writing macros for @code{m4}, most of the time they woould not
+work as intended (as is the case with most programming languages).
+There is a little support for macro debugging in @code{m4}.
+
+@menu
+* Dumpdef:: Displaying macro definitions
+* Trace:: Tracing macro calls
+* Debug Levels:: Controlling debugging output
+* Debug Output:: Saving debugging output
+@end menu
+
+@node Dumpdef, Trace, Debugging, Debugging
+@section Displaying macro definitions
+
+@cindex displaying macro definitions
+@cindex macros, displaying definitions
+@cindex definitions, displaying macro
+@findex dumpdef
+If you want to see what a name expands into, you can use the builtin
+@code{dumpdef}:
+
+@comment ignore
+@example
+dumpdef(...)
+@end example
+
+@noindent
+which accepts any number of arguments. If called without any arguments,
+it displays the definitions of all known names, otherwise it displays
+the definitions of the names given. The output is printed directly on
+the standard error output.
+
+The expansion of @code{dumpdef} is void.
+
+@example
+define(`foo', `Hello world.')
+@result{}
+dumpdef(`foo')
+@error{}foo: `Hello world.'
+@result{}
+dumpdef(`define')
+@error{}define: <define>
+@result{}
+@end example
+
+The last example shows how builtin macros definitions are displayed.
+
+@xref{Debug Levels} for information on controlling the details of the
+display.
+
+@node Trace, Debug Levels, Dumpdef, Debugging
+@section Tracing macro calls
+
+@cindex tracing macro expansion
+@cindex macro expansion, tracing
+@cindex expansion, tracing macro
+@findex traceon
+@findex traceoff
+It is possible to trace macro calls and expansions through the builtins
+@code{traceon} and @code{traceoff}:
+
+@comment ignore
+@example
+traceon(...)
+traceoff(...)
+@end example
+
+@noindent
+When called without any arguments, @code{traceon} and @code{traceoff}
+will turn tracing on and off, respectively, for all defined macros.
+When called with arguments, only the named macros are affected.
+
+The expansion of @code{traceon} and @code{traceoff} is void.
+
+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
+directly on the standard error output.
+
+@example
+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.
+
+@xref{Debug Levels} for information on controlling the details of the
+display.
+
+@node Debug Levels, Debug Output, Trace, Debugging
+@section Controlling debugging output
+
+@cindex controlling debugging output
+@cindex debugging output, controlling
+The @samp{-d} option to @code{m4} controls the amount of details
+presented, when using the macros described in the preceding sections.
+
+The @var{flags} following the option can be one or more of the
+following:
+
+@table @code
+@item t
+Trace all macro calls made in this invocation of @code{m4}.
+
+@item a
+Show the actual arguments in each macro call. This applies to all macro
+calls if the @samp{t} flag is used, otherwise only the macros covered by
+calls of @code{traceon}.
+
+@item e
+Show the expansion of each macro call, if it is not void. This applies
+to all macro calls if the @samp{t} flag is used, otherwise only the
+macros covered by calls of @code{traceon}.
+
+@item q
+Quote actual arguments and macro expansions in the display with the
+current quotes.
+
+@item c
+Show several trace lines for each macro call. A line is shown when the
+macro is seen, but before the arguments are collected; a second line
+when the arguments have been collected and a third line after the call
+has completed.
+
+@item x
+Add a unique `macro call id' to each line of the trace output. This is
+useful in connection with the @samp{c} flag above.
+
+@item f
+Show the name of the current input file in each trace output line.
+
+@item l
+Show the the current input line number in each trace output line.
+
+@item p
+Print a message when a named file is found through the path search
+mecanism (@pxref{Search Path}), giving the actual filename used.
+
+@item i
+Print a message each time the current input file is changed, giving file
+name and input line number.
+
+@item V
+A shorthand for all of the above flags.
+@end table
+
+If no flags are specified with the @samp{-d} option, the default is
+@samp{aeq}. The examples in the previous two sections assumed the
+default flags.
+
+@cindex GNU extensions
+@findex debugmode
+There is a builtin macro @code{debugmode}, which allows on-the-fly control of
+the debugging output format:
+
+@comment ignore
+@example
+debugmode(opt @var{flags})
+@end example
+@noindent
+The argument @var{flags} should be a subset of the letters listed above.
+As special cases, if the argument starts with a @samp{+}, the flags are
+added to the current debug flags, and if it starts with a @samp{-}, they
+are removed. If no argument is present, the debugging flags are set to
+zero (as if no @samp{-d} was given), and with an empty argument the flags
+are reset to the default.
+
+@node Debug Output, , Debug Levels, Debugging
+@section Saving debugging output
+
+@cindex saving debugging output
+@cindex debugging output, saving
+@cindex output, saving debugging
+@cindex GNU extensions
+@findex debugfile
+Debug and tracing output can be redirected to files using either the
+@samp{-o} option to @code{m4}, or with the builtin macro @code{debugfile}:
+
+@comment ignore
+@example
+debugfile(opt @var{filename})
+@end example
+@noindent
+will send all further debug and trace output to @var{filename}. If
+@var{filename} is empty, debug and trace output are discarded and if
+@code{debugfile} is called without any arguments, debug and trace output
+are sent to the standard error output.
+
+@node Input Control, File Inclusion, Debugging, Top
+@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
+* Changeword:: Changing the lexical structure of words
+* M4wrap:: Saving input until end of input
+@end menu
+
+@node Dnl, Changequote, Input Control, Input Control
+@section Deleting whitespace in input
+
+@cindex deleting whitespace in input
+@findex dnl
+The builtin @code{dnl} reads and discards all characters, up to and
+including the first newline:
+
+@comment ignore
+@example
+dnl
+@end example
+@noindent
+and it is often used in connection with @code{define}, to remove the
+newline that follow 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}).
+
+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.
+
+@node Changequote, Changecom, Dnl, Input Control
+@section Changing the quote characters
+
+@cindex changing the quote delimiters
+@cindex quote delimiters, changing the
+@findex changequote
+The default quote delimiters can be changed with the builtin
+@code{changequote}:
+
+@comment ignore
+@example
+changequote(opt @var{start}, opt @var{end})
+@end example
+@noindent
+where @var{start} is the new start-quote delimiter and @var{end} is the
+new end-quote delimiter. If any of the arguments are missing, the default
+quotes (@code{`} and @code{'}) are used instead of the void arguments.
+
+The expansion of @code{changequote} is void.
+
+@example
+changequote([, ])
+@result{}
+define([foo], [Macro [foo].])
+@result{}
+foo
+@result{}Macro foo.
+@end example
+
+If no single character is appropriate, @var{start} and @var{end} can be
+of any length.
+
+@example
+changequote([[, ]])
+@result{}
+define([[foo]], [[Macro [[[foo]]].]])
+@result{}
+foo
+@result{}Macro [foo].
+@end example
+
+Changing the quotes to the empty strings will effectively disable the
+quoting mechanism, leaving no way to quote text.
+
+@example
+define(`foo', `Macro `FOO'.')
+@result{}
+changequote(, )
+@result{}
+foo
+@result{}Macro `FOO'.
+`foo'
+@result{}`Macro `FOO'.'
+@end example
+
+There is no way in @code{m4} to quote a string containing an unmatched
+left quote, except using @code{changequote} to change the current
+quotes.
+
+Neither quote string should start with a letter or @samp{_} (underscore),
+as they will be confused with names in the input. Doing so disables
+the quoting mechanism.
+
+@node Changecom, Changeword, Changequote, Input Control
+@section Changing comment delimiters
+
+@cindex changing comment delimiters
+@cindex comment delimiters, changing
+@findex changecom
+The default comment delimiters can be changed with the builtin
+macro @code{changecom}:
+
+@comment ignore
+@example
+changecom(opt @var{start}, opt @var{end})
+@end example
+@noindent
+where @var{start} is the new start-comment delimiter and @var{end} is
+the new end-comment delimiter. If any of the arguments are void, the
+default comment delimiters (@code{#} and newline) are used instead of
+the void arguments. The comment delimiters can be of any length.
+
+The expansion of @code{changecom} is void.
+
+@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
+start comment delimiter.
+
+Calling @code{changecom} without any arguments disables the commenting
+mechanism completely.
+
+@example
+define(`comment', `COMMENT')
+@result{}
+changecom
+@result{}
+# Not a comment anymore
+@result{}# Not a COMMENT anymore
+@end example
+
+@node Changeword, M4wrap, Changecom, Input Control
+@section Changing the lexical structure of words
+
+@cindex lexical structure of words
+@cindex words, lexical structure of
+@findex changeword
+@quotation
+The macro @code{changeword} and all associated functionnality is
+experimental. It is only available if the @code{--enable-changeword}
+option was given to @code{configure}, at GNU @code{m4} installation
+time. The functionnality 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.
+@end quotation
+
+A file being processed by @code{m4} is split into quoted strings, words
+(potential macro names) and simple tokens (any other single character).
+Initially a word is defined by the following regular expression:
+
+@comment ignore
+@example
+[_a-zA-Z][_a-zA-Z0-9]*
+@end example
+
+Using @code{changeword}, you can change this regular expression. Relaxing
+@code{m4}'s lexical rules might be useful (for example) if you wanted to
+apply translations to a file of numbers:
+
+@comment ignore
+@example
+changeword(`[_a-zA-Z0-9]+')
+define(1, 0)
+@result{}1
+@end example
+
+Tightening the lexical rules is less useful, because it will generally
+make some of the builtins unavailable. You could use it to prevent
+accidental call of builtins, for example:
+
+@comment ignore
+@example
+define(`_indir', defn(`indir'))
+changeword(`_[_a-zA-Z0-9]*')
+esyscmd(foo)
+_indir(`esyscmd', `ls')
+@end example
+
+Because @code{m4} constructs its words a character at a time, there
+is a restriction on the regular expressions that may be passed to
+@code{changeword}. This is that if your regular expression accepts
+@samp{foo}, it must also accept @samp{f} and @samp{fo}.
+
+@code{changeword} has another function. If the regular expression
+supplied contains any bracketed subexpressions, then text outside
+the first of these is discarded before symbol lookup. So:
+
+@comment ignore
+@example
+changecom(`/*', `*/')
+changeword(`#\([_a-zA-Z0-9]*\)')
+#esyscmd(ls)
+@end example
+
+@code{m4} now requires a @samp{#} mark at the beginning of every
+macro invocation, so one can use @code{m4} to preprocess shell
+scripts without getting @code{shift} commands swallowed, and plain
+text without losing various common words.
+
+@code{m4}'s macro substitution is based on text, while @TeX{}'s is based
+on tokens. @code{changeword} can throw this difference into relief. For
+example, here is the same idea represented in @TeX{} and @code{m4}.
+First, the @TeX{} version:
+
+@comment ignore
+@example
+\def\a@{\message@{Hello@}@}
+\catcode`\@@=0
+\catcode`\\=12
+@result{}@@a
+@result{}@@bye
+@end example
+
+@noindent
+Then, the @code{m4} version:
+
+@comment ignore
+@example
+define(a, `errprint(`Hello')')
+changeword(`@@\([_a-zA-Z0-9]*\)')
+@result{}@@a
+@end example
+
+In the @TeX{} example, the first line defines a macro @code{a} to
+print the message @samp{Hello}. The second line defines @key{@@} to
+be usable instead of @key{\} as an escape character. The third line
+defines @key{\} to be a normal printing character, not an escape.
+The fourth line invokes the macro @code{a}. So, when @TeX{} is run
+on this file, it displays the message @samp{Hello}.
+
+When the @code{m4} example is passed through @code{m4}, it outputs
+@samp{errprint(Hello)}. The reason for this is that @TeX{} does
+lexical analysis of macro definition when the macro is @emph{defined}.
+@code{m4} just stores the text, postponing the lexical analysis until
+the macro is @emph{used}.
+
+You should note that using @code{changeword} will slow @code{m4} down
+by a factor of about seven.
+
+@node M4wrap, , Changeword, Input Control
+@section Saving input
+
+@cindex saving input
+@cindex input, saving
+@findex m4wrap
+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}:
+
+@comment ignore
+@example
+m4wrap(@var{string}, ...)
+@end example
+@noindent
+which stores @var{string} and the rest of the arguments in a safe place,
+to be reread when end of input is reached.
+
+@example
+define(`cleanup', `This is the `cleanup' actions.
+')
+@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 actions.
+@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 saved text, but then the order in
+which the saved text is reread is undefined. If @code{m4wrap} is not used
+recursively, the saved pieces of text are reread in the opposite order
+in which they were saved (LIFO---last in, first out).
+
+@node File Inclusion, Diversions, Input Control, Top
+@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
+* Search Path:: Searching for include files
+@end menu
+
+@node Include, Search Path, File Inclusion, File Inclusion
+@section Including named files
+
+@findex include
+@findex sinclude
+There are two builtin macros in @code{m4} for including files:
+
+@comment ignore
+@example
+include(@var{filename})
+sinclude(@var{filename})
+@end example
+
+@noindent
+both of which cause the file named @var{filename} 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{filename}.
+
+It is an error for an @code{include}d file not to exist. If you do
+not want error messages about non-existent files, @code{sinclude} can
+be used to include a file, if it exists, expanding to nothing if it
+does not.
+
+@example
+include(`no-such-file')
+@result{}
+@error{}30.include:2: m4: Cannot open no-such-file: No such file or directory
+sinclude(`no-such-file')
+@result{}
+@end example
+
+Assume in the following that the file @file{incl.m4} contains the lines:
+@comment ignore
+@example
+Include file start
+foo
+Include file end
+@end example
+@noindent
+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:
+
+@example
+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}:
+
+@example
+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.
+
+The builtin macros @code{include} and @code{sinclude} are recognized
+only when given arguments.
+
+@node Search Path, , Include, File Inclusion
+@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.
+
+If a file is not found in the current working directory, and the file
+name is not absolute, the file will be looked for in a specified search
+path. First, the directories specified with the @samp{-I} option will
+be searched, in the order found on the command line. Second, if the
+@samp{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{Debug Levels}) can help isolate the problem.
+
+@node Diversions, Text handling, File Inclusion, Top
+@chapter Diverting and undiverting 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.
+
+Numbered diversions are counted from 0 upwards, diversion number 0
+being the normal output stream. The number of simultaneous diversions
+is limited mainly by the memory used to describe them, because GNU
+@code{m4} tries to keep diversions in memory. However, there is a
+limit to the overall memory usable by all diversions taken altogether
+(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.
+So, it is theoretically possible that the number of diversions be
+limited by the number of available file descriptors.
+
+@c FIXME: need some explanation here why this is a useful feature, not
+@c just how you use it.
+
+@menu
+* Divert:: Diverting output
+* Undivert:: Undiverting output
+* Divnum:: Diversion numbers
+* Cleardiv:: Discarding diverted text
+@end menu
+
+@node Divert, Undivert, Diversions, Diversions
+@section Diverting output
+
+@cindex diverting output to files
+@cindex output, diverting to files
+@cindex files, diverting output to
+@findex divert
+Output is diverted using @code{divert}:
+
+@comment ignore
+@example
+divert(opt @var{number})
+@end example
+
+@noindent
+where @var{number} is the diversion to be used. If @var{number} is left
+out, it is assumed to be zero.
+
+The expansion of @code{divert} is void.
+
+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.
+
+If output is diverted to a non-existent 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 how to avoid them.
+
+@example
+divert(-1)
+define(`foo', `Macro `foo'.')
+define(`bar', `Macro `bar'.')
+divert
+@result{}
+@end example
+
+This is a common programming idiom in @code{m4}.
+
+@node Undivert, Divnum, Divert, Diversions
+@section Undiverting output
+
+@findex undivert
+Diverted text can be undiverted explicitly using the builtin
+@code{undivert}:
+
+@comment ignore
+@example
+undivert(opt @var{number}, ...)
+@end example
+
+@noindent
+which undiverts the diversions given by the arguments, in the order
+given. If no arguments are supplied, all diversions are undiverted, in
+numerical order.
+
+@c FIXME: Explain what happens when undiverting all to else than 0.
+
+The expansion of @code{undivert} is void.
+
+@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.
+
+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.
+
+@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 the word @samp{bar}:
+
+@example
+define(`bar', `BAR')
+@result{}
+undivert(`foo')
+@result{}bar
+@result{}
+include(`foo')
+@result{}BAR
+@result{}
+@end example
+
+@node Divnum, Cleardiv, Undivert, Diversions
+@section Diversion numbers
+
+@cindex diversion numbers
+@findex divnum
+The builtin @code{divnum}:
+
+@comment ignore
+@example
+divnum
+@end example
+
+@noindent
+expands to the number of the current diversion.
+
+@example
+Initial divnum
+@result{}Initial 0
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert
+@result{}
+^D
+@result{}
+@result{}Diversion one: 1
+@result{}
+@result{}Diversion two: 2
+@end example
+
+The last call of @code{divert} without argument is necessary, since the
+undiverted text would otherwise be diverted itself.
+
+@node Cleardiv, , Divnum, Diversions
+@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:
+
+@example
+define(`cleardivert',
+`pushdef(`_num', divnum)divert(-1)undivert($@@)divert(_num)popdef(`_num')')
+@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.)
+
+@node Text handling, Arithmetic, Diversions, Top
+@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:: 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, Index, Text handling, Text handling
+@section Calculating length of strings
+
+@cindex length of strings
+@cindex strings, length of
+@findex len
+The length of a string can be calculated by @code{len}:
+
+@comment ignore
+@example
+len(@var{string})
+@end example
+
+@noindent
+which expands to the length of @var{string}, as a decimal number.
+
+@example
+len()
+@result{}0
+len(`abcdef')
+@result{}6
+@end example
+
+The builtin macro @code{len} is recognized only when given arguments.
+
+@node Index, Regexp, Len, Text handling
+@section Searching for substrings
+
+@findex index
+Searching for substrings is done with @code{index}:
+
+@comment ignore
+@example
+index(@var{string}, @var{substring})
+@end example
+
+@noindent
+which 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}.
+
+@example
+index(`gnus, gnats, and armadillos', `nat')
+@result{}7
+index(`gnus, gnats, and armadillos', `dag')
+@result{}-1
+@end example
+
+The builtin macro @code{index} is recognized only when given arguments.
+
+@node Regexp, Substr, Index, Text handling
+@section Searching for regular expressions
+
+@cindex regular expressions
+@cindex GNU extensions
+@findex regexp
+Searching for regular expressions is done with the builtin
+@code{regexp}:
+
+@comment ignore
+@example
+regexp(@var{string}, @var{regexp}, opt @var{replacement})
+@end example
+
+@noindent
+which searches for @var{regexp} in @var{string}. The syntax for regular
+expressions is the same as in GNU Emacs. @xref{Regexps, , Syntax of
+Regular Expressions, emacs, The GNU Emacs Manual}.
+
+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.
+
+@example
+regexp(`GNUs not Unix', `\<[a-z]\w+')
+@result{}5
+regexp(`GNUs not Unix', `\<Q\w*')
+@result{}-1
+@end example
+
+If @var{replacement} is supplied, @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},
+@samp{\&} being the text the entire regular expression matched.
+
+@example
+regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
+@result{}*** Unix *** nix ***
+@end example
+
+The builtin macro @code{regexp} is recognized only when given arguments.
+
+@node Substr, Translit, Regexp, Text handling
+@section Extracting substrings
+
+@cindex extracting substrings
+@cindex substrings, extracting
+@findex substr
+Substrings are extracted with @code{substr}:
+
+@comment ignore
+@example
+substr(@var{string}, @var{from}, opt @var{length})
+@end example
+
+@noindent
+which expands to the substring of @var{string}, which starts at index
+@var{from}, and extends for @var{length} characters, or to the end of
+@var{string}, if @var{length} is omitted. The starting index of a string
+is always 0.
+
+@example
+substr(`gnus, gnats, and armadillos', 6)
+@result{}gnats, and armadillos
+substr(`gnus, gnats, and armadillos', 6, 5)
+@result{}gnats
+@end example
+
+The builtin macro @code{substr} is recognized only when given arguments.
+
+@node Translit, Patsubst, Substr, Text handling
+@section Translating characters
+
+@cindex translating characters
+@cindex characters, translating
+@findex translit
+Character translation is done with @code{translit}:
+
+@comment ignore
+@example
+translit(@var{string}, @var{chars}, @var{replacement})
+@end example
+
+@noindent
+which 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
+are deleted from the expansion. If @var{replacement} is omitted, all
+characters in @var{string}, that are present in @var{chars} are deleted
+from the expansion.
+
+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.
+
+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}.
+
+@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
+@end example
+
+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.
+
+The builtin macro @code{translit} is recognized only when given
+arguments.
+
+@node Patsubst, Format, Translit, Text handling
+@section Substituting text by regular expression
+
+@cindex regular expressions
+@cindex pattern substitution
+@cindex substitution by regular expression
+@cindex GNU extensions
+@findex patsubst
+Global substitution in a string is done by @code{patsubst}:
+
+@comment ignore
+@example
+patsubst(@var{string}, @var{regexp}, opt @var{replacement})
+@end example
+@noindent
+which searches @var{string} for matches of @var{regexp}, and substitutes
+@var{replacement} for each match. The syntax for regular expressions
+is the same as in GNU Emacs.
+
+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{regexp}, @samp{\&}
+being the text the entire regular expression matched.
+
+The @var{replacement} argument can be omitted, in which case the text
+matched by @var{regexp} is deleted.
+
+@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
+@end example
+
+Here is a slightly more realistic example, which capitalizes individual
+word or whole sentences, by substituting calls of the macros
+@code{upcase} and @code{downcase} into the strings.
+
+@example
+define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
+define(`downcase', `translit(`$*', `A-Z', `a-z')')dnl
+define(`capitalize1',
+ `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')dnl
+define(`capitalize',
+ `patsubst(`$1', `\w+', `capitalize1(`\&')')')dnl
+capitalize(`GNUs not Unix')
+@result{}Gnus Not Unix
+@end example
+
+The builtin macro @code{patsubst} is recognized only when given
+arguments.
+
+@node Format, , Patsubst, Text handling
+@section Formatted output
+
+@cindex formatted output
+@cindex output, formatted
+@cindex GNU extensions
+@findex format
+Formatted output can be made with @code{format}:
+
+@comment ignore
+@example
+format(@var{format-string}, ...)
+@end example
+
+@noindent
+which works much like the C function @code{printf}. The first argument
+is a format string, which can contain @samp{%} specifications, and the
+expansion of @code{format} is the formatted string.
+
+Its use is best described by a few examples:
+
+@example
+define(`foo', `The brown fox jumped over the lazy dog')
+@result{}
+format(`The string "%s" is %d characters long', foo, len(foo))
+@result{}The string "The brown fox jumped over the lazy dog" is 38 characters long
+@end example
+
+Using the @code{forloop} macro defined in @xref{Loops}, this
+example shows how @code{format} can be used to produce tabular output.
+
+@comment ignore
+@example
+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
+@end example
+
+The builtin @code{format} is modeled after the ANSI C @samp{printf}
+function, and supports the normal @samp{%} specifiers: @samp{c},
+@samp{s}, @samp{d}, @samp{o}, @samp{x}, @samp{X}, @samp{u}, @samp{e},
+@samp{E} and @samp{f}; it supports field widths and precisions, and the
+modifiers @samp{+}, @samp{-}, @samp{@w{ }}, @samp{0}, @samp{#}, @samp{h} and
+@samp{l}. For more details on the functioning of @code{printf}, see the
+C Library Manual.
+
+@c FIXME: Why format does not require at least one argument?
+
+@node Arithmetic, UNIX commands, Text handling, Top
+@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
+@end menu
+
+@node Incr, Eval, Arithmetic, Arithmetic
+@section Decrement and increment operators
+
+@cindex decrement operator
+@cindex increment operator
+@findex incr
+@findex decr
+Increment and decrement of integers are supported using the builtins
+@code{incr} and @code{decr}:
+
+@comment ignore
+@example
+incr(@var{number})
+decr(@var{number})
+@end example
+
+@noindent
+which expand to the numerical value of @var{number}, incremented,
+or decremented, respectively, by one.
+
+@example
+incr(4)
+@result{}5
+decr(7)
+@result{}6
+@end example
+
+The builtin macros @code{incr} and @code{decr} are recognized only when
+given arguments.
+
+@node Eval, , Incr, Arithmetic
+@section Evaluating integer expressions
+
+@cindex integer expression evaluation
+@cindex evaluation, of integer expressions
+@cindex expressions, evaluation of integer
+@findex eval
+Integer expressions are evaluated with @code{eval}:
+
+@comment ignore
+@example
+eval(@var{expression}, opt @var{radix}, opt @var{width})
+@end example
+
+@noindent
+which expands to the value of @var{expression}.
+
+Expressions can contain the following operators, listed in order of
+decreasing precedence.
+
+@table @code
+@item -
+Unary minus
+@item **
+Exponentiation
+@item * / %
+Multiplication, division and modulo
+@item + -
+Addition and subtraction
+@item << >>
+Shift left or right
+@item == != > >= < <=
+Relational operators
+@item !
+Logical negation
+@item ~
+Bitwise negation
+@item &
+Bitwise and
+@item ^
+Bitwise exclusive-or
+@item |
+Bitwise or
+@item &&
+Logical and
+@item ||
+Logical or
+@end table
+
+All operators, except exponentiation, are left associative.
+
+Note that many @code{m4} implementations use @samp{^} as an alternate
+operator for the exponentiation, while many others use @samp{^} for the
+bitwise exclusive-or. GNU @code{m4} changed its behavior: it used to
+exponentiate for @samp{^}, it now computes the bitwise exclusive-or.
+
+Numbers without special prefix are given decimal. A simple @samp{0}
+prefix introduces an octal number. @samp{0x} introduces an hexadecimal
+number. @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 any radix, 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(index(`Hello world', `llo') >= 0)
+@result{}1
+define(`square', `eval(($1)**2)')
+@result{}
+square(9)
+@result{}81
+square(square(5)+1)
+@result{}676
+define(`foo', `666')
+@result{}
+eval(`foo'/6)
+@error{}51.eval:14: m4: Bad expression in eval: foo/6
+@result{}
+eval(foo/6)
+@result{}111
+@end example
+
+As the second to last example shows, @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}.
+
+If @var{radix} is specified, it specifies the radix to be used in the
+expansion. The default radix is 10. The result of @code{eval} is
+always taken to be signed. The @var{width} argument specifies a minimum
+output width. The result is zero-padded to extend the expansion to the
+requested width.
+
+@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{}-000003030
+@end example
+
+Take note that @var{radix} cannot be larger than 36.
+
+The builtin macro @code{eval} is recognized only when given arguments.
+
+@node UNIX commands, Miscellaneous, Arithmetic, Top
+@chapter Running UNIX commands
+
+@cindex executing UNIX commands
+@cindex running UNIX commands
+@cindex UNIX commands, running
+@cindex commands, running UNIX
+There are a few builtin macros in @code{m4} that allow you to run UNIX
+commands from within @code{m4}.
+
+@menu
+* Syscmd:: Executing simple commands
+* Esyscmd:: Reading the output of commands
+* Sysval:: Exit codes
+* Maketemp:: Making names for temporary files
+@end menu
+
+@node Syscmd, Esyscmd, UNIX commands, UNIX commands
+@section Executing simple commands
+
+@findex syscmd
+Any shell command can be executed, using @code{syscmd}:
+
+@comment ignore
+@example
+syscmd(@var{shell-command})
+@end example
+
+@noindent
+which 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 output buffers.
+The default standard input, output and error of @var{shell-command} are
+the same as those of @code{m4}.
+
+The builtin macro @code{syscmd} is recognized only when given arguments.
+
+@node Esyscmd, Sysval, Syscmd, UNIX commands
+@section Reading the output of commands
+
+@findex esyscmd
+@cindex GNU extensions
+If you want @code{m4} to read the output of a UNIX command, use
+@code{esyscmd}:
+
+@comment ignore
+@example
+esyscmd(@var{shell-command})
+@end example
+
+@noindent
+which expands to the standard output of the shell command
+@var{shell-command}.
+
+Prior to executing the command, @code{m4} flushes its output buffers.
+The default standard input and error output 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}.
+
+Assume you are positioned into the @file{checks} directory of GNU
+@code{m4} distribution, then:
+
+@example
+define(`vice', `esyscmd(grep Vice ../COPYING)')
+@result{}
+vice
+@result{} Ty Coon, President of Vice
+@result{}
+@end example
+
+Note how the expansion of @code{esyscmd} has a trailing newline.
+
+The builtin macro @code{esyscmd} is recognized only when given
+arguments.
+
+@node Sysval, Maketemp, Esyscmd, UNIX commands
+@section Exit codes
+
+@cindex exit code from UNIX commands
+@cindex UNIX commands, exit code from
+@cindex commands, exit code from UNIX
+@findex sysval
+To see whether a shell command succeeded, use @code{sysval}:
+
+@comment ignore
+@example
+sysval
+@end example
+
+@noindent
+which expands to the exit status of the last shell command run with
+@code{syscmd} or @code{esyscmd}.
+
+@example
+syscmd(`false')
+@result{}
+ifelse(sysval, 0, zero, non-zero)
+@result{}non-zero
+syscmd(`true')
+@result{}
+sysval
+@result{}0
+@end example
+
+@node Maketemp, , Sysval, UNIX commands
+@section Making names for temporary files
+
+@cindex temporary filenames
+@cindex files, names of temporary
+@findex maketemp
+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{maketemp}, for making temporary file
+names:
+
+@comment ignore
+@example
+maketemp(@var{template})
+@end example
+
+@noindent
+which expands to a name of a non-existent file, made from the string
+@var{template}, which should end with the string @samp{XXXXXX}. The six
+@code{X}'s are then replaced, usually with something that includes the
+process id of the @code{m4} process, in order to make the filename unique.
+
+@comment ignore
+@example
+maketemp(`/tmp/fooXXXXXX')
+@result{}/tmp/fooa07346
+maketemp(`/tmp/fooXXXXXX')
+@result{}/tmp/fooa07346
+@end example
+
+As seen in the example, several calls of @code{maketemp} might expand to
+the same string, since the selection criteria is whether the file exists
+or not. If a file has not been created before the next call, the two
+macro calls might expand to the same name.
+
+The builtin macro @code{maketemp} is recognized only when given
+arguments.
+
+@node Miscellaneous, Frozen files, UNIX commands, Top
+@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
+* M4exit:: Exiting from m4
+@end menu
+
+@node Errprint, M4exit, Miscellaneous, Miscellaneous
+@section Printing error messages
+
+@cindex printing error messages
+@cindex error messages, printing
+@cindex messages, printing error
+@findex errprint
+You can print error messages using @code{errprint}:
+
+@comment ignore
+@example
+errprint(@var{message}, ...)
+@end example
+@noindent
+which simply prints @var{message} and the rest of the arguments on the
+standard error output.
+
+The expansion of @code{errprint} is void.
+
+@example
+errprint(`Illegal arguments to forloop
+')
+@error{}Illegal arguments to forloop
+@result{}
+@end example
+
+A trailing newline is @emph{not} printed automatically, so it must be
+supplied as part of the argument, as in the example. (BSD flavored
+@code{m4}'s do append a trailing newline on each @code{errprint} call).
+
+To make it possible to specify the location of the error, two
+utility builtins exist:
+
+@findex file
+@findex line
+@comment ignore
+@example
+__file__
+__line__
+@end example
+@noindent
+which expands to the quoted name of the current input file, and the
+current input line number in that file.
+
+@example
+errprint(`m4:'__file__:__line__: `Input error
+')
+@error{}m4:56.errprint:2: Input error
+@result{}
+@end example
+
+@node M4exit, , Errprint, Miscellaneous
+@section Exiting from @code{m4}
+
+@cindex exiting from @code{m4}
+@findex m4exit
+If you need to exit from @code{m4} before the entire input has been
+read, you can use @code{m4exit}:
+
+@comment ignore
+@example
+m4exit(opt @var{code})
+@end example
+@noindent
+which causes @code{m4} to exit, with exit code @var{code}. If
+@var{code} is left out, the exit code is zero.
+
+@example
+define(`fatal_error', `errprint(`m4: '__file__: __line__`: fatal error: $*
+')m4exit(1)')
+@result{}
+fatal_error(`This is a BAD one, buster')
+@error{}m4: 57.m4exit: 5: fatal error: This is a BAD one, buster
+@end example
+
+After this macro call, @code{m4} will exit with exit code 1. This macro
+is only intended for error exits, since the normal exit procedures are
+not followed, e.g., diverted text is not undiverted, and saved text
+(@pxref{M4wrap}) is not reread.
+
+@node Frozen files, Compatibility, Miscellaneous, Top
+@chapter Fast loading of frozen states
+
+@cindex fast loading of frozen files
+@cindex frozen files for fast loading
+@cindex initialization, frozen states
+@cindex dumping into frozen file
+@cindex reloading a frozen file
+@cindex GNU extensions
+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, @code{include}'d from this input file.
+
+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. Presume the
+user repeatedly uses:
+
+@comment ignore
+@example
+m4 base.m4 input.m4
+@end example
+
+@noindent
+with a varying contents of @file{input.m4}, but a rather fixed contents
+for @file{base.m4}. Then, the user might rather execute:
+
+@comment ignore
+@example
+m4 -F base.m4f base.m4
+@end example
+
+@noindent
+once, and further execute, as often as needed:
+
+@comment ignore
+@example
+m4 -R base.m4f input.m4
+@end example
+
+@noindent
+with the varying input. The first call, containing the @code{-F}
+option, only reads and executes file @file{base.m4}, so defining
+various application macros and computing other initializations. Only
+once the input file @file{base.m4} has been completely processed, GNU
+@code{m4} produces on @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 @code{-R} option, are able to reload
+the internal state of @code{m4}'s memory, from @file{base.m4f},
+@emph{prior} to reading any other input files. By this mean,
+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
+@code{-R} and @code{-F} options simultaneously. For example, if
+some care is taken, the command:
+
+@comment ignore
+@example
+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
+m4 -F file1.m4f file1.m4
+m4 -R file1.m4f -F file2.m4f file2.m4
+m4 -R file2.m4f -F file3.m4f file3.m4
+m4 -R file3.m4f file4.m4
+@end example
+
+Some care is necessary because not every effort has been made for
+this to work in all cases. In particular, the trace attribute of
+macros is not handled, nor the current setting of @code{changeword}.
+Also, interactions for some options of @code{m4} being used in one call
+and not for the next, have not been fully analyzed yet. On the other
+end, you may be confident that stacks of @code{pushdef}'ed definitions
+are handled correctly, so are @code{undefine}'d or renamed builtins,
+changed strings for quotes or comments.
+
+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}).
+
+Frozen files are sharable across architectures. It is safe to write
+a frozen file one one machine and read it on another, given that the
+second machine uses the same, or a newer version of GNU @code{m4}.
+These are simple (editable) text files, made up of directives,
+each starting with a capital letter and ending with a newline
+(@key{NL}). Wherever a directive is expected, the character
+@kbd{#} introduces a comment line, empty lines are also ignored.
+In the following descriptions, @var{length}s always refer to
+corresponding @var{string}s. Numbers are always expressed in decimal.
+The directives are:
+
+@table @code
+@item V @var{number} @key{NL}
+Confirms the format of the file. @var{number} should be 1.
+
+@item C @var{length1} , @var{length2} @key{NL} @var{string1} @var{string2} @key{NL}
+Uses @var{string1} and @var{string2} as the beginning comment and
+end comment strings.
+
+@item Q @var{length1} , @var{length2} @key{NL} @var{string1} @var{string2} @key{NL}
+Uses @var{string1} and @var{string2} as the beginning quote and end quote
+strings.
+
+@item F @var{length1} , @var{length2} @key{NL} @var{string1} @var{string2} @key{NL}
+Defines, through @code{pushdef}, a definition for @var{string1}
+expanding to the function whose builtin name is @var{string2}.
+
+@item T @var{length1} , @var{length2} @key{NL} @var{string1} @var{string2} @key{NL}
+Defines, though @code{pushdef}, a definition for @var{string1}
+expanding to the text given by @var{string2}.
+
+@item D @var{number}, @var{length} @key{NL} @var{string} @key{NL}
+Selects diversion @var{number}, making it current, then copy
+@var{string} in the current diversion. @var{number} may be a negative
+number for a non-existing diversion. To merely specify an active
+selection, use this command with an empty @var{string}. With 0 as the
+diversion @var{number}, @var{string} will be issued on standard output
+at reload time, however this may not be produced from within @code{m4}.
+
+@end table
+
+@node Compatibility, Concept index, Frozen files, Top
+@chapter Compatibility with other versions of @code{m4}
+
+@cindex compatibility
+This chapter describes the differences between this implementation of
+@code{m4}, and the implementation found under UNIX, notably System V,
+Release 3.
+
+There are also differences in BSD flavors of @code{m4}. No attempt
+is made to summarize these here.
+
+@menu
+* Extensions:: Extensions in GNU m4
+* Incompatibilities:: Facilities in System V m4 not in GNU m4
+* Other Incompat:: Other incompatibilities
+@end menu
+
+@node Extensions, Incompatibilities, Compatibility, Compatibility
+@section Extensions in GNU @code{m4}
+
+@cindex GNU extensions
+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 @samp{-G} command line option, unless overridden by other
+command line options.
+
+@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}).
+
+@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 @samp{-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.
+
+@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 current input file and the current input line number are
+accessible through the builtins @code{__file__} and @code{__line__}
+(@pxref{Errprint}).
+
+@item
+The format of the output from @code{dumpdef} and macro tracing can be
+controlled with @code{debugmode} (@pxref{Debug Levels}).
+
+@item
+The destination of trace and debug output can be controlled with
+@code{debugfile} (@pxref{Debug Output}).
+@end itemize
+
+In addition to the above extensions, GNU @code{m4} implements the
+following command line options: @samp{-F}, @samp{-G}, @samp{-I},
+@samp{-L}, @samp{-R}, @samp{-V}, @samp{-W}, @samp{-d},
+@samp{-l}, @samp{-o} and @samp{-t}. @xref{Invoking m4}, for a
+description of these options.
+
+Also, the debugging and tracing facilities in GNU @code{m4} are much
+more extensive than in most other versions of @code{m4}.
+
+@node Incompatibilities, Other Incompat, Extensions, Compatibility
+@section Facilities in System V @code{m4} not in GNU @code{m4}
+
+The version of @code{m4} from System V contains a few facilities that
+have not been implemented in GNU @code{m4} yet.
+
+@itemize @bullet
+@item
+System V @code{m4} supports multiple arguments to @code{defn}. This is
+not implemented in GNU @code{m4}. Its usefulness is unclear to me.
+@end itemize
+
+@node Other Incompat, , Incompatibilities, Compatibility
+@section Other incompatibilities
+
+There are a few other incompatibilities between this implementation of
+@code{m4}, and the System V version.
+
+@itemize @bullet
+@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 filenames 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.
+
+I expect the sync line option to be 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 were made, and not where it was inserted again.
+
+@item
+GNU @code{m4} makes no attempt at prohiting autoreferential definitions
+like:
+
+@comment ignore
+@example
+define(`x', `x')
+define(`x', `x ')
+@end example
+
+There is nothing inherently wrong with defining @samp{x} to
+return @samp{x}. The wrong thing is to expand @samp{x} unquoted.
+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 leave 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
+@findex gnu
+GNU @code{m4} without @samp{-G} option will define the macro
+@code{__gnu__} to expand to the empty string.
+
+@findex unix
+On UNIX systems, GNU @code{m4} without the @samp{-G} option will define
+the macro @code{__unix__}, otherwise the macro @code{unix}. Both will
+expand to the empty string.
+@end itemize
+
+@node Concept index, Macro index, Compatibility, Top
+@unnumbered Concept index
+
+@printindex cp
+
+@node Macro index, , Concept index, Top
+@unnumbered Macro index
+
+References are exclusively to the places where a builtin is introduced
+the first time. Names starting and ending with @samp{__} have these
+characters removed in the index.
+
+@iftex
+@sp 1
+@end iftex
+
+@printindex fn
+
+@summarycontents
+@contents
+@bye
diff --git a/doc/mdate-sh b/doc/mdate-sh
new file mode 100644
index 00000000..37171f21
--- /dev/null
+++ b/doc/mdate-sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+# Get modification time of a file or directory and pretty-print it.
+# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+# written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, June 1995
+#
+# 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 2, 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, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# Prevent date giving response in another language.
+LANG=C
+export LANG
+LC_ALL=C
+export LC_ALL
+LC_TIME=C
+export LC_TIME
+
+# Get the extended ls output of the file or directory.
+# On HPUX /bin/sh, "set" interprets "-rw-r--r--" as options, so the "x" below.
+if ls -L /dev/null 1>/dev/null 2>&1; then
+ set - x`ls -L -l -d $1`
+else
+ set - x`ls -l -d $1`
+fi
+# The month is at least the fourth argument
+# (3 shifts here, the next inside the loop).
+shift
+shift
+shift
+
+# Find the month. Next argument is day, followed by the year or time.
+month=
+until test $month
+do
+ shift
+ case $1 in
+ Jan) month=January; nummonth=1;;
+ Feb) month=February; nummonth=2;;
+ Mar) month=March; nummonth=3;;
+ Apr) month=April; nummonth=4;;
+ May) month=May; nummonth=5;;
+ Jun) month=June; nummonth=6;;
+ Jul) month=July; nummonth=7;;
+ Aug) month=August; nummonth=8;;
+ Sep) month=September; nummonth=9;;
+ Oct) month=October; nummonth=10;;
+ Nov) month=November; nummonth=11;;
+ Dec) month=December; nummonth=12;;
+ esac
+done
+
+day=$2
+
+# Here we have to deal with the problem that the ls output gives either
+# the time of day or the year.
+case $3 in
+ *:*) set `date`; eval year=\$$#
+ case $2 in
+ Jan) nummonthtod=1;;
+ Feb) nummonthtod=2;;
+ Mar) nummonthtod=3;;
+ Apr) nummonthtod=4;;
+ May) nummonthtod=5;;
+ Jun) nummonthtod=6;;
+ Jul) nummonthtod=7;;
+ Aug) nummonthtod=8;;
+ Sep) nummonthtod=9;;
+ Oct) nummonthtod=10;;
+ Nov) nummonthtod=11;;
+ Dec) nummonthtod=12;;
+ esac
+ # For the first six month of the year the time notation can also
+ # be used for files modified in the last year.
+ if (expr $nummonth \> $nummonthtod) > /dev/null;
+ then
+ year=`expr $year - 1`
+ fi;;
+ *) year=$3;;
+esac
+
+# The result.
+echo $day $month $year
diff --git a/doc/stamp-vti b/doc/stamp-vti
new file mode 100644
index 00000000..61e47e5d
--- /dev/null
+++ b/doc/stamp-vti
@@ -0,0 +1 @@
+Sat Nov 5 22:46:26 EST 1994
diff --git a/doc/texinfo.tex b/doc/texinfo.tex
new file mode 100644
index 00000000..93bc18f6
--- /dev/null
+++ b/doc/texinfo.tex
@@ -0,0 +1,4365 @@
+%% TeX macros to handle texinfo files
+
+% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 1994 Free Software Foundation, Inc.
+
+%This texinfo.tex 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 2, or (at
+%your option) any later version.
+
+%This texinfo.tex 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 texinfo.tex file; see the file COPYING. If not, write
+%to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
+%USA.
+
+
+%In other words, you are welcome to use, share and improve this program.
+%You are forbidden to forbid anyone else to use, share and improve
+%what you give them. Help stamp out software-hoarding!
+
+% This automatically updates the version number based on RCS.
+\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
+\deftexinfoversion$Revision$
+\message{Loading texinfo package [Version \texinfoversion]:}
+
+% Print the version number if in a .fmt file.
+\everyjob{\message{[Texinfo version \texinfoversion]}\message{}}
+
+% Save some parts of plain tex whose names we will redefine.
+
+\let\ptextilde=\~
+\let\ptexlbrace=\{
+\let\ptexrbrace=\}
+\let\ptexdots=\dots
+\let\ptexdot=\.
+\let\ptexstar=\*
+\let\ptexend=\end
+\let\ptexbullet=\bullet
+\let\ptexb=\b
+\let\ptexc=\c
+\let\ptexi=\i
+\let\ptext=\t
+\let\ptexl=\l
+\let\ptexL=\L
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ \gdef\tie{\leavevmode\penalty\@M\ }
+}
+\let\~ = \tie % And make it available as @~.
+
+\message{Basics,}
+\chardef\other=12
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Set up fixed words for English.
+\ifx\putwordChapter\undefined{\gdef\putwordChapter{Chapter}}\fi%
+\def\putwordInfo{Info}%
+\ifx\putwordSee\undefined{\gdef\putwordSee{See}}\fi%
+\ifx\putwordsee\undefined{\gdef\putwordsee{see}}\fi%
+\ifx\putwordfile\undefined{\gdef\putwordfile{file}}\fi%
+\ifx\putwordpage\undefined{\gdef\putwordpage{page}}\fi%
+\ifx\putwordsection\undefined{\gdef\putwordsection{section}}\fi%
+\ifx\putwordSection\undefined{\gdef\putwordSection{Section}}\fi%
+\ifx\putwordTableofContents\undefined{\gdef\putwordTableofContents{Table of Contents}}\fi%
+\ifx\putwordShortContents\undefined{\gdef\putwordShortContents{Short Contents}}\fi%
+\ifx\putwordAppendix\undefined{\gdef\putwordAppendix{Appendix}}\fi%
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+\hyphenation{ap-pen-dix}
+\hyphenation{mini-buf-fer mini-buf-fers}
+\hyphenation{eshell}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen \bindingoffset \bindingoffset=0pt
+\newdimen \normaloffset \normaloffset=\hoffset
+\newdimen\pagewidth \newdimen\pageheight
+\pagewidth=\hsize \pageheight=\vsize
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{\tracingcommands2 \tracingstats2
+ \tracingpages1 \tracingoutput1 \tracinglostchars1
+ \tracingmacros2 \tracingparagraphs1 \tracingrestores1
+ \showboxbreadth\maxdimen\showboxdepth\maxdimen
+}%
+
+%---------------------Begin change-----------------------
+%
+%%%% For @cropmarks command.
+% Dimensions to add cropmarks at corners Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\cornerlong \newdimen\cornerthick
+\newdimen \topandbottommargin
+\newdimen \outerhsize \newdimen \outervsize
+\cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks
+\outerhsize=7in
+%\outervsize=9.5in
+% Alternative @smallbook page size is 9.25in
+\outervsize=9.25in
+\topandbottommargin=.75in
+%
+%---------------------End change-----------------------
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions itself, but you have to call it yourself.
+\chardef\PAGE=255 \output={\onepageout{\pagecontents\PAGE}}
+\def\onepageout#1{\hoffset=\normaloffset
+\ifodd\pageno \advance\hoffset by \bindingoffset
+\else \advance\hoffset by -\bindingoffset\fi
+{\escapechar=`\\\relax % makes sure backslash is used in output files.
+\shipout\vbox{{\let\hsize=\pagewidth \makeheadline} \pagebody{#1}%
+{\let\hsize=\pagewidth \makefootline}}}%
+\advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
+
+%%%% For @cropmarks command %%%%
+
+% Here is a modification of the main output routine for Near East Publications
+% This provides right-angle cropmarks at all four corners.
+% The contents of the page are centerlined into the cropmarks,
+% and any desired binding offset is added as an \hskip on either
+% site of the centerlined box. (P. A. MacKay, 12 November, 1986)
+%
+\def\croppageout#1{\hoffset=0pt % make sure this doesn't mess things up
+{\escapechar=`\\\relax % makes sure backslash is used in output files.
+ \shipout
+ \vbox to \outervsize{\hsize=\outerhsize
+ \vbox{\line{\ewtop\hfill\ewtop}}
+ \nointerlineskip
+ \line{\vbox{\moveleft\cornerthick\nstop}
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}}
+ \vskip \topandbottommargin
+ \centerline{\ifodd\pageno\hskip\bindingoffset\fi
+ \vbox{
+ {\let\hsize=\pagewidth \makeheadline}
+ \pagebody{#1}
+ {\let\hsize=\pagewidth \makefootline}}
+ \ifodd\pageno\else\hskip\bindingoffset\fi}
+ \vskip \topandbottommargin plus1fill minus1fill
+ \boxmaxdepth\cornerthick
+ \line{\vbox{\moveleft\cornerthick\nsbot}
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}}
+ \nointerlineskip
+ \vbox{\line{\ewbot\hfill\ewbot}}
+ }}
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
+%
+% Do @cropmarks to get crop marks
+\def\cropmarks{\let\onepageout=\croppageout }
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+%
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg#1{%
+ \let\next = #1%
+ \begingroup
+ \obeylines
+ \futurelet\temp\parseargx
+}
+
+% If the next token is an obeyed space (from an @example environment or
+% the like), remove it and recurse. Otherwise, we're done.
+\def\parseargx{%
+ % \obeyedspace is defined far below, after the definition of \sepspaces.
+ \ifx\obeyedspace\temp
+ \expandafter\parseargdiscardspace
+ \else
+ \expandafter\parseargline
+ \fi
+}
+
+% Remove a single space (as the delimiter token to the macro call).
+{\obeyspaces %
+ \gdef\parseargdiscardspace {\futurelet\temp\parseargx}}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ %
+ % First remove any @c comment, then any @comment.
+ % Result of each macro is put in \toks0.
+ \argremovec #1\c\relax %
+ \expandafter\argremovecomment \the\toks0 \comment\relax %
+ %
+ % Call the caller's macro, saved as \next in \parsearg.
+ \expandafter\next\expandafter{\the\toks0}%
+ }%
+}
+
+% Since all \c{,omment} does is throw away the argument, we can let TeX
+% do that for us. The \relax here is matched by the \relax in the call
+% in \parseargline; it could be more or less anything, its purpose is
+% just to delimit the argument to the \c.
+\def\argremovec#1\c#2\relax{\toks0 = {#1}}
+\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}}
+
+% \argremovec{,omment} might leave us with trailing spaces, though; e.g.,
+% @end itemize @c foo
+% will have two active spaces as part of the argument with the
+% `itemize'. Here we remove all active spaces from #1, and assign the
+% result to \toks0.
+%
+% This loses if there are any *other* active characters besides spaces
+% in the argument -- _ ^ +, for example -- since they get expanded.
+% Fortunately, Texinfo does not define any such commands. (If it ever
+% does, the catcode of the characters in questionwill have to be changed
+% here.) But this means we cannot call \removeactivespaces as part of
+% \argremovec{,omment}, since @c uses \parsearg, and thus the argument
+% that \parsearg gets might well have any character at all in it.
+%
+\def\removeactivespaces#1{%
+ \begingroup
+ \ignoreactivespaces
+ \edef\temp{#1}%
+ \global\toks0 = \expandafter{\temp}%
+ \endgroup
+}
+
+% Change the active space to expand to nothing.
+%
+\begingroup
+ \obeyspaces
+ \gdef\ignoreactivespaces{\obeyspaces\let =\empty}
+\endgroup
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+%% These are used to keep @begin/@end levels from running away
+%% Call \inENV within environments (after a \begingroup)
+\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi}
+\def\ENVcheck{%
+\ifENV\errmessage{Still within an environment. Type Return to continue.}
+\endgroup\fi} % This is not perfect, but it should reduce lossage
+
+% @begin foo is the same as @foo, for now.
+\newhelp\EMsimple{Type <Return> to continue.}
+
+\outer\def\begin{\parsearg\beginxxx}
+
+\def\beginxxx #1{%
+\expandafter\ifx\csname #1\endcsname\relax
+{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else
+\csname #1\endcsname\fi}
+
+% @end foo executes the definition of \Efoo.
+%
+\def\end{\parsearg\endxxx}
+\def\endxxx #1{%
+ \removeactivespaces{#1}%
+ \edef\endthing{\the\toks0}%
+ %
+ \expandafter\ifx\csname E\endthing\endcsname\relax
+ \expandafter\ifx\csname \endthing\endcsname\relax
+ % There's no \foo, i.e., no ``environment'' foo.
+ \errhelp = \EMsimple
+ \errmessage{Undefined command `@end \endthing'}%
+ \else
+ \unmatchedenderror\endthing
+ \fi
+ \else
+ % Everything's ok; the right environment has been started.
+ \csname E\endthing\endcsname
+ \fi
+}
+
+% There is an environment #1, but it hasn't been started. Give an error.
+%
+\def\unmatchedenderror#1{%
+ \errhelp = \EMsimple
+ \errmessage{This `@end #1' doesn't have a matching `@#1'}%
+}
+
+% Define the control sequence \E#1 to give an unmatched @end error.
+%
+\def\defineunmatchedend#1{%
+ \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}%
+}
+
+
+% Single-spacing is done by various environments (specifically, in
+% \nonfillstart and \quotations).
+\newskip\singlespaceskip \singlespaceskip = 12.5pt
+\def\singlespace{%
+ % Why was this kern here? It messes up equalizing space above and below
+ % environments. --karl, 6may93
+ %{\advance \baselineskip by -\singlespaceskip
+ %\kern \baselineskip}%
+ \setleading \singlespaceskip
+}
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt \char '100}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+
+\def\mylbrace {{\tt \char '173}}
+\def\myrbrace {{\tt \char '175}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=3000 }
+
+% @enddots{} is an end-of-sentence ellipsis.
+\gdef\enddots{$\mathinner{\ldotp\ldotp\ldotp\ldotp}$\spacefactor=3000}
+
+% @! is an end-of-sentence bang.
+\gdef\!{!\spacefactor=3000 }
+
+% @? is an end-of-sentence query.
+\gdef\?{?\spacefactor=3000 }
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+\def\group{\begingroup
+ \ifnum\catcode13=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ %
+ % The \vtop we start below produces a box with normal height and large
+ % depth; thus, TeX puts \baselineskip glue before it, and (when the
+ % next line of text is done) \lineskip glue after it. (See p.82 of
+ % the TeXbook.) Thus, space below is not quite equal to space
+ % above. But it's pretty close.
+ \def\Egroup{%
+ \egroup % End the \vtop.
+ \endgroup % End the \group.
+ }%
+ %
+ \vtop\bgroup
+ % We have to put a strut on the last line in case the @group is in
+ % the midst of an example, rather than completely enclosing it.
+ % Otherwise, the interline space between the last line of the group
+ % and the first line afterwards is too small. But we can't put the
+ % strut in \Egroup, since there it would be on a line by itself.
+ % Hence this just inserts a strut at the beginning of each line.
+ \everypar = {\strut}%
+ %
+ % Since we have a strut on every line, we don't need any of TeX's
+ % normal interline spacing.
+ \offinterlineskip
+ %
+ % OK, but now we have to do something about blank
+ % lines in the input in @example-like environments, which normally
+ % just turn into \lisppar, which will insert no space now that we've
+ % turned off the interline space. Simplest is to make them be an
+ % empty paragraph.
+ \ifx\par\lisppar
+ \edef\par{\leavevmode \par}%
+ %
+ % Reset ^^M's definition to new definition of \par.
+ \obeylines
+ \fi
+ %
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+\def\need{\parsearg\needx}
+
+% Old definition--didn't work.
+%\def\needx #1{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000
+%\prevdepth=-1000pt
+%}}
+
+\def\needx#1{%
+ % Go into vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % Don't add any leading before our big empty box, but allow a page
+ % break, since the best break might be right here.
+ \allowbreak
+ \nointerlineskip
+ \vtop to #1\mil{\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+}
+
+% @br forces paragraph break
+
+\let\br = \par
+
+% @dots{} output some dots
+
+\def\dots{$\ldots$}
+
+% @page forces the start of a new page
+
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\def\exdent{\parsearg\exdentyyy}
+\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}}
+
+% This defn is used inside nofill environments such as @example.
+\def\nofillexdent{\parsearg\nofillexdentyyy}
+\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount
+\leftline{\hskip\leftskip{\rm#1}}}}
+
+%\hbox{{\rm#1}}\hfil\break}}
+
+% @include file insert text of that file as input.
+
+\def\include{\parsearg\includezzz}
+%Use \input\thisfile to avoid blank after \input, which may be an active
+%char (in which case the blank would become the \input argument).
+%The grouping keeps the value of \thisfile correct even when @include
+%is nested.
+\def\includezzz #1{\begingroup
+\def\thisfile{#1}\input\thisfile
+\endgroup}
+
+\def\thisfile{}
+
+% @center line outputs that line, centered
+
+\def\center{\parsearg\centerzzz}
+\def\centerzzz #1{{\advance\hsize by -\leftskip
+\advance\hsize by -\rightskip
+\centerline{#1}}}
+
+% @sp n outputs n lines of vertical space
+
+\def\sp{\parsearg\spxxx}
+\def\spxxx #1{\par \vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+
+\def\comment{\catcode 64=\other \catcode 123=\other \catcode 125=\other%
+\parsearg \commentxxx}
+
+\def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 }
+
+\let\c=\comment
+
+% Prevent errors for section commands.
+% Used in @ignore and in failing conditionals.
+\def\ignoresections{%
+\let\chapter=\relax
+\let\unnumbered=\relax
+\let\top=\relax
+\let\unnumberedsec=\relax
+\let\unnumberedsection=\relax
+\let\unnumberedsubsec=\relax
+\let\unnumberedsubsection=\relax
+\let\unnumberedsubsubsec=\relax
+\let\unnumberedsubsubsection=\relax
+\let\section=\relax
+\let\subsec=\relax
+\let\subsubsec=\relax
+\let\subsection=\relax
+\let\subsubsection=\relax
+\let\appendix=\relax
+\let\appendixsec=\relax
+\let\appendixsection=\relax
+\let\appendixsubsec=\relax
+\let\appendixsubsection=\relax
+\let\appendixsubsubsec=\relax
+\let\appendixsubsubsection=\relax
+\let\contents=\relax
+\let\smallbook=\relax
+\let\titlepage=\relax
+}
+
+% Used in nested conditionals, where we have to parse the Texinfo source
+% and so want to turn off most commands, in case they are used
+% incorrectly.
+%
+\def\ignoremorecommands{%
+ \let\defcv = \relax
+ \let\deffn = \relax
+ \let\deffnx = \relax
+ \let\defindex = \relax
+ \let\defivar = \relax
+ \let\defmac = \relax
+ \let\defmethod = \relax
+ \let\defop = \relax
+ \let\defopt = \relax
+ \let\defspec = \relax
+ \let\deftp = \relax
+ \let\deftypefn = \relax
+ \let\deftypefun = \relax
+ \let\deftypevar = \relax
+ \let\deftypevr = \relax
+ \let\defun = \relax
+ \let\defvar = \relax
+ \let\defvr = \relax
+ \let\ref = \relax
+ \let\xref = \relax
+ \let\printindex = \relax
+ \let\pxref = \relax
+ \let\settitle = \relax
+ \let\include = \relax
+ \let\lowersections = \relax
+ \let\down = \relax
+ \let\raisesections = \relax
+ \let\up = \relax
+ \let\set = \relax
+ \let\clear = \relax
+ \let\item = \relax
+ \let\message = \relax
+}
+
+% Ignore @ignore ... @end ignore.
+%
+\def\ignore{\doignore{ignore}}
+
+% Also ignore @ifinfo, @ifhtml, @html, @menu, and @direntry text.
+%
+\def\ifinfo{\doignore{ifinfo}}
+\def\ifhtml{\doignore{ifhtml}}
+\def\html{\doignore{html}}
+\def\menu{\doignore{menu}}
+\def\direntry{\doignore{direntry}}
+
+% Ignore text until a line `@end #1'.
+%
+\def\doignore#1{\begingroup
+ % Don't complain about control sequences we have declared \outer.
+ \ignoresections
+ %
+ % Define a command to swallow text until we reach `@end #1'.
+ \long\def\doignoretext##1\end #1{\enddoignore}%
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \catcode32 = 10
+ %
+ % And now expand that command.
+ \doignoretext
+}
+
+% What we do to finish off ignored text.
+%
+\def\enddoignore{\endgroup\ignorespaces}%
+
+\newif\ifwarnedobs\warnedobsfalse
+\def\obstexwarn{%
+ \ifwarnedobs\relax\else
+ % We need to warn folks that they may have trouble with TeX 3.0.
+ % This uses \immediate\write16 rather than \message to get newlines.
+ \immediate\write16{}
+ \immediate\write16{***WARNING*** for users of Unix TeX 3.0!}
+ \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).}
+ \immediate\write16{If you are running another version of TeX, relax.}
+ \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.}
+ \immediate\write16{ Then upgrade your TeX installation if you can.}
+ \immediate\write16{If you are stuck with version 3.0, run the}
+ \immediate\write16{ script ``tex3patch'' from the Texinfo distribution}
+ \immediate\write16{ to use a workaround.}
+ \immediate\write16{}
+ \warnedobstrue
+ \fi
+}
+
+% **In TeX 3.0, setting text in \nullfont hangs tex. For a
+% workaround (which requires the file ``dummy.tfm'' to be installed),
+% uncomment the following line:
+%%%%%\font\nullfont=dummy\let\obstexwarn=\relax
+
+% Ignore text, except that we keep track of conditional commands for
+% purposes of nesting, up to an `@end #1' command.
+%
+\def\nestedignore#1{%
+ \obstexwarn
+ % We must actually expand the ignored text to look for the @end
+ % command, so that nested ignore constructs work. Thus, we put the
+ % text into a \vbox and then do nothing with the result. To minimize
+ % the change of memory overflow, we follow the approach outlined on
+ % page 401 of the TeXbook: make the current font be a dummy font.
+ %
+ \setbox0 = \vbox\bgroup
+ % Don't complain about control sequences we have declared \outer.
+ \ignoresections
+ %
+ % Define `@end #1' to end the box, which will in turn undefine the
+ % @end command again.
+ \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}%
+ %
+ % We are going to be parsing Texinfo commands. Most cause no
+ % trouble when they are used incorrectly, but some commands do
+ % complicated argument parsing or otherwise get confused, so we
+ % undefine them.
+ %
+ % We can't do anything about stray @-signs, unfortunately;
+ % they'll produce `undefined control sequence' errors.
+ \ignoremorecommands
+ %
+ % Set the current font to be \nullfont, a TeX primitive, and define
+ % all the font commands to also use \nullfont. We don't use
+ % dummy.tfm, as suggested in the TeXbook, because not all sites
+ % might have that installed. Therefore, math mode will still
+ % produce output, but that should be an extremely small amount of
+ % stuff compared to the main input.
+ %
+ \nullfont
+ \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont
+ \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont
+ \let\tensf = \nullfont
+ % Similarly for index fonts (mostly for their use in
+ % smallexample)
+ \let\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont
+ \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont
+ \let\indsf = \nullfont
+ %
+ % Don't complain when characters are missing from the fonts.
+ \tracinglostchars = 0
+ %
+ % Don't bother to do space factor calculations.
+ \frenchspacing
+ %
+ % Don't report underfull hboxes.
+ \hbadness = 10000
+ %
+ % Do minimal line-breaking.
+ \pretolerance = 10000
+ %
+ % Do not execute instructions in @tex
+ \def\tex{\doignore{tex}}
+}
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+%
+\def\set{\parsearg\setxxx}
+\def\setxxx#1{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ \def\temp{#2}%
+ \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty
+ \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted.
+ \fi
+}
+\def\setzzz#1#2 \endsetzzz{\expandafter\xdef\csname SET#1\endcsname{#2}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\def\clear{\parsearg\clearxxx}
+\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax}
+
+% @value{foo} gets the text saved in variable foo.
+%
+\def\value#1{\expandafter
+ \ifx\csname SET#1\endcsname\relax
+ {\{No value for ``#1''\}}
+ \else \csname SET#1\endcsname \fi}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+\def\ifset{\parsearg\ifsetxxx}
+\def\ifsetxxx #1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ \expandafter\ifsetfail
+ \else
+ \expandafter\ifsetsucceed
+ \fi
+}
+\def\ifsetsucceed{\conditionalsucceed{ifset}}
+\def\ifsetfail{\nestedignore{ifset}}
+\defineunmatchedend{ifset}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+\def\ifclear{\parsearg\ifclearxxx}
+\def\ifclearxxx #1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ \expandafter\ifclearsucceed
+ \else
+ \expandafter\ifclearfail
+ \fi
+}
+\def\ifclearsucceed{\conditionalsucceed{ifclear}}
+\def\ifclearfail{\nestedignore{ifclear}}
+\defineunmatchedend{ifclear}
+
+% @iftex always succeeds; we read the text following, through @end
+% iftex). But `@end iftex' should be valid only after an @iftex.
+%
+\def\iftex{\conditionalsucceed{iftex}}
+\defineunmatchedend{iftex}
+
+% We can't just want to start a group at @iftex (for example) and end it
+% at @end iftex, since then @set commands inside the conditional have no
+% effect (they'd get reverted at the end of the group). So we must
+% define \Eiftex to redefine itself to be its previous value. (We can't
+% just define it to fail again with an ``unmatched end'' error, since
+% the @ifset might be nested.)
+%
+\def\conditionalsucceed#1{%
+ \edef\temp{%
+ % Remember the current value of \E#1.
+ \let\nece{prevE#1} = \nece{E#1}%
+ %
+ % At the `@end #1', redefine \E#1 to be its previous value.
+ \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}%
+ }%
+ \temp
+}
+
+% We need to expand lots of \csname's, but we don't want to expand the
+% control sequences after we've constructed them.
+%
+\def\nece#1{\expandafter\noexpand\csname#1\endcsname}
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math means output in math mode.
+% We don't use $'s directly in the definition of \math because control
+% sequences like \math are expanded when the toc file is written. Then,
+% we read the toc file back, the $'s will be normal characters (as they
+% should be, according to the definition of Texinfo). So we must use a
+% control sequence to switch into and out of math mode.
+%
+% This isn't quite enough for @math to work properly in indices, but it
+% seems unlikely it will ever be needed there.
+%
+\let\implicitmath = $
+\def\math#1{\implicitmath #1\implicitmath}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{\implicitmath\ptexbullet\implicitmath}
+\def\minus{\implicitmath-\implicitmath}
+
+\def\node{\ENVcheck\parsearg\nodezzz}
+\def\nodezzz#1{\nodexxx [#1,]}
+\def\nodexxx[#1,#2]{\gdef\lastnode{#1}}
+\let\nwnode=\node
+\let\lastnode=\relax
+
+\def\donoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\setref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\def\unnumbnoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\def\appendixnoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\let\refill=\relax
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \readauxfile
+ \opencontents
+ \openindices
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \global\let\setfilename=\comment % Ignore extra @setfilename cmds.
+ \comment % Ignore the actual filename.
+}
+
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+\message{fonts,}
+
+% Font-change commands.
+
+% Texinfo supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf analogous to plain's \rm, etc.
+\newfam\sffam
+\def\sf{\fam=\sffam \tensf}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+%% Try out Computer Modern fonts at \magstephalf
+\let\mainmagstep=\magstephalf
+
+% Set the font macro #1 to the font named #2, adding on the
+% specified font prefix (normally `cm').
+\def\fontprefix{cm}
+\def\setfont#1#2{\font#1=\fontprefix#2}
+
+% Enter `@setfontprefix dc' to use the dc fonts instead of the cm fonts.
+\def\setfontprefix{\parsearg\\setfontprefixzzz}
+\def\setfontprefixzzz#1{\gdef\fontprefix{#1}}
+
+\ifx\bigger\relax
+\let\mainmagstep=\magstep1
+\setfont\textrm{r12}
+\setfont\texttt{tt12}
+\else
+\setfont\textrm{r10 scaled \mainmagstep}
+\setfont\texttt{tt10 scaled \mainmagstep}
+\fi
+% Instead of cmb10, you many want to use cmbx10.
+% cmbx10 is a prettier font on its own, but cmb10
+% looks better when embedded in a line with cmr10.
+\setfont\textbf{b10 scaled \mainmagstep}
+\setfont\textit{ti10 scaled \mainmagstep}
+\setfont\textsl{sl10 scaled \mainmagstep}
+\setfont\textsf{ss10 scaled \mainmagstep}
+\setfont\textsc{csc10 scaled \mainmagstep}
+\setfont\texti{mi10 scaled \mainmagstep}
+\setfont\textsy{sy10 scaled \mainmagstep}
+
+% A few fonts for @defun, etc.
+\setfont\defbf{bx10 scaled \magstep1} %was 1314
+\setfont\deftt{tt10 scaled \magstep1}
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
+
+% Fonts for indices and small examples.
+% We actually use the slanted font rather than the italic,
+% because texinfo normally uses the slanted fonts for that.
+% Do not make many font distinctions in general in the index, since they
+% aren't very useful.
+\setfont\ninett{tt9}
+\setfont\indrm{r9}
+\setfont\indit{sl9}
+\let\indsl=\indit
+\let\indtt=\ninett
+\let\indsf=\indrm
+\let\indbf=\indrm
+\let\indsc=\indrm
+\setfont\indi{mi9}
+\setfont\indsy{sy9}
+
+% Fonts for headings
+\setfont\chaprm{bx12 scaled \magstep2}
+\setfont\chapit{ti12 scaled \magstep2}
+\setfont\chapsl{sl12 scaled \magstep2}
+\setfont\chaptt{tt12 scaled \magstep2}
+\setfont\chapsf{ss12 scaled \magstep2}
+\let\chapbf=\chaprm
+\setfont\chapsc{csc10 scaled\magstep3}
+\setfont\chapi{mi12 scaled \magstep2}
+\setfont\chapsy{sy10 scaled \magstep3}
+
+\setfont\secrm{bx12 scaled \magstep1}
+\setfont\secit{ti12 scaled \magstep1}
+\setfont\secsl{sl12 scaled \magstep1}
+\setfont\sectt{tt12 scaled \magstep1}
+\setfont\secsf{ss12 scaled \magstep1}
+\setfont\secbf{bx12 scaled \magstep1}
+\setfont\secsc{csc10 scaled\magstep2}
+\setfont\seci{mi12 scaled \magstep1}
+\setfont\secsy{sy10 scaled \magstep2}
+
+% \setfont\ssecrm{bx10 scaled \magstep1} % This size an font looked bad.
+% \setfont\ssecit{cmti10 scaled \magstep1} % The letters were too crowded.
+% \setfont\ssecsl{sl10 scaled \magstep1}
+% \setfont\ssectt{tt10 scaled \magstep1}
+% \setfont\ssecsf{ss10 scaled \magstep1}
+
+%\setfont\ssecrm{b10 scaled 1315} % Note the use of cmb rather than cmbx.
+%\setfont\ssecit{ti10 scaled 1315} % Also, the size is a little larger than
+%\setfont\ssecsl{sl10 scaled 1315} % being scaled magstep1.
+%\setfont\ssectt{tt10 scaled 1315}
+%\setfont\ssecsf{ss10 scaled 1315}
+
+%\let\ssecbf=\ssecrm
+
+\setfont\ssecrm{bx12 scaled \magstephalf}
+\setfont\ssecit{ti12 scaled \magstephalf}
+\setfont\ssecsl{sl12 scaled \magstephalf}
+\setfont\ssectt{tt12 scaled \magstephalf}
+\setfont\ssecsf{ss12 scaled \magstephalf}
+\setfont\ssecbf{bx12 scaled \magstephalf}
+\setfont\ssecsc{csc10 scaled \magstep1}
+\setfont\sseci{mi12 scaled \magstephalf}
+\setfont\ssecsy{sy10 scaled \magstep1}
+% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
+% but that is not a standard magnification.
+
+% Fonts for title page:
+\setfont\titlerm{bx12 scaled \magstep3}
+\let\authorrm = \secrm
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts, we
+% don't bother to reset \scriptfont and \scriptscriptfont (which would
+% also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy
+ \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf
+ \textfont\ttfam = \tentt \textfont\sffam = \tensf
+}
+
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this so that font changes will continue to work
+% in math mode, where it is the current \fam that is relevant in most
+% cases, not the current. Plain TeX does, for example,
+% \def\bf{\fam=\bffam \tenbf} By redefining \tenbf, we obviate the need
+% to redefine \bf itself.
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \resetmathfonts}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+ \resetmathfonts}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+ \resetmathfonts}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+ \resetmathfonts}
+\def\indexfonts{%
+ \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl
+ \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc
+ \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy
+ \resetmathfonts}
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\textfonts
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\setfont\shortcontrm{r12}
+\setfont\shortcontbf{bx12}
+\setfont\shortcontsl{sl12}
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi}
+\def\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\var=\smartitalic
+\let\dfn=\smartitalic
+\let\emph=\smartitalic
+\let\cite=\smartitalic
+
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+\def\t#1{%
+ {\tt \nohyphenation \rawbackslash \frenchspacing #1}%
+ \null
+}
+\let\ttfont = \t
+%\def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null}
+\def\samp #1{`\tclose{#1}'\null}
+\def\key #1{{\tt \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+\let\file=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \frenchspacing
+ #1%
+ }%
+ \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in \code.
+% Otherwise, it is too hard to avoid overful hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate an a dash.
+% -- rms.
+{
+\catcode`\-=\active
+\catcode`\_=\active
+\global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex}
+% The following is used by \doprintindex to insure that long function names
+% wrap around. It is necessary for - and _ to be active before the index is
+% read from the file, as \entry parses the arguments long before \code is
+% ever called. -- mycroft
+\global\def\indexbreaks{\catcode`\-=\active \let-\realdash \catcode`\_=\active \let_\realunder}
+}
+\def\realdash{-}
+\def\realunder{_}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{\normalunderscore\discretionary{}{}{}}
+\def\codex #1{\tclose{#1}\endgroup}
+
+%\let\exp=\tclose %Was temporary
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else\tclose{\look}\fi
+\else\tclose{\look}\fi}
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of
+% @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+\def\l#1{{\li #1}\null} %
+
+\def\r#1{{\rm #1}} % roman font
+% Use of \lowercase was suggested.
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\def\titlefont#1{{\titlerm #1}}
+
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+\def\shorttitlepage{\parsearg\shorttitlepagezzz}
+\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\def\titlepage{\begingroup \parindent=0pt \textfonts
+ \let\subtitlerm=\tenrm
+% I deinstalled the following change because \cmr12 is undefined.
+% This change was not in the ChangeLog anyway. --rms.
+% \let\subtitlerm=\cmr12
+ \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}%
+ %
+ \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}%
+ %
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ %
+ % Now you can print the title using @title.
+ \def\title{\parsearg\titlezzz}%
+ \def\titlezzz##1{\leftline{\titlefont{##1}}
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt}%
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Now you can put text using @subtitle.
+ \def\subtitle{\parsearg\subtitlezzz}%
+ \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}%
+ %
+ % @author should come last, but may come many times.
+ \def\author{\parsearg\authorzzz}%
+ \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi
+ {\authorfont \leftline{##1}}}%
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \oldpage
+ \let\page = \oldpage
+ \hbox{}}%
+% \def\page{\oldpage \hbox{}}
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ \HEADINGSon
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks \evenheadline % Token sequence for heading line of even pages
+\newtoks \oddheadline % Token sequence for heading line of odd pages
+\newtoks \evenfootline % Token sequence for footing line of even pages
+\newtoks \oddfootline % Token sequence for footing line of odd pages
+
+% Now make Tex use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\everyheading{\parsearg\everyheadingxxx}
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\everyfooting{\parsearg\everyfootingxxx}
+
+{\catcode`\@=0 %
+
+\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish}
+\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish}
+\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\everyheadingxxx #1{\everyheadingyyy #1@|@|@|@|\finish}
+\gdef\everyheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish}
+\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish}
+\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\everyfootingxxx #1{\everyfootingyyy #1@|@|@|@|\finish}
+\gdef\everyfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}
+\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+%
+}% unbind the catcode of @.
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{
+%\pagealignmacro
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+}
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{
+%\pagealignmacro
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+}
+
+% Subroutines used in generating headings
+% Produces Day Month Year style of output.
+\def\today{\number\day\space
+\ifcase\month\or
+January\or February\or March\or April\or May\or June\or
+July\or August\or September\or October\or November\or December\fi
+\space\number\year}
+
+% Use this if you want the Month Day, Year style of output.
+%\def\today{\ifcase\month\or
+%January\or February\or March\or April\or May\or June\or
+%July\or August\or September\or October\or November\or December\fi
+%\space\number\day, \number\year}
+
+% @settitle line... specifies the title of the document, for headings
+% It generates no output of its own
+
+\def\thistitle{No Title}
+\def\settitle{\parsearg\settitlezzz}
+\def\settitlezzz #1{\gdef\thistitle{#1}}
+
+\message{tables,}
+
+% @tabs -- simple alignment
+
+% These don't work. For one thing, \+ is defined as outer.
+% So these macros cannot even be defined.
+
+%\def\tabs{\parsearg\tabszzz}
+%\def\tabszzz #1{\settabs\+#1\cr}
+%\def\tabline{\parsearg\tablinezzz}
+%\def\tablinezzz #1{\+#1\cr}
+%\def\&{&}
+
+% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @vtable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz}
+\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz}
+
+\def\internalBkitem{\smallbreak \parsearg\kitemzzz}
+\def\internalBkitemx{\itemxpar \parsearg\kitemzzz}
+
+\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}%
+ \itemzzz {#1}}
+
+\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}%
+ \itemzzz {#1}}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemfont{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % Be sure we are not still in the middle of a paragraph.
+ %{\parskip = 0in
+ %\par
+ %}%
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. Unfortunately
+ % we can't prevent a possible page break at the following
+ % \baselineskip glue.
+ \nobreak
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line. Since that
+ % text will be indented by \tableindent, we make the item text be in
+ % a zero-width box.
+ \noindent
+ \rlap{\hskip -\tableindent\box0}\ignorespaces%
+ \endgroup%
+ \itemxneedsnegativevskiptrue%
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a table}}
+\def\itemx{\errmessage{@itemx while not in a table}}
+\def\kitem{\errmessage{@kitem while not in a table}}
+\def\kitemx{\errmessage{@kitemx while not in a table}}
+\def\xitem{\errmessage{@xitem while not in a table}}
+\def\xitemx{\errmessage{@xitemx while not in a table}}
+
+%% Contains a kludge to get @end[description] to work
+\def\description{\tablez{\dontindex}{1}{}{}{}{}}
+
+\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex}
+{\obeylines\obeyspaces%
+\gdef\tablex #1^^M{%
+\tabley\dontindex#1 \endtabley}}
+
+\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex}
+{\obeylines\obeyspaces%
+\gdef\ftablex #1^^M{%
+\tabley\fnitemindex#1 \endtabley
+\def\Eftable{\endgraf\afterenvbreak\endgroup}%
+\let\Etable=\relax}}
+
+\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex}
+{\obeylines\obeyspaces%
+\gdef\vtablex #1^^M{%
+\tabley\vritemindex#1 \endtabley
+\def\Evtable{\endgraf\afterenvbreak\endgroup}%
+\let\Etable=\relax}}
+
+\def\dontindex #1{}
+\def\fnitemindex #1{\doind {fn}{\code{#1}}}%
+\def\vritemindex #1{\doind {vr}{\code{#1}}}%
+
+{\obeyspaces %
+\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup%
+\tablez{#1}{#2}{#3}{#4}{#5}{#6}}}
+
+\def\tablez #1#2#3#4#5#6{%
+\aboveenvbreak %
+\begingroup %
+\def\Edescription{\Etable}% Neccessary kludge.
+\let\itemindex=#1%
+\ifnum 0#3>0 \advance \leftskip by #3\mil \fi %
+\ifnum 0#4>0 \tableindent=#4\mil \fi %
+\ifnum 0#5>0 \advance \rightskip by #5\mil \fi %
+\def\itemfont{#2}%
+\itemmax=\tableindent %
+\advance \itemmax by -\itemmargin %
+\advance \leftskip by \tableindent %
+\exdentamount=\tableindent
+\parindent = 0pt
+\parskip = \smallskipamount
+\ifdim \parskip=0pt \parskip=2pt \fi%
+\def\Etable{\endgraf\afterenvbreak\endgroup}%
+\let\item = \internalBitem %
+\let\itemx = \internalBitemx %
+\let\kitem = \internalBkitem %
+\let\kitemx = \internalBkitemx %
+\let\xitem = \internalBxitem %
+\let\xitemx = \internalBxitemx %
+}
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\def\itemize{\parsearg\itemizezzz}
+
+\def\itemizezzz #1{%
+ \begingroup % ended by the @end itemsize
+ \itemizey {#1}{\Eitemize}
+}
+
+\def\itemizey #1#2{%
+\aboveenvbreak %
+\itemmax=\itemindent %
+\advance \itemmax by -\itemmargin %
+\advance \leftskip by \itemindent %
+\exdentamount=\itemindent
+\parindent = 0pt %
+\parskip = \smallskipamount %
+\ifdim \parskip=0pt \parskip=2pt \fi%
+\def#2{\endgraf\afterenvbreak\endgroup}%
+\def\itemcontents{#1}%
+\let\item=\itemizeitem}
+
+% Set sfcode to normal for the chars that usually have another value.
+% These are `.?!:;,'
+\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000
+ \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 }
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\def\enumerate{\parsearg\enumeratezzz}
+\def\enumeratezzz #1{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ \begingroup % ended by the @end enumerate
+ %
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call itemizey, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \itemizey{#1.}\Eenumerate\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+% Definition of @item while inside @itemize.
+
+\def\itemizeitem{%
+\advance\itemno by 1
+{\let\par=\endgraf \smallbreak}%
+\ifhmode \errmessage{\in hmode at itemizeitem}\fi
+{\parskip=0in \hskip 0pt
+\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}%
+\vadjust{\penalty 1200}}%
+\flushcr}
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94
+%
+% @multitable ... @endmultitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @percentofhsize .2 .3 .5
+% @item ...
+%
+% Numbers following @percentofhsize are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab, @multicolumn or @endmulticolumn do not need to be on their
+% own lines, but it will not hurt if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @endmultitable
+
+% Default dimensions may be reset by user.
+% @intableparskip will set vertical space between paragraphs in table.
+% @intableparindent will set paragraph indent in table.
+% @spacebetweencols will set horizontal space to be left between columns.
+% @spacebetweenlines will set vertical space to be left between lines.
+
+%%%%
+% Dimensions
+
+\newdimen\intableparskip
+\newdimen\intableparindent
+\newdimen\spacebetweencols
+\newdimen\spacebetweenlines
+\intableparskip=0pt
+\intableparindent=6pt
+\spacebetweencols=12pt
+\spacebetweenlines=12pt
+
+%%%%
+% Macros used to set up halign preamble:
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\percentofhsize\relax
+\def\xpercentofhsize{\percentofhsize}
+\newif\ifsetpercent
+
+\newcount\colcount
+\def\setuptable#1{\def\firstarg{#1}%
+\ifx\firstarg\xendsetuptable\let\go\relax%
+\else
+ \ifx\firstarg\xpercentofhsize\global\setpercenttrue%
+ \else
+ \ifsetpercent
+ \if#1.\else%
+ \global\advance\colcount by1 %
+ \expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}%
+ \fi
+ \else
+ \global\advance\colcount by1
+ \setbox0=\hbox{#1}%
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi%
+ \fi%
+ \let\go\setuptable%
+\fi\go}
+%%%%
+% multitable syntax
+\def\tab{&}
+
+%%%%
+% @multitable ... @endmultitable definitions:
+
+\def\multitable#1\item{\bgroup
+\let\item\cr
+\tolerance=9500
+\hbadness=9500
+\parskip=\intableparskip
+\parindent=\intableparindent
+\overfullrule=0pt
+\global\colcount=0\relax%
+\def\Emultitable{\global\setpercentfalse\global\everycr{}\cr\egroup\egroup}%
+ % To parse everything between @multitable and @item :
+\def\one{#1}\expandafter\setuptable\one\endsetuptable
+ % Need to reset this to 0 after \setuptable.
+\global\colcount=0\relax%
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+\halign\bgroup&\global\advance\colcount by 1\relax%
+\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \spacebetweencols to all columns after
+ % the first one.
+ % If a template has been used, we will add \spacebetweencols
+ % to the width of each template entry.
+ % If user has set preamble in terms of percent of \hsize
+ % we will use that dimension as the width of the column, and
+ % the \leftskip will keep entries from bumping into each other.
+ % Table will start at left margin and final column will justify at
+ % right margin.
+\ifnum\colcount=1
+\else
+ \ifsetpercent
+ \else
+ % If user has <not> set preamble in terms of percent of \hsize
+ % we will advance \hsize by \spacebetweencols
+ \advance\hsize by \spacebetweencols
+ \fi
+ % In either case we will make \leftskip=\spacebetweencols:
+\leftskip=\spacebetweencols
+\fi
+\noindent##}\cr%
+ % \everycr will reset column counter, \colcount, at the end of
+ % each line. Every column entry will cause \colcount to advance by one.
+ % The table preamble
+ % looks at the current \colcount to find the correct column width.
+\global\everycr{\noalign{\nointerlineskip\vskip\spacebetweenlines
+\filbreak%% keeps underfull box messages off when table breaks over pages.
+\global\colcount=0\relax}}}
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within \newindex.
+{\catcode`\@=11
+\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+
+\def\newindex #1{
+\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
+\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\noexpand\doindex {#1}}
+}
+
+% @defindex foo == \newindex{foo}
+
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+
+\def\newcodeindex #1{
+\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
+\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\noexpand\docodeindex {#1}}
+}
+
+\def\defcodeindex{\parsearg\newcodeindex}
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+\def\synindex #1 #2 {%
+\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
+\expandafter\let\csname#1indfile\endcsname=\synindexfoo
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\noexpand\doindex {#2}}%
+}
+
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+\def\syncodeindex #1 #2 {%
+\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
+\expandafter\let\csname#1indfile\endcsname=\synindexfoo
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\noexpand\docodeindex {#2}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+\def\indexdummies{%
+% Take care of the plain tex accent commands.
+\def\"{\realbackslash "}%
+\def\`{\realbackslash `}%
+\def\'{\realbackslash '}%
+\def\^{\realbackslash ^}%
+\def\~{\realbackslash ~}%
+\def\={\realbackslash =}%
+\def\b{\realbackslash b}%
+\def\c{\realbackslash c}%
+\def\d{\realbackslash d}%
+\def\u{\realbackslash u}%
+\def\v{\realbackslash v}%
+\def\H{\realbackslash H}%
+% Take care of the plain tex special European modified letters.
+\def\oe{\realbackslash oe}%
+\def\ae{\realbackslash ae}%
+\def\aa{\realbackslash aa}%
+\def\OE{\realbackslash OE}%
+\def\AE{\realbackslash AE}%
+\def\AA{\realbackslash AA}%
+\def\o{\realbackslash o}%
+\def\O{\realbackslash O}%
+\def\l{\realbackslash l}%
+\def\L{\realbackslash L}%
+\def\ss{\realbackslash ss}%
+% Take care of texinfo commands likely to appear in an index entry.
+\def\_{{\realbackslash _}}%
+\def\w{\realbackslash w }%
+\def\bf{\realbackslash bf }%
+\def\rm{\realbackslash rm }%
+\def\sl{\realbackslash sl }%
+\def\sf{\realbackslash sf}%
+\def\tt{\realbackslash tt}%
+\def\gtr{\realbackslash gtr}%
+\def\less{\realbackslash less}%
+\def\hat{\realbackslash hat}%
+\def\char{\realbackslash char}%
+\def\TeX{\realbackslash TeX}%
+\def\dots{\realbackslash dots }%
+\def\copyright{\realbackslash copyright }%
+\def\tclose##1{\realbackslash tclose {##1}}%
+\def\code##1{\realbackslash code {##1}}%
+\def\samp##1{\realbackslash samp {##1}}%
+\def\t##1{\realbackslash r {##1}}%
+\def\r##1{\realbackslash r {##1}}%
+\def\i##1{\realbackslash i {##1}}%
+\def\b##1{\realbackslash b {##1}}%
+\def\cite##1{\realbackslash cite {##1}}%
+\def\key##1{\realbackslash key {##1}}%
+\def\file##1{\realbackslash file {##1}}%
+\def\var##1{\realbackslash var {##1}}%
+\def\kbd##1{\realbackslash kbd {##1}}%
+\def\dfn##1{\realbackslash dfn {##1}}%
+\def\emph##1{\realbackslash emph {##1}}%
+}
+
+% \indexnofonts no-ops all font-change commands.
+% This is used when outputting the strings to sort the index by.
+\def\indexdummyfont#1{#1}
+\def\indexdummytex{TeX}
+\def\indexdummydots{...}
+
+\def\indexnofonts{%
+% Just ignore accents.
+\let\"=\indexdummyfont
+\let\`=\indexdummyfont
+\let\'=\indexdummyfont
+\let\^=\indexdummyfont
+\let\~=\indexdummyfont
+\let\==\indexdummyfont
+\let\b=\indexdummyfont
+\let\c=\indexdummyfont
+\let\d=\indexdummyfont
+\let\u=\indexdummyfont
+\let\v=\indexdummyfont
+\let\H=\indexdummyfont
+% Take care of the plain tex special European modified letters.
+\def\oe{oe}%
+\def\ae{ae}%
+\def\aa{aa}%
+\def\OE{OE}%
+\def\AE{AE}%
+\def\AA{AA}%
+\def\o{o}%
+\def\O{O}%
+\def\l{l}%
+\def\L{L}%
+\def\ss{ss}%
+\let\w=\indexdummyfont
+\let\t=\indexdummyfont
+\let\r=\indexdummyfont
+\let\i=\indexdummyfont
+\let\b=\indexdummyfont
+\let\emph=\indexdummyfont
+\let\strong=\indexdummyfont
+\let\cite=\indexdummyfont
+\let\sc=\indexdummyfont
+%Don't no-op \tt, since it isn't a user-level command
+% and is used in the definitions of the active chars like <, >, |...
+%\let\tt=\indexdummyfont
+\let\tclose=\indexdummyfont
+\let\code=\indexdummyfont
+\let\file=\indexdummyfont
+\let\samp=\indexdummyfont
+\let\kbd=\indexdummyfont
+\let\key=\indexdummyfont
+\let\var=\indexdummyfont
+\let\TeX=\indexdummytex
+\let\dots=\indexdummydots
+}
+
+% To define \realbackslash, we must make \ not be an escape.
+% We must first make another character (@) an escape
+% so we do not become unable to do a definition.
+
+{\catcode`\@=0 \catcode`\\=\other
+@gdef@realbackslash{\}}
+
+\let\indexbackslash=0 %overridden during \printindex.
+
+\def\doind #1#2{%
+{\count10=\lastpenalty %
+{\indexdummies % Must do this here, since \bf, etc expand at this stage
+\escapechar=`\\%
+{\let\folio=0% Expand all macros now EXCEPT \folio
+\def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
+% so it will be output as is; and it will print as backslash in the indx.
+%
+% Now process the index-string once, with all font commands turned off,
+% to get the string to sort the index by.
+{\indexnofonts
+\xdef\temp1{#2}%
+}%
+% Now produce the complete index entry. We process the index-string again,
+% this time with font commands expanded, to get what to print in the index.
+\edef\temp{%
+\write \csname#1indfile\endcsname{%
+\realbackslash entry {\temp1}{\folio}{#2}}}%
+\temp }%
+}\penalty\count10}}
+
+\def\dosubind #1#2#3{%
+{\count10=\lastpenalty %
+{\indexdummies % Must do this here, since \bf, etc expand at this stage
+\escapechar=`\\%
+{\let\folio=0%
+\def\rawbackslashxx{\indexbackslash}%
+%
+% Now process the index-string once, with all font commands turned off,
+% to get the string to sort the index by.
+{\indexnofonts
+\xdef\temp1{#2 #3}%
+}%
+% Now produce the complete index entry. We process the index-string again,
+% this time with font commands expanded, to get what to print in the index.
+\edef\temp{%
+\write \csname#1indfile\endcsname{%
+\realbackslash entry {\temp1}{\folio}{#2}{#3}}}%
+\temp }%
+}\penalty\count10}}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% This is what you call to cause a particular index to get printed.
+% Write
+% @unnumbered Function Index
+% @printindex fn
+
+\def\printindex{\parsearg\doprintindex}
+
+\def\doprintindex#1{%
+ \tex
+ \dobreak \chapheadingskip {10000}
+ \catcode`\%=\other\catcode`\&=\other\catcode`\#=\other
+ \catcode`\$=\other
+ \catcode`\~=\other
+ \indexbreaks
+ %
+ % The following don't help, since the chars were translated
+ % when the raw index was written, and their fonts were discarded
+ % due to \indexnofonts.
+ %\catcode`\"=\active
+ %\catcode`\^=\active
+ %\catcode`\_=\active
+ %\catcode`\|=\active
+ %\catcode`\<=\active
+ %\catcode`\>=\active
+ % %
+ \def\indexbackslash{\rawbackslashxx}
+ \indexfonts\rm \tolerance=9500 \advance\baselineskip -1pt
+ \begindoublecolumns
+ %
+ % See if the index file exists and is nonempty.
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ (Index is nonexistent)
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ (Index is empty)
+ \else
+ \input \jobname.#1s
+ \fi
+ \fi
+ \closein 1
+ \enddoublecolumns
+ \Etex
+}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+% Same as \bigskipamount except no shrink.
+% \balancecolumns gets confused if there is any shrink.
+\newskip\initialskipamount \initialskipamount 12pt plus4pt
+
+\def\initial #1{%
+{\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+\ifdim\lastskip<\initialskipamount
+\removelastskip \penalty-200 \vskip \initialskipamount\fi
+\line{\secbf#1\hfill}\kern 2pt\penalty10000}}
+
+% This typesets a paragraph consisting of #1, dot leaders, and then #2
+% flush to the right margin. It is used for index and table of contents
+% entries. The paragraph is indented by \leftskip.
+%
+\def\entry #1#2{\begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent=2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % Start a ``paragraph'' for the index entry so the line breaking
+ % parameters we've set above will have an effect.
+ \noindent
+ %
+ % Insert the text of the index entry. TeX will do line-breaking on it.
+ #1%
+ % The following is kluged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \def\tempa{{\rm }}%
+ \def\tempb{#2}%
+ \edef\tempc{\tempa}%
+ \edef\tempd{\tempb}%
+ \ifx\tempc\tempd\ \else%
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ #2% The page number ends the paragraph.
+ \fi%
+ \par
+\endgroup}
+
+% Like \dotfill except takes at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+
+\def\secondary #1#2{
+{\parfillskip=0in \parskip=0in
+\hangindent =1in \hangafter=1
+\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par
+}}
+
+%% Define two-column mode, which is used in indexes.
+%% Adapted from the TeXbook, page 416.
+\catcode `\@=11
+
+\newbox\partialpage
+
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup
+ % Grab any single-column material above us.
+ \output = {\global\setbox\partialpage
+ =\vbox{\unvbox255\kern -\topskip \kern \baselineskip}}%
+ \eject
+ %
+ % Now switch to the double-column output routine.
+ \output={\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it once.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +- <
+ % 1pt) as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+ \doublecolumnpagegoal
+}
+
+\def\enddoublecolumns{\eject \endgroup \pagegoal=\vsize \unvbox\partialpage}
+
+\def\doublecolumnsplit{\splittopskip=\topskip \splitmaxdepth=\maxdepth
+ \global\dimen@=\pageheight \global\advance\dimen@ by-\ht\partialpage
+ \global\setbox1=\vsplit255 to\dimen@ \global\setbox0=\vbox{\unvbox1}
+ \global\setbox3=\vsplit255 to\dimen@ \global\setbox2=\vbox{\unvbox3}
+ \ifdim\ht0>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi
+ \ifdim\ht2>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi
+}
+\def\doublecolumnpagegoal{%
+ \dimen@=\vsize \advance\dimen@ by-2\ht\partialpage \global\pagegoal=\dimen@
+}
+\def\pagesofar{\unvbox\partialpage %
+ \hsize=\doublecolumnhsize % have to restore this since output routine
+ \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}}
+\def\doublecolumnout{%
+ \setbox5=\copy255
+ {\vbadness=10000 \doublecolumnsplit}
+ \ifvbox255
+ \setbox0=\vtop to\dimen@{\unvbox0}
+ \setbox2=\vtop to\dimen@{\unvbox2}
+ \onepageout\pagesofar \unvbox255 \penalty\outputpenalty
+ \else
+ \setbox0=\vbox{\unvbox5}
+ \ifvbox0
+ \dimen@=\ht0 \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by2 \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ {\vbadness=10000
+ \loop \global\setbox5=\copy0
+ \setbox1=\vsplit5 to\dimen@
+ \setbox3=\vsplit5 to\dimen@
+ \ifvbox5 \global\advance\dimen@ by1pt \repeat
+ \setbox0=\vbox to\dimen@{\unvbox1}
+ \setbox2=\vbox to\dimen@{\unvbox3}
+ \global\setbox\partialpage=\vbox{\pagesofar}
+ \doublecolumnpagegoal
+ }
+ \fi
+ \fi
+}
+
+\catcode `\@=\other
+\message{sectioning,}
+% Define chapters, sections, etc.
+
+\newcount \chapno
+\newcount \secno \secno=0
+\newcount \subsecno \subsecno=0
+\newcount \subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount \appendixno \appendixno = `\@
+\def\appendixletter{\char\the\appendixno}
+
+\newwrite \contentsfile
+% This is called from \setfilename.
+\def\opencontents{\openout \contentsfile = \jobname.toc}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it. @section does likewise
+
+\def\thischapter{} \def\thissection{}
+\def\seccheck#1{\if \pageno<0 %
+\errmessage{@#1 not allowed after generating table of contents}\fi
+%
+}
+
+\def\chapternofonts{%
+\let\rawbackslash=\relax%
+\let\frenchspacing=\relax%
+\def\result{\realbackslash result}
+\def\equiv{\realbackslash equiv}
+\def\expansion{\realbackslash expansion}
+\def\print{\realbackslash print}
+\def\TeX{\realbackslash TeX}
+\def\dots{\realbackslash dots}
+\def\copyright{\realbackslash copyright}
+\def\tt{\realbackslash tt}
+\def\bf{\realbackslash bf }
+\def\w{\realbackslash w}
+\def\less{\realbackslash less}
+\def\gtr{\realbackslash gtr}
+\def\hat{\realbackslash hat}
+\def\char{\realbackslash char}
+\def\tclose##1{\realbackslash tclose {##1}}
+\def\code##1{\realbackslash code {##1}}
+\def\samp##1{\realbackslash samp {##1}}
+\def\r##1{\realbackslash r {##1}}
+\def\b##1{\realbackslash b {##1}}
+\def\key##1{\realbackslash key {##1}}
+\def\file##1{\realbackslash file {##1}}
+\def\kbd##1{\realbackslash kbd {##1}}
+% These are redefined because @smartitalic wouldn't work inside xdef.
+\def\i##1{\realbackslash i {##1}}
+\def\cite##1{\realbackslash cite {##1}}
+\def\var##1{\realbackslash var {##1}}
+\def\emph##1{\realbackslash emph {##1}}
+\def\dfn##1{\realbackslash dfn {##1}}
+}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raise/lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% Choose a numbered-heading macro
+% #1 is heading level if unmodified by @raisesections or @lowersections
+% #2 is text for heading
+\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \chapterzzz{#2}
+\or
+ \seczzz{#2}
+\or
+ \numberedsubseczzz{#2}
+\or
+ \numberedsubsubseczzz{#2}
+\else
+ \ifnum \absseclevel<0
+ \chapterzzz{#2}
+ \else
+ \numberedsubsubseczzz{#2}
+ \fi
+\fi
+}
+
+% like \numhead, but chooses appendix heading levels
+\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \appendixzzz{#2}
+\or
+ \appendixsectionzzz{#2}
+\or
+ \appendixsubseczzz{#2}
+\or
+ \appendixsubsubseczzz{#2}
+\else
+ \ifnum \absseclevel<0
+ \appendixzzz{#2}
+ \else
+ \appendixsubsubseczzz{#2}
+ \fi
+\fi
+}
+
+% like \numhead, but chooses numberless heading levels
+\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \unnumberedzzz{#2}
+\or
+ \unnumberedseczzz{#2}
+\or
+ \unnumberedsubseczzz{#2}
+\or
+ \unnumberedsubsubseczzz{#2}
+\else
+ \ifnum \absseclevel<0
+ \unnumberedzzz{#2}
+ \else
+ \unnumberedsubsubseczzz{#2}
+ \fi
+\fi
+}
+
+
+\def\thischaptername{No Chapter Title}
+\outer\def\chapter{\parsearg\chapteryyy}
+\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz #1{\seccheck{chapter}%
+\secno=0 \subsecno=0 \subsubsecno=0
+\global\advance \chapno by 1 \message{Chapter \the\chapno}%
+\chapmacro {#1}{\the\chapno}%
+\gdef\thissection{#1}%
+\gdef\thischaptername{#1}%
+% We don't substitute the actual chapter name into \thischapter
+% because we don't want its macros evaluated now.
+\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}%
+{\chapternofonts%
+\edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\global\let\section = \numberedsec
+\global\let\subsection = \numberedsubsec
+\global\let\subsubsection = \numberedsubsubsec
+}}
+
+\outer\def\appendix{\parsearg\appendixyyy}
+\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz #1{\seccheck{appendix}%
+\secno=0 \subsecno=0 \subsubsecno=0
+\global\advance \appendixno by 1 \message{Appendix \appendixletter}%
+\chapmacro {#1}{\putwordAppendix{} \appendixletter}%
+\gdef\thissection{#1}%
+\gdef\thischaptername{#1}%
+\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}%
+{\chapternofonts%
+\edef\temp{{\realbackslash chapentry
+ {#1}{\putwordAppendix{} \appendixletter}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\global\let\section = \appendixsec
+\global\let\subsection = \appendixsubsec
+\global\let\subsubsection = \appendixsubsubsec
+}}
+
+\outer\def\top{\parsearg\unnumberedyyy}
+\outer\def\unnumbered{\parsearg\unnumberedyyy}
+\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz #1{\seccheck{unnumbered}%
+\secno=0 \subsecno=0 \subsubsecno=0
+%
+% This used to be simply \message{#1}, but TeX fully expands the
+% argument to \message. Therefore, if #1 contained @-commands, TeX
+% expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+% expanded @cite (which turns out to cause errors because \cite is meant
+% to be executed, not expanded).
+%
+% Anyway, we don't want the fully-expanded definition of @cite to appear
+% as a result of the \message, we just want `@cite' itself. We use
+% \the<toks register> to achieve this: TeX expands \the<toks> only once,
+% simply yielding the contents of the <toks register>.
+\toks0 = {#1}\message{(\the\toks0)}%
+%
+\unnumbchapmacro {#1}%
+\gdef\thischapter{#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\global\let\section = \unnumberedsec
+\global\let\subsection = \unnumberedsubsec
+\global\let\subsubsection = \unnumberedsubsubsec
+}}
+
+\outer\def\numberedsec{\parsearg\secyyy}
+\def\secyyy #1{\numhead1{#1}} % normally calls seczzz
+\def\seczzz #1{\seccheck{section}%
+\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash secentry %
+{#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appenixsection{\parsearg\appendixsecyyy}
+\outer\def\appendixsec{\parsearg\appendixsecyyy}
+\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz #1{\seccheck{appendixsection}%
+\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash secentry %
+{#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy}
+\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz #1{\seccheck{unnumberedsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy}
+\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz #1{\seccheck{subsection}%
+\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsecentry %
+{#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy}
+\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz #1{\seccheck{appendixsubsec}%
+\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsecentry %
+{#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy}
+\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy}
+\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz #1{\seccheck{subsubsection}%
+\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+\subsubsecheading {#1}
+ {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsubsecentry %
+ {#1}
+ {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}
+ {\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy}
+\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}%
+\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+\subsubsecheading {#1}
+ {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsubsecentry{#1}%
+ {\appendixletter}
+ {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy}
+\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+% These are variants which are not "outer", so they can appear in @ifinfo.
+% Actually, they should now be obsolete; ordinary section commands should work.
+\def\infotop{\parsearg\unnumberedzzz}
+\def\infounnumbered{\parsearg\unnumberedzzz}
+\def\infounnumberedsec{\parsearg\unnumberedseczzz}
+\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz}
+\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz}
+
+\def\infoappendix{\parsearg\appendixzzz}
+\def\infoappendixsec{\parsearg\appendixseczzz}
+\def\infoappendixsubsec{\parsearg\appendixsubseczzz}
+\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz}
+
+\def\infochapter{\parsearg\chapterzzz}
+\def\infosection{\parsearg\sectionzzz}
+\def\infosubsection{\parsearg\subsectionzzz}
+\def\infosubsubsection{\parsearg\subsubsectionzzz}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\global\let\section = \numberedsec
+\global\let\subsection = \numberedsubsec
+\global\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and
+% such:
+% 1) We use \vbox rather than the earlier \line to permit
+% overlong headings to fold.
+% 2) \hyphenpenalty is set to 10000 because hyphenation in a
+% heading is obnoxious; this forbids it.
+% 3) Likewise, headings look best if no \parindent is used, and
+% if justification is not attempted. Hence \raggedright.
+
+
+\def\majorheading{\parsearg\majorheadingzzz}
+\def\majorheadingzzz #1{%
+{\advance\chapheadingskip by 10pt \chapbreak }%
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 200}
+
+\def\chapheading{\parsearg\chapheadingzzz}
+\def\chapheadingzzz #1{\chapbreak %
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 200}
+
+\def\heading{\parsearg\secheadingi}
+
+\def\subheading{\parsearg\subsecheadingi}
+
+\def\subsubheading{\parsearg\subsubsecheadingi}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip \chapheadingskip \chapheadingskip = 30pt plus 8pt minus 4pt
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+\def\CHAPFplain{
+\global\let\chapmacro=\chfplain
+\global\let\unnumbchapmacro=\unnchfplain}
+
+\def\chfplain #1#2{%
+ \pchapsepmacro
+ {%
+ \chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #2\enspace #1}%
+ }%
+ \bigskip
+ \penalty5000
+}
+
+\def\unnchfplain #1{%
+\pchapsepmacro %
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 10000 %
+}
+\CHAPFplain % The default
+
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 10000 %
+}
+
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+
+\def\CHAPFopen{
+\global\let\chapmacro=\chfopen
+\global\let\unnumbchapmacro=\unnchfopen}
+
+% Parameter controlling skip before section headings.
+
+\newskip \subsecheadingskip \subsecheadingskip = 17pt plus 8pt minus 4pt
+\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}}
+
+\newskip \secheadingskip \secheadingskip = 21pt plus 8pt minus 4pt
+\def\secheadingbreak{\dobreak \secheadingskip {-1000}}
+
+% @paragraphindent is defined for the Info formatting commands only.
+\let\paragraphindent=\comment
+
+% Section fonts are the base font at magstep2, which produces
+% a size a bit more than 14 points in the default situation.
+
+\def\secheading #1#2#3{\secheadingi {#2.#3\enspace #1}}
+\def\plainsecheading #1{\secheadingi {#1}}
+\def\secheadingi #1{{\advance \secheadingskip by \parskip %
+\secheadingbreak}%
+{\secfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 }
+
+
+% Subsection fonts are the base font at magstep1,
+% which produces a size of 12 points.
+
+\def\subsecheading #1#2#3#4{\subsecheadingi {#2.#3.#4\enspace #1}}
+\def\subsecheadingi #1{{\advance \subsecheadingskip by \parskip %
+\subsecheadingbreak}%
+{\subsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 }
+
+\def\subsubsecfonts{\subsecfonts} % Maybe this should change:
+ % Perhaps make sssec fonts scaled
+ % magstep half
+\def\subsubsecheading #1#2#3#4#5{\subsubsecheadingi {#2.#3.#4.#5\enspace #1}}
+\def\subsubsecheadingi #1{{\advance \subsecheadingskip by \parskip %
+\subsecheadingbreak}%
+{\subsubsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000}
+
+
+\message{toc printing,}
+
+% Finish up the main text and prepare to read what we've written
+% to \contentsfile.
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\def\startcontents#1{%
+ \pagealignmacro
+ \immediate\closeout \contentsfile
+ \ifnum \pageno>0
+ \pageno = -1 % Request roman numbered pages.
+ \fi
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \unnumbchapmacro{#1}\def\thischapter{}%
+ \begingroup % Set up to handle contents files properly.
+ \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
+ \catcode`\^=7 % to see ^^e4 as \"a etc. juha@piuha.ydi.vtt.fi
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+}
+
+
+% Normal (long) toc.
+\outer\def\contents{%
+ \startcontents{\putwordTableofContents}%
+ \input \jobname.toc
+ \endgroup
+ \vfill \eject
+}
+
+% And just the chapters.
+\outer\def\summarycontents{%
+ \startcontents{\putwordShortContents}%
+ %
+ \let\chapentry = \shortchapentry
+ \let\unnumbchapentry = \shortunnumberedentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl
+ \rm
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\secentry ##1##2##3##4{}
+ \def\unnumbsecentry ##1##2{}
+ \def\subsecentry ##1##2##3##4##5{}
+ \def\unnumbsubsecentry ##1##2{}
+ \def\subsubsecentry ##1##2##3##4##5##6{}
+ \def\unnumbsubsubsecentry ##1##2{}
+ \input \jobname.toc
+ \endgroup
+ \vfill \eject
+}
+\let\shortcontents = \summarycontents
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapter-level things, for both the long and short contents.
+\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}}
+
+% See comments in \dochapentry re vbox and related settings
+\def\shortchapentry#1#2#3{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}%
+}
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter.
+% We could simplify the code here by writing out an \appendixentry
+% command in the toc file for appendices, instead of using \chapentry
+% for both, but it doesn't seem worth it.
+\setbox0 = \hbox{\shortcontrm \putwordAppendix }
+\newdimen\shortappendixwidth \shortappendixwidth = \wd0
+
+\def\shortchaplabel#1{%
+ % We typeset #1 in a box of constant width, regardless of the text of
+ % #1, so the chapter titles will come out aligned.
+ \setbox0 = \hbox{#1}%
+ \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi
+ %
+ % This space should be plenty, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in in \shortchapentry above.)
+ \advance\dimen0 by 1.1em
+ \hbox to \dimen0{#1\hfil}%
+}
+
+\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}}
+\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}}
+
+% Sections.
+\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}}
+\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}}
+
+% Subsections.
+\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}}
+\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}}
+
+% And subsubsections.
+\def\subsubsecentry#1#2#3#4#5#6{%
+ \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}}
+\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}}
+
+
+% This parameter controls the indentation of the various levels.
+\newdimen\tocindent \tocindent = 3pc
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we would want to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno{#2}}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+% Final typesetting of a toc entry; we use the same \entry macro as for
+% the index entries, but we want to suppress hyphenation here. (We
+% can't do that in the \entry macro, since index entries might consist
+% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.)
+%
+\def\tocentry#1#2{\begingroup
+ \hyphenpenalty = 10000
+ \entry{#1}{#2}%
+\endgroup}
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\let\subsecentryfonts = \textfonts
+\let\subsubsecentryfonts = \textfonts
+
+
+\message{environments,}
+
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+% Furthermore, these definitions must come after we define our fonts.
+\newbox\dblarrowbox \newbox\longdblarrowbox
+\newbox\pushcharbox \newbox\bullbox
+\newbox\equivbox \newbox\errorbox
+
+\let\ptexequiv = \equiv
+
+%{\tentt
+%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil}
+%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil}
+%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil}
+%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil}
+% Adapted from the manmac format (p.420 of TeXbook)
+%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex
+% depth .1ex\hfil}
+%}
+
+\def\point{$\star$}
+
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% Adapted from the TeXbook's \boxit.
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+
+\global\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+
+% The @error{} command.
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\def\tex{\begingroup
+\catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+\catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+\catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie
+\catcode `\%=14
+\catcode 43=12
+\catcode`\"=12
+\catcode`\==12
+\catcode`\|=12
+\catcode`\<=12
+\catcode`\>=12
+\escapechar=`\\
+%
+\let\~=\ptextilde
+\let\{=\ptexlbrace
+\let\}=\ptexrbrace
+\let\.=\ptexdot
+\let\*=\ptexstar
+\let\dots=\ptexdots
+\def\@{@}%
+\let\bullet=\ptexbullet
+\let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext \let\l=\ptexl
+\let\L=\ptexL
+%
+\let\Etex=\endgroup}
+
+% Define @lisp ... @endlisp.
+% @lisp does a \begingroup so it can rebind things,
+% including the definition of @endlisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% Make each space character in the input produce a normal interword
+% space in the output. Don't allow a line break at this space, as this
+% is used only in environments like @example, where each line of input
+% should produce a line of output anyway.
+%
+{\obeyspaces %
+\gdef\sepspaces{\obeyspaces\let =\tie}}
+
+% Define \obeyedspace to be our active space, whatever it is. This is
+% for use in \parsearg.
+{\sepspaces%
+\global\let\obeyedspace= }
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip
+%
+\def\aboveenvbreak{{\advance\envskipamount by \parskip
+\endgraf \ifdim\lastskip<\envskipamount
+\removelastskip \penalty-50 \vskip\envskipamount \fi}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins.
+\let\nonarrowing=\relax
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \cartouche: draw rectangle w/rounded corners around argument
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\long\def\cartouche{%
+\begingroup
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt %we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18pt % allow for 3pt kerns on either
+% side, and for 6pt waste from
+% each corner char
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing=\comment
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \hsize=\cartinner
+ \kern3pt
+ \begingroup
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+\def\Ecartouche{%
+ \endgroup
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+\endgroup
+}}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+ \aboveenvbreak
+ \inENV % This group ends at the end of the body
+ \hfuzz = 12pt % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \singlespace
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ \parindent = 0pt
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ % @cartouche defines \nonarrowing to inhibit narrowing
+ % at next level down.
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \let\exdent=\nofillexdent
+ \let\nonarrowing=\relax
+ \fi
+}
+
+% To ending an @example-like environment, we first end the paragraph
+% (via \afterenvbreak's vertical glue), and then the group. That way we
+% keep the zero \parskip that the environments set -- \parskip glue
+% will be inserted at the beginning of the next paragraph in the
+% document, after the environment.
+%
+\def\nonfillfinish{\afterenvbreak\endgroup}%
+
+% This macro is
+\def\lisp{\begingroup
+ \nonfillstart
+ \let\Elisp = \nonfillfinish
+ \tt
+ \rawbackslash % have \ input char produce \ char from current font
+ \gobble
+}
+
+% Define the \E... control sequence only if we are inside the
+% environment, so the error checking in \end will work.
+%
+% We must call \lisp last in the definition, since it reads the
+% return following the @example (or whatever) command.
+%
+\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp}
+\def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp}
+\def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp}
+
+% @smallexample and @smalllisp. This is not used unless the @smallbook
+% command is given. Originally contributed by Pavel@xerox.
+%
+\def\smalllispx{\begingroup
+ \nonfillstart
+ \let\Esmalllisp = \nonfillfinish
+ \let\Esmallexample = \nonfillfinish
+ %
+ % Smaller interline space and fonts for small examples.
+ \setleading{10pt}%
+ \indexfonts \tt
+ \rawbackslash % make \ output the \ character from the current font (tt)
+ \gobble
+}
+
+% This is @display; same as @lisp except use roman font.
+%
+\def\display{\begingroup
+ \nonfillstart
+ \let\Edisplay = \nonfillfinish
+ \gobble
+}
+
+% This is @format; same as @display except don't narrow margins.
+%
+\def\format{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eformat = \nonfillfinish
+ \gobble
+}
+
+% @flushleft (same as @format) and @flushright.
+%
+\def\flushleft{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eflushleft = \nonfillfinish
+ \gobble
+}
+\def\flushright{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eflushright = \nonfillfinish
+ \advance\leftskip by 0pt plus 1fill
+ \gobble}
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.
+%
+\def\quotation{%
+ \begingroup\inENV %This group ends at the end of the @quotation body
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \singlespace
+ \parindent=0pt
+ % We have retained a nonzero parskip for the environment, since we're
+ % doing normal filling. So to avoid extra space below the environment...
+ \def\Equotation{\parskip = 0pt \nonfillfinish}%
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \advance\rightskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \let\nonarrowing = \relax
+ \fi
+}
+
+\message{defuns,}
+% Define formatter for defuns
+% First, allow user to change definition object font (\df) internally
+\def\setdeffont #1 {\csname DEF#1\endcsname}
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deftypemargin \deftypemargin=12pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+
+\newcount\parencount
+% define \functionparens, which makes ( and ) and & do special things.
+% \functionparens affects the group it is contained in.
+\def\activeparens{%
+\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active
+\catcode`\[=\active \catcode`\]=\active}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+{\activeparens % Now, smart parens don't turn on until &foo (see \amprm)
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+\global\let(=\lparen \global\let)=\rparen
+\global\let[=\lbrack \global\let]=\rbrack
+
+\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 }
+\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+
+% Definitions of (, ) and & used in args for functions.
+% This is the definition of ( outside of all parentheses.
+\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested %
+\global\advance\parencount by 1 }
+%
+% This is the definition of ( when already inside a level of parens.
+\gdef\opnested{\char`\(\global\advance\parencount by 1 }
+%
+\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0.
+% also in that case restore the outer-level definition of (.
+\ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi
+\global\advance \parencount by -1 }
+% If we encounter &foo, then turn on ()-hacking afterwards
+\gdef\amprm#1 {{\rm\&#1}\let(=\oprm \let)=\clrm\ }
+%
+\gdef\normalparens{\boldbrax\let&=\ampnr}
+} % End of definition inside \activeparens
+%% These parens (in \boldbrax) actually are a little bolder than the
+%% contained text. This is especially needed for [ and ]
+\def\opnr{{\sf\char`\(}} \def\clnr{{\sf\char`\)}} \def\ampnr{\&}
+\def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}}
+
+% First, defname, which formats the header line itself.
+% #1 should be the function name.
+% #2 should be the type of definition, such as "Function".
+
+\def\defname #1#2{%
+% Get the values of \leftskip and \rightskip as they were
+% outside the @def...
+\dimen2=\leftskip
+\advance\dimen2 by -\defbodyindent
+\dimen3=\rightskip
+\advance\dimen3 by -\defbodyindent
+\noindent %
+\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}%
+\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line
+\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations
+\parshape 2 0in \dimen0 \defargsindent \dimen1 %
+% Now output arg 2 ("Function" or some such)
+% ending at \deftypemargin from the right margin,
+% but stuck inside a box of width 0 so it does not interfere with linebreaking
+{% Adjust \hsize to exclude the ambient margins,
+% so that \rightline will obey them.
+\advance \hsize by -\dimen2 \advance \hsize by -\dimen3
+\rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}%
+% Make all lines underfull and no complaints:
+\tolerance=10000 \hbadness=10000
+\advance\leftskip by -\defbodyindent
+\exdentamount=\defbodyindent
+{\df #1}\enskip % Generate function name
+}
+
+% Actually process the body of a definition
+% #1 should be the terminating control sequence, such as \Edefun.
+% #2 should be the "another name" control sequence, such as \defunx.
+% #3 should be the control sequence that actually processes the header,
+% such as \defunheader.
+
+\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2{\begingroup\obeylines\activeparens\spacesplit#3}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup %
+\catcode 61=\active % 61 is `='
+\obeylines\activeparens\spacesplit#3}
+
+\def\defmethparsebody #1#2#3#4 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\activeparens\spacesplit{#3{#4}}}
+
+\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 ##2 {\def#4{##1}%
+\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\activeparens\spacesplit{#3{#5}}}
+
+% These parsing functions are similar to the preceding ones
+% except that they do not make parens into active characters.
+% These are used for "variables" since they have no arguments.
+
+\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2{\begingroup\obeylines\spacesplit#3}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup %
+\catcode 61=\active %
+\obeylines\spacesplit#3}
+
+% This is used for \def{tp,vr}parsebody. It could probably be used for
+% some of the others, too, with some judicious conditionals.
+%
+\def\parsebodycommon#1#2#3{%
+ \begingroup\inENV %
+ \medbreak %
+ % Define the end token that this defining construct specifies
+ % so that it will exit this group.
+ \def#1{\endgraf\endgroup\medbreak}%
+ \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}%
+ \parindent=0in
+ \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+ \exdentamount=\defbodyindent
+ \begingroup\obeylines
+}
+
+\def\defvrparsebody#1#2#3#4 {%
+ \parsebodycommon{#1}{#2}{#3}%
+ \spacesplit{#3{#4}}%
+}
+
+% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the
+% type is just `struct', because we lose the braces in `{struct
+% termios}' when \spacesplit reads its undelimited argument. Sigh.
+% \let\deftpparsebody=\defvrparsebody
+%
+% So, to get around this, we put \empty in with the type name. That
+% way, TeX won't find exactly `{...}' as an undelimited argument, and
+% won't strip off the braces.
+%
+\def\deftpparsebody #1#2#3#4 {%
+ \parsebodycommon{#1}{#2}{#3}%
+ \spacesplit{\parsetpheaderline{#3{#4}}}\empty
+}
+
+% Fine, but then we have to eventually remove the \empty *and* the
+% braces (if any). That's what this does, putting the result in \tptemp.
+%
+\def\removeemptybraces\empty#1\relax{\def\tptemp{#1}}%
+
+% After \spacesplit has done its work, this is called -- #1 is the final
+% thing to call, #2 the type name (which starts with \empty), and #3
+% (which might be empty) the arguments.
+%
+\def\parsetpheaderline#1#2#3{%
+ \removeemptybraces#2\relax
+ #1{\tptemp}{#3}%
+}%
+
+\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 ##2 {\def#4{##1}%
+\begingroup\obeylines\spacesplit{#3{##2}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\spacesplit{#3{#5}}}
+
+% Split up #2 at the first space token.
+% call #1 with two arguments:
+% the first is all of #2 before the space token,
+% the second is all of #2 after that space token.
+% If #2 contains no space token, all of it is passed as the first arg
+% and the second is passed as empty.
+
+{\obeylines
+\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}%
+\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{%
+\ifx\relax #3%
+#1{#2}{}\else #1{#2}{#3#4}\fi}}
+
+% So much for the things common to all kinds of definitions.
+
+% Define @defun.
+
+% First, define the processing that is wanted for arguments of \defun
+% Use this to expand the args and terminate the paragraph they make up
+
+\def\defunargs #1{\functionparens \sl
+% Expand, preventing hyphenation at `-' chars.
+% Note that groups don't affect changes in \hyphenchar.
+\hyphenchar\tensl=0
+#1%
+\hyphenchar\tensl=45
+\ifnum\parencount=0 \else \errmessage{unbalanced parens in @def arguments}\fi%
+\interlinepenalty=10000
+\advance\rightskip by 0pt plus 1fil
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
+}
+
+\def\deftypefunargs #1{%
+% Expand, preventing hyphenation at `-' chars.
+% Note that groups don't affect changes in \hyphenchar.
+\functionparens
+\tclose{#1}% avoid \code because of side effects on active chars
+\interlinepenalty=10000
+\advance\rightskip by 0pt plus 1fil
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
+}
+
+% Do complete processing of one @defun or @defunx line already parsed.
+
+% @deffn Command forward-char nchars
+
+\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader}
+
+\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}%
+\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defun == @deffn Function
+
+\def\defun{\defparsebody\Edefun\defunx\defunheader}
+
+\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Function}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @deftypefun int foobar (int @var{foo}, float @var{bar})
+
+\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader}
+
+% #1 is the data type. #2 is the name and args.
+\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax}
+% #1 is the data type, #2 the name, #3 the args.
+\def\deftypefunheaderx #1#2 #3\relax{%
+\doind {fn}{\code{#2}}% Make entry in function index
+\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}%
+\deftypefunargs {#3}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar})
+
+\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader}
+
+% \defheaderxcond#1\relax$$$
+% puts #1 in @code, followed by a space, but does nothing if #1 is null.
+\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi}
+
+% #1 is the classification. #2 is the data type. #3 is the name and args.
+\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax}
+% #1 is the classification, #2 the data type, #3 the name, #4 the args.
+\def\deftypefnheaderx #1#2#3 #4\relax{%
+\doind {fn}{\code{#3}}% Make entry in function index
+\begingroup
+\normalparens % notably, turn off `&' magic, which prevents
+% at least some C++ text from working
+\defname {\defheaderxcond#2\relax$$$#3}{#1}%
+\deftypefunargs {#4}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defmac == @deffn Macro
+
+\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader}
+
+\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Macro}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defspec == @deffn Special Form
+
+\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader}
+
+\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Special Form}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% This definition is run if you use @defunx
+% anywhere other than immediately after a @defun or @defunx.
+
+\def\deffnx #1 {\errmessage{@deffnx in invalid context}}
+\def\defunx #1 {\errmessage{@defunx in invalid context}}
+\def\defmacx #1 {\errmessage{@defmacx in invalid context}}
+\def\defspecx #1 {\errmessage{@defspecx in invalid context}}
+\def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}}
+\def\deftypeunx #1 {\errmessage{@deftypeunx in invalid context}}
+
+% @defmethod, and so on
+
+% @defop {Funny Method} foo-class frobnicate argument
+
+\def\defop #1 {\def\defoptype{#1}%
+\defopparsebody\Edefop\defopx\defopheader\defoptype}
+
+\def\defopheader #1#2#3{%
+\dosubind {fn}{\code{#2}}{on #1}% Make entry in function index
+\begingroup\defname {#2}{\defoptype{} on #1}%
+\defunargs {#3}\endgroup %
+}
+
+% @defmethod == @defop Method
+
+\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader}
+
+\def\defmethodheader #1#2#3{%
+\dosubind {fn}{\code{#2}}{on #1}% entry in function index
+\begingroup\defname {#2}{Method on #1}%
+\defunargs {#3}\endgroup %
+}
+
+% @defcv {Class Option} foo-class foo-flag
+
+\def\defcv #1 {\def\defcvtype{#1}%
+\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype}
+
+\def\defcvarheader #1#2#3{%
+\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
+\begingroup\defname {#2}{\defcvtype{} of #1}%
+\defvarargs {#3}\endgroup %
+}
+
+% @defivar == @defcv {Instance Variable}
+
+\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader}
+
+\def\defivarheader #1#2#3{%
+\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
+\begingroup\defname {#2}{Instance Variable of #1}%
+\defvarargs {#3}\endgroup %
+}
+
+% These definitions are run if you use @defmethodx, etc.,
+% anywhere other than immediately after a @defmethod, etc.
+
+\def\defopx #1 {\errmessage{@defopx in invalid context}}
+\def\defmethodx #1 {\errmessage{@defmethodx in invalid context}}
+\def\defcvx #1 {\errmessage{@defcvx in invalid context}}
+\def\defivarx #1 {\errmessage{@defivarx in invalid context}}
+
+% Now @defvar
+
+% First, define the processing that is wanted for arguments of @defvar.
+% This is actually simple: just print them in roman.
+% This must expand the args and terminate the paragraph they make up
+\def\defvarargs #1{\normalparens #1%
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000}
+
+% @defvr Counter foo-count
+
+\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader}
+
+\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}%
+\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup}
+
+% @defvar == @defvr Variable
+
+\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader}
+
+\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
+\begingroup\defname {#1}{Variable}%
+\defvarargs {#2}\endgroup %
+}
+
+% @defopt == @defvr {User Option}
+
+\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader}
+
+\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
+\begingroup\defname {#1}{User Option}%
+\defvarargs {#2}\endgroup %
+}
+
+% @deftypevar int foobar
+
+\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader}
+
+% #1 is the data type. #2 is the name.
+\def\deftypevarheader #1#2{%
+\doind {vr}{\code{#2}}% Make entry in variables index
+\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}%
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000
+\endgroup}
+
+% @deftypevr {Global Flag} int enable
+
+\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader}
+
+\def\deftypevrheader #1#2#3{\doind {vr}{\code{#3}}%
+\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1}
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000
+\endgroup}
+
+% This definition is run if you use @defvarx
+% anywhere other than immediately after a @defvar or @defvarx.
+
+\def\defvrx #1 {\errmessage{@defvrx in invalid context}}
+\def\defvarx #1 {\errmessage{@defvarx in invalid context}}
+\def\defoptx #1 {\errmessage{@defoptx in invalid context}}
+\def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}}
+\def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}}
+
+% Now define @deftp
+% Args are printed in bold, a slight difference from @defvar.
+
+\def\deftpargs #1{\bf \defvarargs{#1}}
+
+% @deftp Class window height width ...
+
+\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader}
+
+\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}%
+\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup}
+
+% This definition is run if you use @deftpx, etc
+% anywhere other than immediately after a @deftp, etc.
+
+\def\deftpx #1 {\errmessage{@deftpx in invalid context}}
+
+\message{cross reference,}
+% Define cross-reference macros
+\newwrite \auxfile
+
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% \setref{foo} defines a cross-reference point named foo.
+
+\def\setref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Ysectionnumberandtype}}
+
+\def\unnumbsetref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Ynothing}}
+
+\def\appendixsetref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Yappendixletterandtype}}
+
+% \xref, \pxref, and \ref generate cross-references to specified points.
+% For \xrefX, #1 is the node name, #2 the name of the Info
+% cross-reference, #3 the printed node name, #4 the name of the Info
+% file, #5 the name of the printed manual. All but the node name can be
+% omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \def\printedmanual{\ignorespaces #5}%
+ \def\printednodename{\ignorespaces #3}%
+ \setbox1=\hbox{\printedmanual}%
+ \setbox0=\hbox{\printednodename}%
+ \ifdim \wd0 = 0pt
+ % No printed node name was explicitly given.
+ \ifx\SETxref-automatic-section-title\relax %
+ % Use the actual chapter/section title appear inside
+ % the square brackets. Use the real section title if we have it.
+ \ifdim \wd1>0pt%
+ % It is in another manual, so we don't have it.
+ \def\printednodename{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We know the real title if we have the xref values.
+ \def\printednodename{\refx{#1-title}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printednodename{\ignorespaces #1}%
+ \fi%
+ \fi
+ \def\printednodename{#1-title}%
+ \else
+ % Use the node name inside the square brackets.
+ \def\printednodename{\ignorespaces #1}%
+ \fi
+ \fi
+ %
+ % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+ % insert empty discretionaries after hyphens, which means that it will
+ % not find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens, this
+ % is a loss. Therefore, we give the text of the node name again, so it
+ % is as if TeX is seeing it for the first time.
+ \ifdim \wd1 > 0pt
+ \putwordsection{} ``\printednodename'' in \cite{\printedmanual}%
+ \else
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive \refx{#1-snt}{}}%
+ \space [\printednodename],\space
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi
+\endgroup}
+
+% \dosetq is the interface for calls from other macros
+
+% Use \turnoffactive so that punctuation chars such as underscore
+% work in node names.
+\def\dosetq #1#2{{\let\folio=0 \turnoffactive%
+\edef\next{\write\auxfile{\internalsetq {#1}{#2}}}%
+\next}}
+
+% \internalsetq {foo}{page} expands into
+% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...}
+% When the aux file is read, ' is the escape character
+
+\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}}
+
+% Things to be expanded by \internalsetq
+
+\def\Ypagenumber{\folio}
+
+\def\Ytitle{\thissection}
+
+\def\Ynothing{}
+
+\def\Ysectionnumberandtype{%
+\ifnum\secno=0 \putwordChapter\xreftie\the\chapno %
+\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno %
+\else \ifnum \subsubsecno=0 %
+\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno %
+\else %
+\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno %
+\fi \fi \fi }
+
+\def\Yappendixletterandtype{%
+\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}%
+\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno %
+\else \ifnum \subsubsecno=0 %
+\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno %
+\else %
+\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
+\fi \fi \fi }
+
+\gdef\xreftie{'tie}
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Non-3.0.
+\else
+ \def\linenumber{\the\inputlineno:\space}
+\fi
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+
+\def\refx#1#2{%
+ \expandafter\ifx\csname X#1\endcsname\relax
+ % If not defined, say something at least.
+ $\langle$un\-de\-fined$\rangle$%
+ \ifhavexrefs
+ \message{\linenumber Undefined cross reference `#1'.}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \csname X#1\endcsname
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+
+% This is the macro invoked by entries in the aux file.
+\def\xrdef #1#2{
+{\catcode`\'=\other\expandafter \gdef \csname X#1\endcsname {#2}}}
+
+\def\readauxfile{%
+\begingroup
+\catcode `\^^@=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\^^C=\other
+\catcode `\^^D=\other
+\catcode `\^^E=\other
+\catcode `\^^F=\other
+\catcode `\^^G=\other
+\catcode `\^^H=\other
+\catcode `\ =\other
+\catcode `\^^L=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode 26=\other
+\catcode `\^^[=\other
+\catcode `\^^\=\other
+\catcode `\^^]=\other
+\catcode `\^^^=\other
+\catcode `\^^_=\other
+\catcode `\@=\other
+\catcode `\^=\other
+\catcode `\~=\other
+\catcode `\[=\other
+\catcode `\]=\other
+\catcode`\"=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode `\$=\other
+\catcode `\#=\other
+\catcode `\&=\other
+% `\+ does not work, so use 43.
+\catcode 43=\other
+% Make the characters 128-255 be printing characters
+{%
+ \count 1=128
+ \def\loop{%
+ \catcode\count 1=\other
+ \advance\count 1 by 1
+ \ifnum \count 1<256 \loop \fi
+ }%
+}%
+% the aux file uses ' as the escape.
+% Turn off \ as an escape so we do not lose on
+% entries which were dumped with control sequences in their names.
+% For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^
+% Reference to such entries still does not work the way one would wish,
+% but at least they do not bomb out when the aux file is read in.
+\catcode `\{=1 \catcode `\}=2
+\catcode `\%=\other
+\catcode `\'=0
+\catcode `\\=\other
+\openin 1 \jobname.aux
+\ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue
+\global\warnedobstrue
+\fi
+% Open the new aux file. Tex will close it automatically at exit.
+\openout \auxfile=\jobname.aux
+\endgroup}
+
+
+% Footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed.
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only..
+\let\footnotestyle=\comment
+
+\let\ptexfootnote=\footnote
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \footnotezzz
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+\long\gdef\footnotezzz#1{\insert\footins{%
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ % Hang the footnote text off the number.
+ \hang
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ #1\strut}%
+}
+
+}%end \catcode `\@=11
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+ \normalbaselineskip = #1\relax
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+
+% End of control word definitions.
+
+\message{and turning on texinfo input format.}
+
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% Set some numeric style parameters, for 8.5 x 11 format.
+
+%\hsize = 6.5in
+\newdimen\defaultparindent \defaultparindent = 15pt
+\parindent = \defaultparindent
+\parskip 18pt plus 1pt
+\setleading{15pt}
+\advance\topskip by 1.2cm
+
+% Prevent underfull vbox error messages.
+\vbadness=10000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. This makes it come to about 9pt for the 8.5x11 format.
+%
+\ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+\else
+ \emergencystretch = \hsize
+ \divide\emergencystretch by 45
+\fi
+
+% Use @smallbook to reset parameters for 7x9.5 format (or else 7x9.25)
+\def\smallbook{
+
+% These values for secheadingskip and subsecheadingskip are
+% experiments. RJC 7 Aug 1992
+\global\secheadingskip = 17pt plus 6pt minus 3pt
+\global\subsecheadingskip = 14pt plus 6pt minus 3pt
+
+\global\lispnarrowing = 0.3in
+\setleading{12pt}
+\advance\topskip by -1cm
+\global\parskip 3pt plus 1pt
+\global\hsize = 5in
+\global\vsize=7.5in
+\global\tolerance=700
+\global\hfuzz=1pt
+\global\contentsrightmargin=0pt
+\global\deftypemargin=0pt
+\global\defbodyindent=.5cm
+
+\global\pagewidth=\hsize
+\global\pageheight=\vsize
+
+\global\let\smalllisp=\smalllispx
+\global\let\smallexample=\smalllispx
+\global\def\Esmallexample{\Esmalllisp}
+}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{
+\global\tolerance=700
+\global\hfuzz=1pt
+\setleading{12pt}
+\global\parskip 15pt plus 1pt
+
+\global\vsize= 53\baselineskip
+\advance\vsize by \topskip
+%\global\hsize= 5.85in % A4 wide 10pt
+\global\hsize= 6.5in
+\global\outerhsize=\hsize
+\global\advance\outerhsize by 0.5in
+\global\outervsize=\vsize
+\global\advance\outervsize by 0.6in
+
+\global\pagewidth=\hsize
+\global\pageheight=\vsize
+}
+
+% Allow control of the text dimensions. Parameters in order: textheight;
+% textwidth; \voffset; \hoffset (!); binding offset. All require a dimension;
+% header is additional; added length extends the bottom of the page.
+
+\def\changepagesizes#1#2#3#4#5
+{\global\vsize= #1
+ \advance\vsize by \topskip
+ \global\voffset= #3
+ \global\hsize= #2
+ \global\outerhsize=\hsize
+ \global\advance\outerhsize by 0.5in
+ \global\outervsize=\vsize
+ \global\advance\outervsize by 0.6in
+ \global\pagewidth=\hsize
+ \global\pageheight=\vsize
+ \global\normaloffset= #4
+ \global\bindingoffset= #5}
+
+% This layout is compatible with Latex on A4 paper.
+
+\def\afourlatex{\changepagesizes{22cm}{15cm}{7mm}{4.6mm}{5mm}}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+
+% This macro is used to make a character print one way in ttfont
+% where it can probably just be output, and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt \char '042}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt \char '176}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+% Subroutine for the previous macro.
+\def\_{\lvvmode \kern.06em \vbox{\hrule width.3em height.1ex}}
+
+% \lvvmode is equivalent in function to \leavevmode.
+% Using \leavevmode runs into trouble when written out to
+% an index file due to the expansion of \leavevmode into ``\unhbox
+% \voidb@x'' ---which looks to TeX like ``\unhbox \voidb\x'' due to our
+% magic tricks with @.
+\def\lvvmode{\vbox to 0pt{}}
+
+\catcode`\|=\active
+\def|{{\tt \char '174}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+%\catcode 27=\active
+%\def^^[{$\diamondsuit$}
+
+% Set up an active definition for =, but don't enable it most of the time.
+{\catcode`\==\active
+\global\def={{\tt \char 61}}}
+
+\catcode`\@=0
+
+% \rawbackslashxx output one backslash character in current font
+\global\chardef\rawbackslashxx=`\\
+%{\catcode`\\=\other
+%@gdef@rawbackslashxx{\}}
+
+% \rawbackslash redefines \ as input to do \rawbackslashxx.
+{\catcode`\\=\active
+@gdef@rawbackslash{@let\=@rawbackslashxx }}
+
+% \normalbackslash outputs one backslash in fixed width font.
+\def\normalbackslash{{\tt\rawbackslashxx}}
+
+% Say @foo, not \foo, in error messages.
+\escapechar=`\@
+
+% \catcode 17=0 % Define control-q
+\catcode`\\=\active
+
+% Used sometimes to turn off (effectively) the active characters
+% even after parsing them.
+@def@turnoffactive{@let"=@normaldoublequote
+@let\=@realbackslash
+@let~=@normaltilde
+@let^=@normalcaret
+@let_=@normalunderscore
+@let|=@normalverticalbar
+@let<=@normalless
+@let>=@normalgreater
+@let+=@normalplus}
+
+@def@normalturnoffactive{@let"=@normaldoublequote
+@let\=@normalbackslash
+@let~=@normaltilde
+@let^=@normalcaret
+@let_=@normalunderscore
+@let|=@normalverticalbar
+@let<=@normalless
+@let>=@normalgreater
+@let+=@normalplus}
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\{ in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+%
+@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi}
+
+%% These look ok in all fonts, so just make them not special. The @rm below
+%% makes sure that the current font starts out as the newly loaded cmr10
+@catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other
+
+@textfonts
+@rm
+
+@c Local variables:
+@c page-delimiter: "^\\\\message"
+@c End:
diff --git a/doc/version.texi b/doc/version.texi
new file mode 100644
index 00000000..b55168ee
--- /dev/null
+++ b/doc/version.texi
@@ -0,0 +1,3 @@
+@set EDITION 1.4
+@set UPDATED November 1994
+@set VERSION 1.4
diff --git a/examples/Makefile.am b/examples/Makefile.am
new file mode 100644
index 00000000..8b96545b
--- /dev/null
+++ b/examples/Makefile.am
@@ -0,0 +1,5 @@
+EXTRA_DIST = capitalize.m4 comments.m4 ddivert.m4 \
+debug.m4 esyscmd.m4 exp.m4 file.m4 foreach.m4 forloop.m4 fstab.m4 \
+hanoi.m4 incl-test.m4 include.m4 indir.m4 misc.m4 multiquotes.m4 \
+patsubst.m4 pushpop.m4 regexp.m4 reverse.m4 stackovf.sh sync-lines.m4 \
+sysv-args.m4 trace.m4 translit.m4 undivert.incl undivert.m4 wrap.m4
diff --git a/examples/Makefile.in b/examples/Makefile.in
new file mode 100644
index 00000000..47e6fe16
--- /dev/null
+++ b/examples/Makefile.in
@@ -0,0 +1,60 @@
+# Makefile for GNU m4 examples.
+# Copyright (C) 1994 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 2, 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, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+PRODUCT = @PRODUCT@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+.SUFFIXES:
+
+DISTFILES = Makefile.in capitalize.m4 comments.m4 ddivert.m4 \
+debug.m4 esyscmd.m4 exp.m4 file.m4 foreach.m4 forloop.m4 fstab.m4 \
+hanoi.m4 incl-test.m4 include.m4 indir.m4 misc.m4 multiquotes.m4 \
+patsubst.m4 pushpop.m4 regexp.m4 reverse.m4 stackovf.sh sync-lines.m4 \
+sysv-args.m4 trace.m4 translit.m4 undivert.incl undivert.m4 wrap.m4
+
+all:
+
+install:
+
+uninstall:
+
+mostlyclean:
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile
+
+realclean: distclean
+
+dist: $(DISTFILES)
+ @echo "Copying distribution files"
+ @for file in $(DISTFILES); do \
+ ln $(srcdir)/$$file ../$(PRODUCT)-$(VERSION)/examples 2> /dev/null \
+ || cp -p $(srcdir)/$$file ../$(PRODUCT)-$(VERSION)/examples; \
+ done
+
+Makefile: Makefile.in ../config.status
+ cd .. && CONFIG_FILES=examples/$@ CONFIG_HEADERS= ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/examples/WWW/Makefile b/examples/WWW/Makefile
new file mode 100644
index 00000000..f143493e
--- /dev/null
+++ b/examples/WWW/Makefile
@@ -0,0 +1,18 @@
+M4 = m4
+M4OPTS = -Im4lib
+
+VPATH = .:m4lib
+
+all: *.htm
+
+%.htm: %.m4
+ @$(M4) $(M4OPTS) $< >new.htm && \
+ if cmp -s new.htm $@; then \
+ rm new.htm; \
+ echo "$@ has not changed"; \
+ else \
+ echo "$@ updated"; \
+ mv new.htm $@; \
+ fi
+
+*.htm: m4lib/*.m4
diff --git a/examples/WWW/_footer.htm b/examples/WWW/_footer.htm
new file mode 100644
index 00000000..8fbbce61
--- /dev/null
+++ b/examples/WWW/_footer.htm
@@ -0,0 +1,15 @@
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/_header.htm b/examples/WWW/_header.htm
new file mode 100644
index 00000000..643223d6
--- /dev/null
+++ b/examples/WWW/_header.htm
@@ -0,0 +1,234 @@
+<!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 1.4o">
+</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/examples/WWW/bugs.htm b/examples/WWW/bugs.htm
new file mode 100644
index 00000000..207fcc31
--- /dev/null
+++ b/examples/WWW/bugs.htm
@@ -0,0 +1,284 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - Known bugs in GNU m4 \__m4_version__</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4n">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>Known bugs in GNU m4 1.4n</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+
+
+
+
+
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A><BR>
+<A HREF="features.htm">Features</A><BR>
+<A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD height=5>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD height=5>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A><BR>
+<A HREF="todo.htm">TODO</A><BR>
+<A HREF="news.htm">NEWS</A><BR>
+<A HREF="changelog.htm">ChangeLog</A><BR>
+<A HREF="thanks.htm">Contributors</A><BR>
+<A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD height=5>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A><BR>
+<A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD height=5>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A><BR>
+<A HREF="feedback.htm">Feedback</A><BR>
+<A HREF="download.htm">Download</A><BR>
+<A HREF="bugs.htm">Known bugs</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD height=5>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<H2>Known bugs in GNU m4</H2>
+
+
+
+
+
+
+<UL>
+
+
+<LI> <A HREF="#undivert">undivert(0) might read from standard output.</A>
+
+
+
+
+<LI> <A HREF="#sigaltstack">failure if sigaltstack or sigstack returns ENOSYS.</A>
+
+
+
+
+
+</UL>
+
+
+<P>
+See also the <A HREF="todo.htm">TODO</A> file.
+</P>
+
+
+
+<HR align=center width=50%><A NAME="undivert">
+<H2>undivert(0) might read from standard output</H2>
+</A><P>
+If calling <TT>undivert(0)</TT> 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.
+</P>
+
+
+<P>
+Fixed in version 1.4n
+</P>
+
+
+
+<HR align=center width=50%><A NAME="sigaltstack">
+<H2>failure if sigaltstack or sigstack returns ENOSYS</H2>
+</A><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.
+</P>
+
+
+<P>
+A <A
+HREF="mailto:m4-feedback@seindal.dk?subject=GNU m4: failure if sigaltstack or sigstack returns ENOSYS"
+>volunteer</A> is badly needed for this, as I have no way of testing
+this myself.
+</P>
+
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/changelog.htm b/examples/WWW/changelog.htm
new file mode 100644
index 00000000..56713edc
--- /dev/null
+++ b/examples/WWW/changelog.htm
@@ -0,0 +1,2248 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - ChangeLog</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>ChangeLog</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<PRE>1998-11-18 Rene' Seindal &lt;rene@seindal.dk&gt;
+
+ * 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 Rene' Seindal &lt;rene@seindal.dk&gt;
+
+ * 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 &lt;bfox@datawave.net&gt;. 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 Rene' Seindal &lt;rene@seindal.dk&gt;
+
+ * 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 &lt;rene@seindal.dk&gt;
+
+ * 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 &lt;rene@seindal.dk&gt;
+
+ * 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 &lt;rene@seindal.dk&gt;
+
+ * 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 &lt;rene@seindal.dk&gt;
+
+ * Prerelease 1.4i.
+
+ * configure.in (ALL_LINGUAS): Added Polish pl.po
+
+1998-10-03 René Seindal &lt;rene@seindal.dk&gt;
+
+ * 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
+ &lt;dlfcn.h&gt; and -ldl.
+
+ * acconfig.h: Added WITH_MODULES
+
+1998-10-02 René Seindal &lt;rene@seindal.dk&gt;
+
+ * 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 &lt;Erick.Branderhorst@asml.nl&gt;
+
+ * examples/{comments,ddivert,debug,iso8859,reverse,sysv-args,\
+ wrap}.test: Added a few testcases.
+
+1998-08-21 Erick Branderhorst &lt;Erick.Branderhorst@asml.nl&gt;
+
+ * 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 &lt;Erick.Branderhorst@asml.nl&gt;
+
+ * 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 &lt;Erick.Branderhorst@asml.nl&gt;
+
+ * 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 &lt;rene@seindal.dk&gt;
+
+ * 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 &lt;rene@seindal.dk&gt;
+
+ * 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 &lt;rene@seindal.dk&gt;
+
+ * 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 &lt;mike@clove.com&gt;
+
+1998-08-06 René Seindal &lt;rene@seindal.dk&gt;
+
+ * gettext.m4: corrected AM_WITH_NLS to handle use of installed
+ -lintl.
+
+1998-08-03 René Seindal &lt;rene@seindal.dk&gt;
+
+ * Prerelease 1.4e
+
+ * src/m4.h: Added ifdef ENABLE_NLS around include of &lt;libintl.h&gt;
+ 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-22 Erick Branderhorst &lt;Erick.Branderhorst@asml.nl&gt;
+
+ * Prerelease 1.4d.
+
+ * src/m4.c: #include &lt;signal.h&gt; not &lt;sys/signal.h&gt;.
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * configure.in: Check for &lt;libintl.h&gt; and &lt;locale.h&gt;.
+ * 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 &lt;libintl.h&gt; and declare _ as gettext.
+ * src/m4.c: Possibly include &lt;locale.h&gt; 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * Release 1.4.
+
+ * doc/Makefile.in (realclean): Also remove stamp-vti.
+ Reported by Eric Backus.
+
+1994-11-02 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * src/m4.h: Get rid of CONFIG_BROKETS.
+
+1994-10-02 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * src/Makefile.in (TAGS): Include a ../lib/TAGS reference.
+ Reported by Karl Berry.
+
+1994-09-14 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * configure.in: Use fp_ to match aclocal.m4. Revert _OS_ macros
+ to old names, for following Autoconf.
+
+1994-09-08 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * lib/Makefile.in (install): Depend on all.
+
+1994-08-31 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * m4.h: Include &lt;unistd.h&gt; 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * Makefile.in, lib/Makefile.in, checks/Makefile.in: Arrange so
+ dist works from another build directory.
+
+1994-08-27 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * m4.c (long_options): Use "error-output", the dash was missing.
+ Reported by Akiko Matsushita.
+
+1994-08-12 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * m4.h: Include &lt;sys/types.h&gt;.
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * m4.c (usage): Replace printf par fputs.
+
+1994-07-18 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * Release 1.2
+
+1994-07-17 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * ansi2knr.c: New version sent by its author, Peter Deutsch.
+
+1994-07-15 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;jima@netcom.com&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * configure.in: Avoid USE_STACKOVF if &lt;siginfo.h&gt; 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * m4.h (_): Change argument from `x' to `Args'.
+
+1994-04-22 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * m4.h: Rename Args() to _().
+ * m4.h: Remove extern specifier from all function declarations.
+
+1994-04-22 Jim Avera &lt;jima@netcom.com&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * checks/Makefile.in: Rename .all-stamp to stamp-checks.
+
+ * Makefile.in (Makefile, etc.): Adapt for Autoconf 1.8.
+
+1994-01-30 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;memory.h&gt; together with &lt;string.h&gt;.
+ Reported by Jim Meyering.
+
+1994-01-25 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * Makefile.in: Do not define LDFLAGS, use CFLAGS on link calls.
+ Reported by Richard Stallman.
+
+1993-12-25 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * m4.c: Include &lt;getopt.h&gt; 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 &lt;config.h&gt; 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;varargs.h&gt;.
+ * debug.c: Include &lt;stdarg.h&gt; or &lt;varargs.h&gt;.
+ (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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * lib/Makefile.in (dist): Correct permissions on files.
+
+ * output.c: Declare tmpfile, some systems don't.
+
+1993-11-03 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;string.h&gt; 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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: ~, ^, &lt;&lt;, &gt;&gt;.
+ 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * Makefile.in (m4.info): Use -I$(srcdir) on $(MAKEINFO).
+ Reported by Noah Friedman.
+
+1993-10-25 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * Makefile.in: Remove MDEFINES and cleanup.
+
+1993-06-09 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * Makefile.in (dist): Replace "echo `pwd`" by a mere "pwd".
+ Create a gzip file.
+
+1993-02-06 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * Makefile.in, lib/Makefile.in: Reinstate $(CPPFLAGS), use it.
+ Richard wants it there.
+
+1992-12-27 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;meyering@idefix&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * *.[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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;meyering@idefix&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * *.[ch]: Rename nil to NULL, using the declaration from &lt;stdio.h&gt;,
+ 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * m4.h: Remove the tag `boolean' on the enum introducing typedef
+ `boolean'. This tag conflicts with &lt;sys/types.h&gt; on SVR4.
+ Reported by Tom McConnell.
+
+1992-11-13 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;errno.h&gt; and
+ ensure that it does not define errno.
+ Reported by Richard Stallman.
+
+1992-11-11 François Pinard &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;sys/types.h&gt; 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;pinard@iro.umontreal.ca&gt;
+
+ * 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 &lt;seindal@diku.dk&gt;
+
+ * 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 &lt;seindal@diku.dk&gt;
+
+ * Fixed various bugs. Release 0.99, manual 0.09. Many thanks to
+ Francois 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 &lt;seindal@diku.dk&gt;
+
+ * 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 &lt;seindal@diku.dk&gt;
+
+ * Initial beta release. Release 0.50, manual 0.05.
+
+</PRE>
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/download.htm b/examples/WWW/download.htm
new file mode 100644
index 00000000..9b714f32
--- /dev/null
+++ b/examples/WWW/download.htm
@@ -0,0 +1,302 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - Download</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>Download</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<P>
+In the download area there are usually several version
+present. Please take only the latest.
+</P>
+
+
+<P>
+The files are name <TT>m4-1.4<I>X</I>.tar.gz</TT> where X is a letter.
+</P>
+
+
+<P>
+<A HREF="ftp://ftp.seindal.dk/pub/rene/gnu/">Download latest
+development version</A>.
+</P>
+
+
+<P>
+<A HREF="ftp://ftp.seindal.dk/pub/rene/gnu/m4-1.4.tar.gz">Download
+latest stable version</A>.
+</P>
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/features.htm b/examples/WWW/features.htm
new file mode 100644
index 00000000..ce8f1895
--- /dev/null
+++ b/examples/WWW/features.htm
@@ -0,0 +1,380 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - New feaures since version 1.4</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>New feaures since version 1.4</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<P>
+Please look at the <A HREF="news.htm">NEWS</A> and the <A HREF="changelog.htm">ChangeLog</A> for all the gory details.
+</P>
+
+
+<DL>
+<DT><B>GNU m4 uses GNU Automake and GNU Autoconf for configuration.</B></DT>
+
+<DD>
+<P>
+This has been long overdue and now hit is done thanks to Erick
+Branderhorst.
+</P>
+
+</DD>
+
+
+<DT><B>GNU m4 uses GNU gettext for internationalisation.</B></DT>
+
+<DD>
+<P>
+GNU m4 now speaks several languages. Translations for
+german french italian japanese dutch polish romenian and swedish
+have been made.
+</P>
+
+</DD>
+
+
+<DT><B>Support for multiple precision arithmetic in eval.</B></DT>
+
+<DD>
+<P>
+If appropriately configured GNU m4 can now do multiple precision
+arithmetic in the build in macro 'eval'. If not configured GNU m4
+will use the largest integer available for its calculations.
+</P>
+
+</DD>
+
+
+<DT><B>An input syntax table to change how input is parsed.</B></DT>
+
+<DD>
+<P>
+A new build in macro 'changesyntax' allows finer control over how input
+characters are parsed into input tokens.&nbsp; It is no 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>
+
+
+<P>
+See the <A HREF="man/m4_7.html#SEC41">manual section</A> for more details.
+</P>
+
+</DD>
+
+
+<DT><B>Support for loadable modules.</B></DT>
+
+<DD>
+<P>
+GNU m4 now has rudimentary support for dynamic loading of
+compiled modules at runtime. A module can define any number of new build
+in macros which will be indistinguishable from the standard set of
+build in macros. Modules can also override existing build in macros.
+</P>
+
+
+<P>
+Module support for GNU m4 still needs some work.
+</P>
+
+
+<P>
+See the <A HREF="modules.htm">separate README file for modules</A>
+</P>
+
+
+</DD>
+
+
+<DT><B>Better control of sync-lines generation.</B></DT>
+
+<DD>
+<P>
+The new build in macro 'syncoutput' allows better control of the
+generation of sync-lines.&nbsp; They can no be turned on or off at
+will.
+</P>
+
+</DD>
+
+
+
+</DL>
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/feedback.htm b/examples/WWW/feedback.htm
new file mode 100644
index 00000000..f6a991d1
--- /dev/null
+++ b/examples/WWW/feedback.htm
@@ -0,0 +1,297 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - Feedback</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>Feedback</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<P>
+Bug reports should be sent to <A HREF="mailto:bug-m4@gnu.org">bug-m4@gnu.org</A>.
+</P>
+
+
+<P>
+Generel discussion about GNU m4 should take place on
+<A HREF="mailto:m4-forum@seindal.dk">m4-forum</A>.
+</P>
+
+
+<P>
+Informal comments about this site and GNU m4 can be sent to
+<A HREF="mailto:m4-feedback@seindal.dk">m4-feedback</A>.
+</P>
+
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/index.htm b/examples/WWW/index.htm
new file mode 100644
index 00000000..8e739aef
--- /dev/null
+++ b/examples/WWW/index.htm
@@ -0,0 +1,319 @@
+<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 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>Development site</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<H2>Current development version is 1.4l.</H2>
+
+
+<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
+<A HREF="features.htm">new features</A> for more detail):
+</P>
+
+
+<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.
+
+</UL>
+
+
+<P>
+A new release is expected ready for December 1998.
+</P>
+
+
+<P>
+GNU <TT>m4</TT> 1.4 is from october 1994 and can be considered stable.
+</P>
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/lists.htm b/examples/WWW/lists.htm
new file mode 100644
index 00000000..afa2b9be
--- /dev/null
+++ b/examples/WWW/lists.htm
@@ -0,0 +1,320 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - Mailing lists</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>Mailing lists</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+
+<H3>There are two mailing lists for GNU m4</H3>
+
+
+<DL>
+<DT><B><A HREF="mailto:m4-forum@seindal.dk">m4-forum@seindal.dk</A></B></DT>
+
+<DD>
+<P>
+This list is intended for discussions between people interested
+and/or participating in the further development of m4.
+</P>
+
+</DD>
+
+
+<DT><B>m4-announce@seindal.dk</B></DT>
+
+<DD>
+<P>
+Announcements regarding GNU m4 will posted here.
+</P>
+
+<P>
+The volume will certainly be very low.
+</P>
+
+</DD>
+
+
+
+</DL>
+
+
+<P>
+Currently these lists are maintained manually. Send a message to <A HREF="mailto:rene@seindal.dk">rene@seindal.dk</A>
+saying whether you want to subscribe or unsubscribe to any of these
+lists.
+</P>
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/m4lib/bugs.m4 b/examples/WWW/m4lib/bugs.m4
new file mode 100644
index 00000000..f3204317
--- /dev/null
+++ b/examples/WWW/m4lib/bugs.m4
@@ -0,0 +1,52 @@
+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([])
+
+])
diff --git a/examples/WWW/m4lib/changelog.m4 b/examples/WWW/m4lib/changelog.m4
new file mode 100644
index 00000000..cdcab269
--- /dev/null
+++ b/examples/WWW/m4lib/changelog.m4
@@ -0,0 +1,18 @@
+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/examples/WWW/m4lib/download.m4 b/examples/WWW/m4lib/download.m4
new file mode 100644
index 00000000..a26eedfb
--- /dev/null
+++ b/examples/WWW/m4lib/download.m4
@@ -0,0 +1,21 @@
+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]).)
+
+\divert(0)\dnl
+\DO_LAYOUT([\undivert(1)])
+\divert(-1)
diff --git a/examples/WWW/m4lib/features.m4 b/examples/WWW/m4lib/features.m4
new file mode 100644
index 00000000..67bb8b2a
--- /dev/null
+++ b/examples/WWW/m4lib/features.m4
@@ -0,0 +1,62 @@
+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 build 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 no 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 rudimentary support for dynamic loading of
+compiled modules at runtime. A module can define any number of new build
+in macros, which will be indistinguishable from the standard set of
+build in macros. Modules can also override existing build in macros.)
+
+\p(Module support for GNU m4 still needs some work.)
+
+\p(See the \link(modules.htm, separate README file for modules))
+)
+
+\dt(\b(Better control of sync-lines generation.))
+
+\dd(\p(The new build in macro 'syncoutput' allows better control of the
+generation of sync-lines.&nbsp; They can no be turned on or off at
+will.))
+
+)
+
+\divert(0)\dnl
+\DO_LAYOUT([\undivert(1)])
+\divert(-1)
diff --git a/examples/WWW/m4lib/feedback.m4 b/examples/WWW/m4lib/feedback.m4
new file mode 100644
index 00000000..f61d63e5
--- /dev/null
+++ b/examples/WWW/m4lib/feedback.m4
@@ -0,0 +1,20 @@
+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/examples/WWW/m4lib/html.m4 b/examples/WWW/m4lib/html.m4
new file mode 100644
index 00000000..50330af2
--- /dev/null
+++ b/examples/WWW/m4lib/html.m4
@@ -0,0 +1,119 @@
+\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([$0], $@)])
+
+\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([ul], [\large_container([$0], $@)])
+\define([ol], [\large_container([$0], $@)])
+
+\define([li], [\simple_tag([$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/examples/WWW/m4lib/index.m4 b/examples/WWW/m4lib/index.m4
new file mode 100644
index 00000000..043faa35
--- /dev/null
+++ b/examples/WWW/m4lib/index.m4
@@ -0,0 +1,36 @@
+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 December 1998.])
+
+\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/examples/WWW/m4lib/layout.m4 b/examples/WWW/m4lib/layout.m4
new file mode 100644
index 00000000..6feb08ec
--- /dev/null
+++ b/examples/WWW/m4lib/layout.m4
@@ -0,0 +1,50 @@
+\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=center 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)]);
+
diff --git a/examples/WWW/m4lib/lists.m4 b/examples/WWW/m4lib/lists.m4
new file mode 100644
index 00000000..cc710eba
--- /dev/null
+++ b/examples/WWW/m4lib/lists.m4
@@ -0,0 +1,32 @@
+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/examples/WWW/m4lib/menu.m4 b/examples/WWW/m4lib/menu.m4
new file mode 100644
index 00000000..1a770b63
--- /dev/null
+++ b/examples/WWW/m4lib/menu.m4
@@ -0,0 +1,35 @@
+\pushdef([header], [\tr([\td([\C_BG3], [\p([\b([$1])])])])])
+\pushdef([row], [\tr([\td([\font([size=-1], [\p([\b([\link([$1], [$2])])])])])])])
+
+\table([align=left valign=top columns=1],
+ [\header([Generel info])],
+ [\row([whatis.htm], [What is m4])],
+ [\row([features.htm], [Features])],
+ [\row([uses.htm], [Uses of m4])],
+
+ [\header([Documentation])],
+ [\row([man/m4_toc.html], [Manual])],
+
+ [\header([Source files])],
+ [\row([readme.htm], [README])],
+ [\row([todo.htm], [TODO])],
+ [\row([news.htm], [NEWS])],
+ [\row([changelog.htm], [ChangeLog])],
+ [\row([thanks.htm], [Contributors])],
+ [\row([m4/], [Browse it])],
+
+ [\header([The Future])],
+ [\row([modules.htm], [Modules])],
+ [\row([visions.htm], [Visions])],
+
+ [\header([Development])],
+ [\row([lists.htm], [Mailing-lists])],
+ [\row([feedback.htm], [Feedback])],
+ [\row([download.htm], [Download])],
+
+ [\header([Examples])],
+ [\row([thissite.htm], [This site])],
+ )
+
+\popdef([header])
+\popdef([row])
diff --git a/examples/WWW/m4lib/modules.m4 b/examples/WWW/m4lib/modules.m4
new file mode 100644
index 00000000..b9c148f1
--- /dev/null
+++ b/examples/WWW/m4lib/modules.m4
@@ -0,0 +1,18 @@
+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/examples/WWW/m4lib/news.m4 b/examples/WWW/m4lib/news.m4
new file mode 100644
index 00000000..e5da0d89
--- /dev/null
+++ b/examples/WWW/m4lib/news.m4
@@ -0,0 +1,18 @@
+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/examples/WWW/m4lib/readme.m4 b/examples/WWW/m4lib/readme.m4
new file mode 100644
index 00000000..1612c7d1
--- /dev/null
+++ b/examples/WWW/m4lib/readme.m4
@@ -0,0 +1,18 @@
+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/examples/WWW/m4lib/setup.m4 b/examples/WWW/m4lib/setup.m4
new file mode 100644
index 00000000..310b65f8
--- /dev/null
+++ b/examples/WWW/m4lib/setup.m4
@@ -0,0 +1,7 @@
+divert(-1)
+changequote([,])
+changecom([<!--], [-->])
+changesyntax([@\])
+
+\include([html.m4])
+\include([layout.m4])
diff --git a/examples/WWW/m4lib/test.m4 b/examples/WWW/m4lib/test.m4
new file mode 100644
index 00000000..9fdef40b
--- /dev/null
+++ b/examples/WWW/m4lib/test.m4
@@ -0,0 +1,9 @@
+include(`_setup.m4')
+\include([_html.m4])
+\include([_layout.m4])
+
+\set_title([Development site])
+
+\divert
+
+\DO_BODY([BODY])
diff --git a/examples/WWW/m4lib/thanks.m4 b/examples/WWW/m4lib/thanks.m4
new file mode 100644
index 00000000..61928d07
--- /dev/null
+++ b/examples/WWW/m4lib/thanks.m4
@@ -0,0 +1,18 @@
+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/examples/WWW/m4lib/thissite.m4 b/examples/WWW/m4lib/thissite.m4
new file mode 100644
index 00000000..0d4d772b
--- /dev/null
+++ b/examples/WWW/m4lib/thissite.m4
@@ -0,0 +1,39 @@
+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)).)
+
+\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 with 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 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/examples/WWW/m4lib/tmpl.m4 b/examples/WWW/m4lib/tmpl.m4
new file mode 100644
index 00000000..8262d293
--- /dev/null
+++ b/examples/WWW/m4lib/tmpl.m4
@@ -0,0 +1,11 @@
+include(`setup.m4')
+
+\set_author([René Seindal])
+\set_title([])
+
+\divert(1)
+\h2([])
+
+\divert(0)\dnl
+\DO_LAYOUT([\undivert(1)])
+\divert(-1)
diff --git a/examples/WWW/m4lib/todo.m4 b/examples/WWW/m4lib/todo.m4
new file mode 100644
index 00000000..7a22c151
--- /dev/null
+++ b/examples/WWW/m4lib/todo.m4
@@ -0,0 +1,18 @@
+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/examples/WWW/m4lib/uses.m4 b/examples/WWW/m4lib/uses.m4
new file mode 100644
index 00000000..75f7b6ae
--- /dev/null
+++ b/examples/WWW/m4lib/uses.m4
@@ -0,0 +1,36 @@
+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(\link(thissite.htm, These files are created with GNU m4 \__m4_version__).)
+
+
+\divert(0)\dnl
+\DO_LAYOUT([\undivert(1)])
+\divert(-1)
diff --git a/examples/WWW/m4lib/visions.m4 b/examples/WWW/m4lib/visions.m4
new file mode 100644
index 00000000..c904976d
--- /dev/null
+++ b/examples/WWW/m4lib/visions.m4
@@ -0,0 +1,28 @@
+include(`setup.m4')
+
+\set_author([René Seindal])
+\set_title([The Road Ahead])
+
+\divert(1)
+\h2([Possible features for future versions])
+
+
+\ul(
+
+\li \p(Guile can be used as an extension language so complicated macros can be
+written in Scheme while still maintaining the m4 interface.)
+
+\li\p(A kind of super-quotes can be added, quotes that aren't stripped
+when read, as are normal quotes. These quotes should be stripped when
+output. In that way text can be super-quote and consequently passed
+untouched to the output. It is a bit like comments, but there the
+quotes are removed before output.)
+
+)
+
+\p(See also the \link(todo.htm, TODO) file.)
+
+
+\divert(0)\dnl
+\DO_LAYOUT([\undivert(1)])
+\divert(-1)
diff --git a/examples/WWW/m4lib/whatis.m4 b/examples/WWW/m4lib/whatis.m4
new file mode 100644
index 00000000..506269a2
--- /dev/null
+++ b/examples/WWW/m4lib/whatis.m4
@@ -0,0 +1,43 @@
+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. It is mostly SVR4 compatible, 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. GNU m4 is mostly compatible with the
+System V, Release 3 version, except for some minor differences.])
+
+\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.])
+
+\divert(0)\dnl
+\DO_LAYOUT([\undivert(1)])
+\divert(-1)
diff --git a/examples/WWW/modules.htm b/examples/WWW/modules.htm
new file mode 100644
index 00000000..ee668972
--- /dev/null
+++ b/examples/WWW/modules.htm
@@ -0,0 +1,347 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - Modules</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>Modules</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<PRE>This directory contains demonstration modules for GNU m4.
+
+Nothing in this directory is built by default.
+
+Dynamic modules is a experimental feature of GNU m4. Currently it has
+only been certified to work under Linux 2.0.
+
+Dynamic modules are only available if GNU m4 was configured with
+--with-modules and if the dlopen(3) interface is available in the
+operating system.
+
+Implementation details are in ../src/module.c
+
+A module is a compiled shared object, i.e., modules are written in C and
+then compiled. The compiled file can then be loaded into a running m4
+process by calling the builtin "loadmodule". This will give GNU m4
+access to any system feature with a C interface.
+
+Modules are searched for in M4MODPATH, if set, and in a module directory
+defined at configure time, default /usr/local/libexec/m4.
+
+A module extends GNU m4 by defining new builtins, It can define builtins
+with the same names as existing builtins, which will then be
+unavailable. A module cannot redefine internal functions of GNU m4,
+such as the input parser or argument handling.
+
+The infrastructure for writing and compiling modules is still a bit
+wanting.
+
+Each module should include the two header files ../src/m4.h and
+../src/builtin.h. These will include &lt;ctype.h&gt;, &lt;stdio.h&gt;,
+../lib/obstack.h and ../config.h.
+
+Each module *must* define the symbol "m4_macro_table" as a pointer to a
+table of "struct builtin" (defined in m4.h). The table ends with an
+entry with name == NULL. The builtins described in the table will be
+defined by GNU m4 as were they normal builtins.
+
+If a module defines the symbol "m4_init_module", it is supposed to be a
+function with a prototype of "void m4_init_module(struct obstack *obs)",
+and it will be called as soon as the module is loaded. Any non-finished
+object left on the obstack will be the expansion of the call of the
+builtin "loadmodule". The obstack pointer might be NULL (in the future).
+
+If a module defines the symbol "m4_finish_module", it is supposed to be
+a function with a prototype of "void m4_finish_module(void)", and it
+will be called just before GNU m4 exits. This will allow a module to
+clean up before exit. There is no way of communicating information to
+the user, as GNU m4 exits immeidately afterwards.
+
+No other symbols will be used by GNU m4. Other external symbols within
+the module are private and will not be accessible to GNU m4 or to other
+modules.
+
+Modules are allowed to call external functions already defined within
+the GNU m4 sources. Some of these have prototypes in builtin.h.
+
+
+A complete, though silly, example is found in test.c. A more
+interesting example is in time.c.
+
+To try the demos, compile with `make' and run them with the commands as:
+
+ M4MODPATH=`pwd` ../src/m4 time.m4
+
+
+</PRE>
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/news.htm b/examples/WWW/news.htm
new file mode 100644
index 00000000..ed4f374f
--- /dev/null
+++ b/examples/WWW/news.htm
@@ -0,0 +1,551 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - NEWS - History of user-visible changes</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>NEWS - History of user-visible changes</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<PRE>GNU m4 NEWS - History of user-visible changes. -*-indented-text-*-
+Copyright (C) 1992, 1993, 1994, 1998 Free Software Foundation, Inc.
+
+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"
+ &lt;bfox@datawave.net&gt;, who have 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, `&lt;&lt;' and `&gt;&gt;' 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 built-in 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:
+
+</PRE>
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/readme.htm b/examples/WWW/readme.htm
new file mode 100644
index 00000000..09d483e7
--- /dev/null
+++ b/examples/WWW/readme.htm
@@ -0,0 +1,329 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - README</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>README</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<PRE>GNU `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). `m4' also has built-in functions for including files,
+running shell commands, doing arithmetic, etc. Autoconf needs GNU
+`m4' for generating `configure' scripts, but not for running them.
+
+GNU `m4' has been originally written by René Seindal, from Denmark.
+
+If GNU `m4' is meant to serve GNU `autoconf', beware that `m4'
+should be fully installed *prior to* configuring `autoconf' itself.
+
+In the subdirectories `tests' and `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.
+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 `THANKS' for a list of contributors.
+
+By using `./configure --with-gmp, you get multiple precision integral
+and rational arithmetic in eval. The implementation depends on the GNU
+gmp v2 library.
+
+By using `./configure --with-modules, you get the possibility of using
+dynamic modules. The implementation depends on dlopen(3) interface.
+See file `modules/README' for a more detailed description.
+
+By using `./configure --enable-changeword', you get an experimental
+feature which allows for changing the syntax of what is a "word" in
+`m4'. THIS WILL PROBABLY GO AWAY, so don't count on it. Some of the
+same things can be achieved with `changesyntax' at a much better speed.
+
+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.
+
+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, ...
+
+</PRE>
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/thanks.htm b/examples/WWW/thanks.htm
new file mode 100644
index 00000000..78470a16
--- /dev/null
+++ b/examples/WWW/thanks.htm
@@ -0,0 +1,377 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - People who have contributed to m4</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>People who have contributed to m4</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<PRE>GNU m4 THANKS file
+
+GNU m4 has originally been written by Rene' Seindal. Many people
+further contributed to GNU m4 by reporting problems, suggesting
+various improvements or submitting actual code. Here is a list of
+these people. Help me keep it complete and exempt of errors.
+
+
+
+Akiko Matsushita matusita@sra.co.jp
+Alan Magnuson awm@osc.edu
+Alexander Lehmann alex@hal.rhein-main.de
+Amos Shapira amoss@cs.huji.ac.il
+Andreas Gustafsson gson@niksula.hut.fi
+Andreas Schwab schwab@ls5.informatik.uni-dortmund.de
+Andrew Athan athan@morgan.com
+Andrew Bettison andrewb@zip.com.au
+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
+Brendan Kehoe brendan@cygnus.com
+Brian J. Fox bfox@datawave.net
+Brian D. Carlstrom bdc@clark.lcs.mit.edu
+David J. MacKenzie djm@uunet.uu.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
+François Pinard pinard@iro.umontreal.ca
+Gary Affonso Gary_Affonso@iqinc.com
+Geoff Russell grussell@guest.adelaide.edu.au
+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
+Jan Djarv Jan.Djarv@sa.erisoft.se
+Jason Merrill jason@jarthur.claremont.edu
+Jim Avera jima@netcom.com
+Jim Kingdom kingdon@cygnus.com
+Jim Meyering meyering@na-net.ornl.gov
+Joel Sherrill jsherril@uahcs2.cs.uah.edu
+John David Anglin dave@hiauly1.hia.nrc.ca
+John Gerard Malecki johnm@artisan.com
+Joseph E. Sacco jsacco@ssl.com
+Joshua R. Poulson jrp@plaza.ds.adp.com
+Karl Berry karl@cs.umb.edu
+Karl Vogel vogelke@c-17igp.wpafb.af.mil
+Kaveh R. Ghazi ghazi@noc.rutgers.edu
+Keith Bostic bostic@abyssinian.sleepycat.com
+Kristine Lund lund@lpnaxp.in2p3.fr
+Krste Asanovic krste@icsi.berkeley.edu
+Marcus Daniels marcus@ee.pdx.edu
+Marion Hakanson hakanson@cse.ogi.edu
+Mark Seiden mis@seiden.com
+Massimo Dal Zotto dz@cs.unitn.it
+Matthias Rabe rabe@mathematik.uni-bielefeld.de
+Michael Fetterman mafetter@ichips.intel.com
+Michael L. Welcome welcome@bigbird.llnl.gov
+Mike Andrews kramer@fragile.termfrost.org
+Mike Howard mike@clove.com
+Mike Lijewski lijewski@theory.tc.cornell.edu
+Nick S. Kanakakorn skanan@otl.scu.edu
+Nicolas Pioch pioch@inf.enst.fr
+Noah Friedman friedman@gnu.org
+Pete Chown pete.chown@dale.dircon.co.uk
+Pierre Gaumond gaumondp@ere.umontreal.ca
+Pierre Mathieu mathieu@geod.emr.ca
+Rafael Corvalan rafael@club-internet.fr
+René Seindal rene@seindal.dk
+Richard Ling richard@research.canon.oz.au
+Richard Stallman rms@gnu.org
+Robert Bernstein rocky@panix.com
+Roland H. Pesch roland@wrs.com
+Roland McGrath roland@gnu.org
+Scott Bartram deneb!scottb
+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
+Terry Jones terry@cliffs.ucsd.edu
+Thorsten Ohl ohl@physics.harvard.edu
+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
+Vivek P. Singhal singhal@cs.utexas.edu
+Walter Wong wcw+@cmu.edu
+
+</PRE>
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/thissite.htm b/examples/WWW/thissite.htm
new file mode 100644
index 00000000..03e2a01a
--- /dev/null
+++ b/examples/WWW/thissite.htm
@@ -0,0 +1,327 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - This site</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>This site</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<P>
+This GNU m4 site is maintained by René Seindal (<A HREF="mailto:rene@seindal">rene@seindal</A>).
+</P>
+
+
+<P>
+All files are generated using GNU m4 1.4l. You can view
+the <A HREF="m4lib/">source files</A>. They are very simple. They use some
+features from Gnu m4 1.4l
+</P>
+
+
+<P>
+The basic M4 definitions of quotes comments escapes are in
+<A HREF="m4lib/setup.m4">m4lib/setup.m4</A>. 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</I>.
+</P>
+
+
+<P>
+Some fairly general macros to generate various HTML construct are
+found in <A HREF="m4lib/html.m4">m4lib/html.m4</A>. There are macros for simple tags containers with and with attributes links and a few utility macros.
+</P>
+
+
+<P>
+The visual aspects of the pages are in <A HREF="m4lib/layout.m4">m4lib/layout.m4</A>.
+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>
+
+
+<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
+<A HREF="m4lib/thissite.m4">these definitions</A>.
+</P>
+
+
+<P>
+There is a single file for each HTML file.
+</P>
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/todo.htm b/examples/WWW/todo.htm
new file mode 100644
index 00000000..9c5100f1
--- /dev/null
+++ b/examples/WWW/todo.htm
@@ -0,0 +1,388 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - TODO - Things still to be done</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>TODO - Things still to be done</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<PRE>* TODO file for GNU m4 -*- indented-text -*-
+
+Tell the maintainers at &lt;bug-m4@gnu.org&gt; if you feel like volunteering
+for any of these ideas or if you have others to add.
+
+
+* Features or problems
+
+ + GMP eval() should be enables if the library is present, maybe by
+ providing two different versions of eval(). That way users can
+ choose whether to use gmp on an individual basis.
+
+ + There should be a way ot have m4 discard comments instead of
+ outputting them.
+
+ + Implement discarding comment delimiters with the syntax table.
+
+ + The module system is still rudimentary (see below)
+
+ + Changes in the syntax_table are not saved to frozen files.
+
+ + Information about loaded modules is not saved to frozen files.
+
+ + m4wrap.1.test fail on Solaris 2.6 using egcs 1.1a compiler (Erick B).
+
+ + The $ used in user defined macros cannot be changed through
+ changesyntax. It should be handled as a modifier.
+
+ + Make show include dependencies like gcc so targets are updated
+ when their (included) input files are updated (Erick B).
+
+ + The test case `other-tests/stackovf.test' does not work.
+
+ + Sort out all the weird forms of interaction between changesyntax,
+ changecom and changequote. What happens if you install a quote with
+ changequote and removes it with changesyntax and vice versa.
+
+ + 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.).
+
+
+* Module specific issues
+
+ + Support for other DL interfaces besides dlopen, such as dld and
+ hpux is still missing.
+
+ + Modules should be loadable from the command line with something like
+ `-M module.so' o `--load-module=module.so'. M4 should abort if it
+ fails.
+
+ + Some way of linking a module statically is needed, for systems
+ without support for dynamic loading.
+
+
+
+Below is the old 1.4 TODO list, several years old. Only a few points
+have been kept. Some things are fixed, many others just seem
+dated. Write me if I have been to harsh. (René Seindal)
+
+------------------------------------------------------------------------
+Tell &lt;pinard@iro.umontreal.ca&gt; if you feel like volunteering for any
+of these ideas, listed more or less in decreasing order of priority.
+Some TODO items are implicit from received email. See file BACKLOG.
+
+.* Features or problems
+. + Update documentation from accumulated mail about it
+. + Changeword without arguments should restore default behavior
+. + Study synclines at the very beginning of each diverted sequence
+. + Make eval work on bignums - the 32 bits limit is artificial
+ From Krste Asanovic &lt;krste@icsi.berkeley.edu&gt;, 1993-03-20
+. + Make show include dependencies like gcc so targets are updated
+ when their (included) input files are updated (Erick B).
+. + Ask FSF to create m4-bugs@gnu.org for bug reports (Erick B).
+. + m4wrap.1.test fail on Solaris 2.6 using egcs 1.1a compiler (Erick B).
+
+.* Optimization and clean up
+. + Check for memory leaks and uninitialized reads
+ From Vern Paxson &lt;vern@horse.ee.lbl.gov&gt; on 1993-12-06
+. + Simplify format/ecvt code, together with HAVE_EFGCVT
+. + Finalize the stdarg vs varargs thing
+. + Profile GNU m4 and speed it up
+ From David J. MacKenzie &lt;djm@eng.umd.edu&gt;, 1993-01-20
+
+ GNU m4 should be sped up by a factor of three for competing
+ with other versions (I think that the lexer is not agressive
+ enough and too often return single characters; obstacks might
+ be a little abused, too).
+. + Have NULs go really undisturbed through GNU m4
+ See `dumpdef' and debugging section, which abuses %s
+ From Thorsten Ohl &lt;ohl@chico.harvard.edu&gt;, 1992-12-21
+
+ path.c (add_include_directory): Why the '\0' terminator?
+
+ GNU m4 is lousy regarding NULs in streams (this would require
+ maintaining the string lengths, and avoiding strlen, strcpy,
+ etc.).
+. + Clean up the obstack.[ch] code
+. + Use rx.[ch] instead of regex.[ch]
+ From Hal Peterson &lt;hrp@ironwood.cray.com&gt;, 1994-04-22
+
+</PRE>
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/uses.htm b/examples/WWW/uses.htm
new file mode 100644
index 00000000..9988dacf
--- /dev/null
+++ b/examples/WWW/uses.htm
@@ -0,0 +1,322 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - Current uses of m4</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>Current uses of m4</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<P>
+The MTA sendmail uses <TT>m4</TT> for generating configuration files.
+</P>
+
+
+<P>
+<A HREF="http://www.gnu.org/software/autoconf/autoconf.html">GNU
+Autoconf</A> uses <TT>m4</TT> to generate "configure" scripts that are used
+for configuring <A HREF="http://www.gnu.org/">GNU</A> software for a
+particular platform.
+</P>
+
+
+<P>
+Htm4l is a set of macros for generating HTML. Html4 is written by
+Terry Jones (terry@cliffs.ucsd.edu). See
+<A HREF="http://cliffs.ucsd.edu/terry/htm4l/htm4l/main.html">http://cliffs.ucsd.edu/terry/htm4l/htm4l/main.html</A> for
+details.
+</P>
+
+
+<P>
+Various programs uses m4 to preprocess configuration files for
+example the X11 window manager fvwm.
+</P>
+
+
+<P>
+There is an <A HREF="http://www.ssc.com/lg/issue22/using_m4.html">article in the Linux Gazette</A> about writing HTML with GNU m4 written by
+<A HREF="mailto:bhepple@bit.net.au">Bob Hepple</A> . More recent versions
+are kept at <A HREF="http://www.bit.net.au/~bhepple">Bob's home site</A>.
+The macros are used to maintain a large commercial site at
+<A HREF="http://www.finder.com.au">http://www.finder.com.au</A>.
+</P>
+
+
+
+<P>
+<A HREF="thissite.htm">These files are created with GNU m4 1.4l</A>.
+</P>
+
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/visions.htm b/examples/WWW/visions.htm
new file mode 100644
index 00000000..eceec6f7
--- /dev/null
+++ b/examples/WWW/visions.htm
@@ -0,0 +1,309 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - The Road Ahead</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>The Road Ahead</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<H2>Possible features for future versions</H2>
+
+
+
+<UL>
+<LI> <P>
+Guile can be used as an extension language so complicated macros can be
+written in Scheme while still maintaining the m4 interface.
+</P>
+
+
+<LI><P>
+A kind of super-quotes can be added quotes that aren't stripped
+when read as are normal quotes. These quotes should be stripped when
+output. In that way text can be super-quote and consequently passed
+untouched to the output. It is a bit like comments but there the
+quotes are removed before output.
+</P>
+
+
+
+</UL>
+
+
+<P>
+See also the <A HREF="todo.htm">TODO</A> file.
+</P>
+
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/WWW/whatis.htm b/examples/WWW/whatis.htm
new file mode 100644
index 00000000..3f793cd0
--- /dev/null
+++ b/examples/WWW/whatis.htm
@@ -0,0 +1,327 @@
+<DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
+<HTML>
+<HEAD>
+<TITLE>GNU m4 - What is GNU m4</TITLE>
+<META NAME="AUTHOR" CONTENT="René Seindal">
+<META NAME="GENERATOR" CONTENT="GNU m4 1.4l">
+</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=center colspan="3" width="100%" bgcolor="#FF9900">
+
+<H1>GNU m4</H1>
+
+<H2>What is GNU m4</H2>
+
+</TD>
+
+</TR>
+ <TR >
+<TD align=left valign=top width="15%" bgcolor="#FF9900">
+
+
+
+<TABLE align=left valign=top columns=1>
+<TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Generel info</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="whatis.htm">What is m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="features.htm">Features</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="uses.htm">Uses of m4</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Documentation</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="man/m4_toc.html">Manual</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Source files</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="readme.htm">README</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="todo.htm">TODO</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="news.htm">NEWS</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="changelog.htm">ChangeLog</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thanks.htm">Contributors</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="m4/">Browse it</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>The Future</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="modules.htm">Modules</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="visions.htm">Visions</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Development</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="lists.htm">Mailing-lists</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="feedback.htm">Feedback</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="download.htm">Download</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+ <TR>
+<TD bgcolor="#CC6600">
+<P>
+<B>Examples</B>
+</P>
+
+</TD>
+
+</TR>
+ <TR>
+<TD>
+
+<FONT size=-1><P>
+<B><A HREF="thissite.htm">This site</A></B>
+</P>
+</FONT>
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+
+
+
+
+</TD>
+ <TD align=left valign=top width="90%">
+
+
+<P>
+GNU <TT>m4</TT> 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). GNU
+<TT>m4</TT> also has built-in functions for including files, running shell
+commands, doing arithmetic, etc.
+</P>
+
+
+<P>
+GNU <TT>m4</TT> 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>
+
+
+<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. GNU m4 is mostly compatible with the
+System V, Release 3 version, except for some minor differences.
+</P>
+
+
+<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>
+
+
+<P>
+Autoconf needs GNU m4 for generating `configure' scripts, but not for
+running them.
+</P>
+
+
+
+</TD>
+
+</TR>
+
+</TABLE>
+
+</BODY>
+
+
+</HTML>
+
+
diff --git a/examples/capitalize.m4 b/examples/capitalize.m4
new file mode 100644
index 00000000..5c28de22
--- /dev/null
+++ b/examples/capitalize.m4
@@ -0,0 +1,8 @@
+dnl
+dnl convert to upper- resp. lowercase
+define(`upcase', `translit(`$*', `a-z', `A-Z')')
+define(`downcase', `translit(`$*', `A-Z', `a-z')')
+dnl
+dnl capitalize a single word
+define(`capitalize1', `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')
+define(`capitalize', `patsubst(`$1', `\w+', ``'capitalize1(`\0')')')
diff --git a/examples/capitalize.test b/examples/capitalize.test
new file mode 100755
index 00000000..5b80f5c0
--- /dev/null
+++ b/examples/capitalize.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# capitalize.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/capitalize.m4 >in
+
+cat <<\EOF >ok
+
+
+CONVERT TO UPPER CASE
+convert to lower case
+
+
+This Sentence Should Be Capitalized
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/comments.m4 b/examples/comments.m4
new file mode 100644
index 00000000..c1e3be0a
--- /dev/null
+++ b/examples/comments.m4
@@ -0,0 +1,7 @@
+# An ordinary comment
+define(`foo', # A comment in a macro
+`Macro `foo' expansion')
+foo
+define(`comment', `*** Macro `comment' expansion ***')
+changecom(`@', `@')
+foo
diff --git a/examples/comments.test b/examples/comments.test
new file mode 100755
index 00000000..63161dc2
--- /dev/null
+++ b/examples/comments.test
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# comments.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(comments.m4)dnl
+EOF
+
+cat <<\EOF >ok
+# An ordinary comment
+
+# A comment in a macro
+Macro foo expansion
+
+
+# A *** Macro comment expansion *** in a macro
+Macro foo expansion
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
diff --git a/examples/ddivert.m4 b/examples/ddivert.m4
new file mode 100644
index 00000000..e6e0017e
--- /dev/null
+++ b/examples/ddivert.m4
@@ -0,0 +1,4 @@
+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/examples/ddivert.test b/examples/ddivert.test
new file mode 100755
index 00000000..5db82e90
--- /dev/null
+++ b/examples/ddivert.test
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# ddivert.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(ddivert.m4)dnl
+EOF
+
+cat <<\EOF >ok
+Text diverted a first time.
+Text diverted a second time.
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
diff --git a/examples/debug.m4 b/examples/debug.m4
new file mode 100644
index 00000000..16f4c74e
--- /dev/null
+++ b/examples/debug.m4
@@ -0,0 +1,4 @@
+define(`countdown', `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Liftoff')')
+debugmode(`aeqc')
+traceon(`countdown')
+countdown(2)
diff --git a/examples/debug.test b/examples/debug.test
new file mode 100755
index 00000000..0260641e
--- /dev/null
+++ b/examples/debug.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# debug.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(debug.m4)dnl
+EOF
+
+cat <<\EOF >ok
+
+
+
+2 1 0 Liftoff
+EOF
+
+cat <<\EOF >okerr
+m4trace: -1- countdown ...
+m4trace: -1- countdown(`2') -> ???
+m4trace: -1- countdown(...) -> `2 ifelse(eval(2 > 0), 1, `countdown(decr(2))', `Liftoff')'
+m4trace: -1- countdown ...
+m4trace: -1- countdown(`1') -> ???
+m4trace: -1- countdown(...) -> `1 ifelse(eval(1 > 0), 1, `countdown(decr(1))', `Liftoff')'
+m4trace: -1- countdown ...
+m4trace: -1- countdown(`0') -> ???
+m4trace: -1- countdown(...) -> `0 ifelse(eval(0 > 0), 1, `countdown(decr(0))', `Liftoff')'
+EOF
+
+M4PATH=$srcdir $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
diff --git a/examples/defs b/examples/defs
new file mode 100644
index 00000000..cf97e3b3
--- /dev/null
+++ b/examples/defs
@@ -0,0 +1,54 @@
+# -*- ksh -*-
+# Defines for GNU m4 testing environment.
+# Erick Branderhorst <Erick.Branderhorst@asml.nl>
+
+# Ensure $srcdir set correctly.
+test -f ${srcdir}/defs || {
+ echo "defs: installation error" 1>&2
+ exit 1
+}
+
+# If srcdir is relative, we need to modify it.
+case "$srcdir" in
+ /*)
+ ;;
+
+ *)
+ srcdir="../$srcdir"
+ ;;
+esac
+
+rm -rf testSubDir > /dev/null 2>&1
+mkdir testSubDir
+cd testSubDir
+
+# Build appropriate environment in test directory. Eg create
+# configure.in, touch all necessary files, etc.
+
+# nothing yet
+
+# See how redirections should work. User can set VERBOSE to see all
+# output.
+test -z "$VERBOSE" && {
+ exec > /dev/null 2>&1
+}
+
+# User can set MAKE to choose which make to use. Must use GNU make.
+test -z "$MAKE" && MAKE=make
+
+echo "=== Running test $0"
+
+# See how GNU m4 should be run. No options as default.
+test -z "$M4" && M4=../../src/m4
+
+# See how cmp should be run.
+test -z "$CMP" && CMP=cmp
+
+# Setting nls related vars. Override them in the test when needed.
+LANGUAGE=C
+export LANGUAGE
+LC_ALL=C
+export LC_ALL
+LANG=C
+export LANG
+
diff --git a/examples/esyscmd.m4 b/examples/esyscmd.m4
new file mode 100644
index 00000000..b839148c
--- /dev/null
+++ b/examples/esyscmd.m4
@@ -0,0 +1,5 @@
+define(`hostname', esyscmd(`hostname'))dnl
+`hostname = >>'hostname`<<'
+define(`hostname',
+pushdef(`_tmp', `$1')_tmp(translit(esyscmd(`hostname'), `.', `,'))`'popdef(`_tmp'))dnl
+`hostname = >>'hostname`<<'
diff --git a/examples/esyscmd.test b/examples/esyscmd.test
new file mode 100755
index 00000000..47602094
--- /dev/null
+++ b/examples/esyscmd.test
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# esyscmd.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/esyscmd.m4 >in
+
+cat <<\EOF >ok
+# Cannot use real hostname program because test would fail
+hostname = >>www.gnu.org
+<<
+hostname = >>www<<
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/exp.m4 b/examples/exp.m4
new file mode 100644
index 00000000..8aef93e9
--- /dev/null
+++ b/examples/exp.m4
@@ -0,0 +1 @@
+define(`countdown', `$1 ifelse(eval($1 > 0), 1, `countdown(decr($1))', `Done')')
diff --git a/examples/exp.test b/examples/exp.test
new file mode 100755
index 00000000..443e98c7
--- /dev/null
+++ b/examples/exp.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# exp.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/exp.m4 >in
+
+cat <<\EOF >ok
+7
+6
+5
+4
+3
+2
+1
+0
+Done
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/file.m4 b/examples/file.m4
new file mode 100644
index 00000000..e7db5f13
--- /dev/null
+++ b/examples/file.m4
@@ -0,0 +1,5 @@
+changequote([[,]])dnl
+define([[quoteall]], [[patsubst([[[[$*]]]], [[,[ ]+]], [[,]])]])dnl
+define([[group]], quoteall(include([[/etc/group]])))dnl
+dnl
+group()dnl
diff --git a/examples/foreach.m4 b/examples/foreach.m4
new file mode 100644
index 00000000..d5b81866
--- /dev/null
+++ b/examples/foreach.m4
@@ -0,0 +1,19 @@
+divert(-1)
+# foreach(x, (item_1, item_2, ..., item_n), stmt)
+define(`foreach', `pushdef(`$1', `')_foreach(`$1', `$2', `$3')popdef(`$1')')
+define(`_arg1', `$1')
+define(`_foreach',
+ `ifelse(`$2', `()', ,
+ `define(`$1', _arg1$2)$3`'_foreach(`$1', (shift$2), `$3')')')
+# traceon(`define', `foreach', `_foreach', `ifelse')
+divert
+foreach(`x', `(foo, bar, foobar)', `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
diff --git a/examples/foreach.test b/examples/foreach.test
new file mode 100755
index 00000000..969e1638
--- /dev/null
+++ b/examples/foreach.test
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+# foreach.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/foreach.m4 >in
+
+cat <<\EOF >ok
+
+Word was: foo
+Word was: bar
+Word was: foobar
+
+# Something more complex, from Pierre Gaumond <gaumondp@ere.umontreal.ca>.
+case "$1" in
+ a)
+ vara=" -a";;
+ b)
+ varb=" -b";;
+ c)
+ varc=" -c";;
+esac
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/forloop.m4 b/examples/forloop.m4
new file mode 100644
index 00000000..a8bb6bce
--- /dev/null
+++ b/examples/forloop.m4
@@ -0,0 +1,8 @@
+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
diff --git a/examples/forloop.test b/examples/forloop.test
new file mode 100755
index 00000000..f2a41e7d
--- /dev/null
+++ b/examples/forloop.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# forloop.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/forloop.m4 >in
+
+cat <<\EOF >ok
+
+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
+
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/fstab.m4 b/examples/fstab.m4
new file mode 100644
index 00000000..dbf538ae
--- /dev/null
+++ b/examples/fstab.m4
@@ -0,0 +1,7 @@
+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/examples/fstab.test b/examples/fstab.test
new file mode 100755
index 00000000..89fd2c6b
--- /dev/null
+++ b/examples/fstab.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# fstab.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/fstab.m4 >in
+
+cat <<\EOF >ok
+
+
+
+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
+
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/hanoi.m4 b/examples/hanoi.m4
new file mode 100644
index 00000000..c4a80fc6
--- /dev/null
+++ b/examples/hanoi.m4
@@ -0,0 +1,15 @@
+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
diff --git a/examples/hanoi.test b/examples/hanoi.test
new file mode 100755
index 00000000..6080d5f6
--- /dev/null
+++ b/examples/hanoi.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# hanoi.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/hanoi.m4 >in
+
+cat <<\EOF >ok
+
+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.
+
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/incl-test.m4 b/examples/incl-test.m4
new file mode 100644
index 00000000..8b7d223f
--- /dev/null
+++ b/examples/incl-test.m4
@@ -0,0 +1,2 @@
+`include test file.'
+define()
diff --git a/examples/include.m4 b/examples/include.m4
new file mode 100644
index 00000000..fb788047
--- /dev/null
+++ b/examples/include.m4
@@ -0,0 +1,7 @@
+Beginning.
+include(`NOFILE')
+Intermidiate
+include(`test/incl-test.m4')
+After
+include(`NOFILE')
+very late
diff --git a/examples/include.test b/examples/include.test
new file mode 100755
index 00000000..5d0b1100
--- /dev/null
+++ b/examples/include.test
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+# include.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/include.m4 >in
+
+cat <<\EOF >ok
+Beginning.
+
+Intermidiate
+include test file.
+
+
+After
+
+very late
+EOF
+
+cat <<\EOF >okerr
+in:2: m4: Cannot open NOFILE: No such file or directory
+in:6: m4: Cannot open NOFILE: No such file or directory
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/examples/indir.m4 b/examples/indir.m4
new file mode 100644
index 00000000..bc301238
--- /dev/null
+++ b/examples/indir.m4
@@ -0,0 +1,10 @@
+define(`%%$$##', `>>>$0<<< cnt $#')
+
+# indir(`%%$$##', nonsens, nonsens)
+indir(`%%$$##', nonsens, nonsens)
+
+# indir(`indir', `%%$$##', nonsens)
+indir(`indir', `%%$$##', nonsens)
+
+# indir(`indir', `indir', `indir', `indir', `%%$$##')
+indir(`indir', `indir', `indir', `indir', `%%$$##')
diff --git a/examples/indir.test b/examples/indir.test
new file mode 100755
index 00000000..e243f97c
--- /dev/null
+++ b/examples/indir.test
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# indir.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/indir.m4 >in
+
+cat <<\EOF >ok
+
+
+# indir(`%%$$##', nonsens, nonsens)
+>>>%%$$##<<< cnt 2
+
+# indir(`indir', `%%$$##', nonsens)
+>>>%%$$##<<< cnt 1
+
+# indir(`indir', `indir', `indir', `indir', `%%$$##')
+>>>%%$$##<<< cnt 0
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/iso8859.m4 b/examples/iso8859.m4
new file mode 100644
index 00000000..4ac1d196
--- /dev/null
+++ b/examples/iso8859.m4
Binary files differ
diff --git a/examples/iso8859.test b/examples/iso8859.test
new file mode 100755
index 00000000..3cca92e1
--- /dev/null
+++ b/examples/iso8859.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# iso8859.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(iso8859.m4)dnl
+EOF
+
+cat <<\EOF >ok
+# Texting quotes
+DEFINE
+CHANGEQUOTE(«,»)
+0 TEST # TEST
+1 test # test
+2 «test» # «test»
+3 ««test»» # ««test»»
+CHANGEQUOTE(«««,»»»)
+0 TEST # TEST
+1 «TEST» # «TEST»
+2 ««TEST»» # ««TEST»»
+3 test # test
+# Test use of all iso8859 characters except NUL ` '
+Length of string is: 253
+Comparing strings: MATCH
+# NUL does not pass through
+This will be seen.
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
diff --git a/examples/misc.m4 b/examples/misc.m4
new file mode 100644
index 00000000..eff8766d
--- /dev/null
+++ b/examples/misc.m4
@@ -0,0 +1,9 @@
+divert(-1)
+define(`HOST', `vale')
+define(`TMP', maketemp(`/tmp/hejXXXXXX'))
+syscmd(`ypmatch' HOST `hosts | awk "{print \$1}"' > TMP)
+define(`IP', include(TMP))
+syscmd(`rm -f' TMP)
+divert
+
+IP
diff --git a/examples/misc.test b/examples/misc.test
new file mode 100755
index 00000000..59ea58ad
--- /dev/null
+++ b/examples/misc.test
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# misc.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/misc.m4 >in
+
+cat <<\EOF >ok
+
+127.0.0.1
+
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/mktests.sh b/examples/mktests.sh
new file mode 100644
index 00000000..1546b568
--- /dev/null
+++ b/examples/mktests.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+: ${M4:=../../src/m4}
+
+test $# -eq 1 || exit 1
+FILE=`basename $1 .m4`
+
+
+test -r $FILE.m4 || exit 1
+
+if head -1 $FILE.m4 | fgrep -w 'dnl noauto' >/dev/null; then
+ echo "$FILE.test cannot be generated" 1>&2
+ exit 1
+fi
+
+test -d testSubDir || mkdir testSubDir
+
+cat "$FILE.m4" > testSubDir/in
+(cd testSubDir; $M4 -I.. -d "in" >out 2>err)
+
+(
+
+cat <<EOFEOF
+#!/bin/sh
+
+# $FILE.test is part of the GNU m4 testsuite
+
+. \${srcdir}/defs
+
+cat \${srcdir}/$FILE.m4 >in
+EOFEOF
+
+echo
+echo 'cat <<\EOF >ok'
+cat testSubDir/out
+echo EOF
+
+if [ -s testSubDir/err ]; then
+ echo
+ echo 'cat <<\EOF >okerr'
+ sed -e "s, $M4:, m4:," testSubDir/err
+ echo EOF
+fi
+
+echo
+echo 'M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err'
+echo 'sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err'
+
+if [ -s testSubDir/err ]; then
+ echo '$CMP -s out ok && $CMP -s err okerr'
+else
+ echo '$CMP -s out ok'
+fi
+) >$FILE.test.new
+
+if cmp -s $FILE.test.new $FILE.test; then
+ echo "$FILE.test unchanged" 1>&2
+ rm -f $FILE.test.new
+else
+ echo "creating $FILE.test" 1>&2
+ mv $FILE.test.new $FILE.test
+ chmod +x $FILE.test
+fi
+
+rm -f testSubDir/out testSubDir/err
diff --git a/examples/multiquotes.m4 b/examples/multiquotes.m4
new file mode 100644
index 00000000..b56cfbd8
--- /dev/null
+++ b/examples/multiquotes.m4
@@ -0,0 +1,17 @@
+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/examples/multiquotes.test b/examples/multiquotes.test
new file mode 100755
index 00000000..81bd10d1
--- /dev/null
+++ b/examples/multiquotes.test
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# multiquotes.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/multiquotes.m4 >in
+
+cat <<\EOF >ok
+
+``traceon''
+foo
+``FOO''
+
+BAR
+foo bar
+``FOO'' BAR
+*>*>*<*<
+EOF
+
+cat <<\EOF >okerr
+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
+foo: !``FOO''!
+m4trace: -1- dumpdef(!foo!)
+m4trace: -1- dnl
+m4trace: -1- define(!bar!, !BAR!)
+m4trace: -1- changequote(!>*>*>*>*>!, !<*<*<*<*<!)
+m4trace: -1- dnl
+bar: >*>*>*>*>BAR<*<*<*<*<
+foo: >*>*>*>*>``FOO''<*<*<*<*<
+m4trace: -1- dumpdef(>*>*>*>*>foo<*<*<*<*<, >*>*>*>*>bar<*<*<*<*<)
+m4trace: -1- dnl
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/examples/patsubst.m4 b/examples/patsubst.m4
new file mode 100644
index 00000000..3b390ae0
--- /dev/null
+++ b/examples/patsubst.m4
@@ -0,0 +1,8 @@
+# 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/examples/patsubst.test b/examples/patsubst.test
new file mode 100755
index 00000000..c31c4c5d
--- /dev/null
+++ b/examples/patsubst.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# patsubst.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/patsubst.m4 >in
+
+cat <<\EOF >ok
+# 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
+EOF
+
+cat <<\EOF >okerr
+in:4: m4: WARNING: \0 will disappear, use \& instead in replacements
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/examples/pushpop.m4 b/examples/pushpop.m4
new file mode 100644
index 00000000..d0f2ebb8
--- /dev/null
+++ b/examples/pushpop.m4
@@ -0,0 +1,25 @@
+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/examples/pushpop.test b/examples/pushpop.test
new file mode 100755
index 00000000..038aca15
--- /dev/null
+++ b/examples/pushpop.test
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+# pushpop.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/pushpop.m4 >in
+
+cat <<\EOF >ok
+EOF
+
+cat <<\EOF >okerr
+hej: `def 1.'
+hej: `def 2.'
+hej: `def 3.'
+hej: `def 4.'
+hej: `def 3.'
+hej: `def 2.'
+hej: `def 1.'
+in:18: m4: Undefined name hej
+in:20: m4: Undefined name hej
+in:23: m4: Undefined name mac2
+in:25: m4: Undefined name mac2
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/examples/regexp.m4 b/examples/regexp.m4
new file mode 100644
index 00000000..a4ca573e
--- /dev/null
+++ b/examples/regexp.m4
@@ -0,0 +1,12 @@
+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/examples/regexp.test b/examples/regexp.test
new file mode 100755
index 00000000..4cf21990
--- /dev/null
+++ b/examples/regexp.test
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+# regexp.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/regexp.m4 >in
+
+cat <<\EOF >ok
+>>hej med dig<<
+>>hej<<
+>>hej med dig<<
+>>med<<
+>>med dig<< >>ed dig<<
+
+0
+0
+0
+4
+4
+EOF
+
+cat <<\EOF >okerr
+in:2: m4: WARNING: \0 will disappear, use \& instead in replacements
+m4trace: -1- regexp(`hej med dig', `.*', `>>\0<<') -> `>>hej med dig<<'
+m4trace: -1- regexp(`hej med dig', `\w*', `>>\0<<') -> `>>hej<<'
+m4trace: -1- regexp(`hej med dig', `.+', `>>\0<<') -> `>>hej med dig<<'
+m4trace: -1- regexp(`hej med dig', `m\w+', `>>\0<<') -> `>>med<<'
+m4trace: -1- regexp(`hej med dig', `m\(.*\)', `>>\0<< >>\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'
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/examples/reverse.m4 b/examples/reverse.m4
new file mode 100644
index 00000000..1e620088
--- /dev/null
+++ b/examples/reverse.m4
@@ -0,0 +1,4 @@
+define(`reverse', `ifelse(eval($# > 1), 1, `reverse(shift($@)), `$1'', ``$1'')')
+``'' => reverse
+``hej'' => reverse(hej)
+``hej, med, dig'' => reverse(hej, med, dig)
diff --git a/examples/reverse.test b/examples/reverse.test
new file mode 100755
index 00000000..63b4cefa
--- /dev/null
+++ b/examples/reverse.test
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# reverse.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(reverse.m4)dnl
+EOF
+
+cat <<\EOF >ok
+
+`' =>
+`hej' => hej
+`hej, med, dig' => dig, med, hej
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
diff --git a/examples/stackovf.sh b/examples/stackovf.sh
new file mode 100644
index 00000000..e389a210
--- /dev/null
+++ b/examples/stackovf.sh
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+# 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=m4
+type $M4
+
+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
+$M4 -L999999999 > $tmpfile 2>&1
+)
+result=$?
+
+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*)
+ 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/examples/sync-lines.m4 b/examples/sync-lines.m4
new file mode 100644
index 00000000..405ab618
--- /dev/null
+++ b/examples/sync-lines.m4
@@ -0,0 +1,11 @@
+# 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
diff --git a/examples/sysv-args.m4 b/examples/sysv-args.m4
new file mode 100644
index 00000000..7c82beb0
--- /dev/null
+++ b/examples/sysv-args.m4
@@ -0,0 +1,14 @@
+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/examples/sysv-args.test b/examples/sysv-args.test
new file mode 100755
index 00000000..ceb68c9a
--- /dev/null
+++ b/examples/sysv-args.test
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+# sysv-args.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(sysv-args.m4)dnl
+EOF
+
+cat <<\EOF >ok
+
+
+0
+1
+6
+
+
+hej med dig
+hej med dig en gang igen
+an awful lot of argument at least more that ten silly arguments
+EOF
+
+cat <<\EOF >okerr
+m4trace: -1- nargs
+m4trace: -1- nargs
+m4trace: -1- nargs
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+m4trace: -1- concat
+EOF
+
+M4PATH=$srcdir $M4 in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
diff --git a/examples/trace.m4 b/examples/trace.m4
new file mode 100644
index 00000000..a79dbcdd
--- /dev/null
+++ b/examples/trace.m4
@@ -0,0 +1,30 @@
+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)
diff --git a/examples/trace.test b/examples/trace.test
new file mode 100755
index 00000000..47008f60
--- /dev/null
+++ b/examples/trace.test
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+# trace.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/trace.m4 >in
+
+cat <<\EOF >ok
+
+# 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.
+
+EOF
+
+cat <<\EOF >okerr
+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- 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'.
+
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/examples/translit.m4 b/examples/translit.m4
new file mode 100644
index 00000000..078d1726
--- /dev/null
+++ b/examples/translit.m4
@@ -0,0 +1,8 @@
+# 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/examples/translit.test b/examples/translit.test
new file mode 100755
index 00000000..92acfb62
--- /dev/null
+++ b/examples/translit.test
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# translit.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/translit.m4 >in
+
+cat <<\EOF >ok
+# traceon(`translit')dnl
+GNU U
+GNUS NOT UNIX
+gnus not unix
+s not nix
+z
+-ZY
+tmfs not fnix
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/undivert.incl b/examples/undivert.incl
new file mode 100644
index 00000000..408e0e20
--- /dev/null
+++ b/examples/undivert.incl
@@ -0,0 +1 @@
+This is to be undiverted soon.
diff --git a/examples/undivert.m4 b/examples/undivert.m4
new file mode 100644
index 00000000..61dfb391
--- /dev/null
+++ b/examples/undivert.m4
@@ -0,0 +1,5 @@
+define(`undiverted', `UNDIVERTED')
+# undiverted file.
+undivert(`undivert.incl')
+# included file.
+include(`undivert.incl')
diff --git a/examples/undivert.test b/examples/undivert.test
new file mode 100755
index 00000000..6814a732
--- /dev/null
+++ b/examples/undivert.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# undivert.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/undivert.m4 >in
+
+cat <<\EOF >ok
+
+# undiverted file.
+This is to be undiverted soon.
+
+# included file.
+This is to be UNDIVERTED soon.
+
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/examples/wrap.m4 b/examples/wrap.m4
new file mode 100644
index 00000000..bbe7ae0b
--- /dev/null
+++ b/examples/wrap.m4
@@ -0,0 +1,10 @@
+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/examples/wrap.test b/examples/wrap.test
new file mode 100755
index 00000000..a6bba3c2
--- /dev/null
+++ b/examples/wrap.test
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# wrap.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(wrap.m4)dnl
+EOF
+
+cat <<\EOF >ok
+
+No. 33: The End.
+Wrapper no. 2
+Wrapper no. 1
+Wrapper no. 3
+Wrapper no. 4
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
diff --git a/gettext.m4 b/gettext.m4
new file mode 100644
index 00000000..969d0922
--- /dev/null
+++ b/gettext.m4
@@ -0,0 +1,384 @@
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# Modified for GNU m4 by René Seindal (rene@seindal.dk)
+
+# serial 5
+
+AC_DEFUN(AM_WITH_NLS,
+ [AC_MSG_CHECKING([whether NLS is requested])
+ dnl Default is enabled NLS
+ AC_ARG_ENABLE(nls,
+ [ --disable-nls do not use Native Language Support],
+ USE_NLS=$enableval, USE_NLS=yes)
+ AC_MSG_RESULT($USE_NLS)
+ AC_SUBST(USE_NLS)
+
+ USE_INCLUDED_LIBINTL=no
+
+ dnl If we use NLS figure out what method
+ if test "$USE_NLS" = "yes"; then
+ AC_DEFINE(ENABLE_NLS)
+ AC_MSG_CHECKING([whether included gettext is requested])
+ AC_ARG_WITH(included-gettext,
+ [ --with-included-gettext use the GNU gettext library included here],
+ nls_cv_force_use_gnu_gettext=$withval,
+ nls_cv_force_use_gnu_gettext=no)
+ AC_MSG_RESULT($nls_cv_force_use_gnu_gettext)
+
+ nls_cv_use_gnu_gettext="$nls_cv_force_use_gnu_gettext"
+ if test "$nls_cv_force_use_gnu_gettext" != "yes"; then
+ dnl User does not insist on using GNU NLS library. Figure out what
+ dnl to use. If gettext or catgets are available (in this order) we
+ dnl use this. Else we have to fall back to GNU NLS library.
+ dnl catgets is only used if permitted by option --with-catgets.
+ nls_cv_header_intl=
+ nls_cv_header_libgt=
+ CATOBJEXT=NONE
+
+ AC_CHECK_HEADER(libintl.h,
+ [AC_CACHE_CHECK([for gettext in libc], gt_cv_func_gettext_libc,
+ [AC_TRY_LINK([#include <libintl.h>], [return (int) gettext ("")],
+ gt_cv_func_gettext_libc=yes, gt_cv_func_gettext_libc=no)])
+
+ if test "$gt_cv_func_gettext_libc" != "yes"; then
+ AC_CHECK_LIB(intl, bindtextdomain,
+ [AC_CHECK_LIB(intl, gettext,
+ [LIBS="$LIBS -lintl"
+ gt_cv_func_gettext_libintl=yes],
+ [gt_cv_func_gettext_libintl=no])])
+ fi
+
+ if test "$gt_cv_func_gettext_libc" = "yes" \
+ || test "$gt_cv_func_gettext_libintl" = "yes"; then
+ AC_DEFINE(HAVE_GETTEXT)
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+ if test "$MSGFMT" != "no"; then
+ AC_CHECK_FUNCS(dcgettext)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+ return _nl_msg_cat_cntr],
+ [CATOBJEXT=.gmo
+ DATADIRNAME=share],
+ [CATOBJEXT=.mo
+ DATADIRNAME=lib])
+ INSTOBJEXT=.mo
+ fi
+ fi
+ ])
+
+ if test "$CATOBJEXT" = "NONE"; then
+ AC_MSG_CHECKING([whether catgets can be used])
+ AC_ARG_WITH(catgets,
+ [ --with-catgets use catgets functions if available],
+ nls_cv_use_catgets=$withval, nls_cv_use_catgets=no)
+ AC_MSG_RESULT($nls_cv_use_catgets)
+
+ if test "$nls_cv_use_catgets" = "yes"; then
+ dnl No gettext in C library. Try catgets next.
+ AC_CHECK_LIB(i, main)
+ AC_CHECK_FUNC(catgets,
+ [AC_DEFINE(HAVE_CATGETS)
+ INTLOBJS="\$(CATOBJS)"
+ AC_PATH_PROG(GENCAT, gencat, no)dnl
+ if test "$GENCAT" != "no"; then
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, no)
+ if test "$GMSGFMT" = "no"; then
+ AM_PATH_PROG_WITH_TEST(GMSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)
+ fi
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.cat
+ INSTOBJEXT=.cat
+ DATADIRNAME=lib
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi])
+ fi
+ fi
+
+ if test "$CATOBJEXT" = "NONE"; then
+ dnl Neither gettext nor catgets in included in the C library.
+ dnl Fall back on GNU gettext library.
+ nls_cv_use_gnu_gettext=yes
+ fi
+ fi
+
+ if test "$nls_cv_use_gnu_gettext" = "yes"; then
+ dnl Mark actions used to generate GNU NLS library.
+ INTLOBJS="\$(GETTOBJS)"
+ AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], msgfmt)
+ AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+ AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+ [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+ AC_SUBST(MSGFMT)
+ USE_INCLUDED_LIBINTL=yes
+ CATOBJEXT=.gmo
+ INSTOBJEXT=.mo
+ DATADIRNAME=share
+ INTLDEPS='$(top_builddir)/intl/libintl.a'
+ INTLLIBS=$INTLDEPS
+ LIBS=`echo $LIBS | sed -e 's/-lintl//'`
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+
+ dnl Test whether we really found GNU xgettext.
+ if test "$XGETTEXT" != ":"; then
+ dnl If it is no GNU xgettext we define it as : so that the
+ dnl Makefiles still can work.
+ if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+ : ;
+ else
+ AC_MSG_RESULT(
+ [found xgettext program is not GNU xgettext; ignore it])
+ XGETTEXT=":"
+ fi
+ fi
+
+ # We need to process the po/ directory.
+ POSUB=po
+ else
+ DATADIRNAME=share
+ nls_cv_header_intl=intl/libintl.h
+ nls_cv_header_libgt=intl/libgettext.h
+ fi
+ AC_LINK_FILES($nls_cv_header_libgt, $nls_cv_header_intl)
+ AC_OUTPUT_COMMANDS(
+ [case "$CONFIG_FILES" in *po/Makefile.in*)
+ sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+ esac])
+
+
+ # If this is used in GNU gettext we have to set USE_NLS to `yes'
+ # because some of the sources are only built for this goal.
+ if test "$PACKAGE" = gettext; then
+ USE_NLS=yes
+ USE_INCLUDED_LIBINTL=yes
+ fi
+
+ dnl These rules are solely for the distribution goal. While doing this
+ dnl we only have to keep exactly one list of the available catalogs
+ dnl in configure.in.
+ for lang in $ALL_LINGUAS; do
+ GMOFILES="$GMOFILES $lang.gmo"
+ POFILES="$POFILES $lang.po"
+ done
+
+ dnl Make all variables we use known to autoconf.
+ AC_SUBST(USE_INCLUDED_LIBINTL)
+ AC_SUBST(CATALOGS)
+ AC_SUBST(CATOBJEXT)
+ AC_SUBST(DATADIRNAME)
+ AC_SUBST(GMOFILES)
+ AC_SUBST(INSTOBJEXT)
+ AC_SUBST(INTLDEPS)
+ AC_SUBST(INTLLIBS)
+ AC_SUBST(INTLOBJS)
+ AC_SUBST(POFILES)
+ AC_SUBST(POSUB)
+ ])
+
+AC_DEFUN(AM_GNU_GETTEXT,
+ [AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+ AC_REQUIRE([AC_PROG_CC])dnl
+ AC_REQUIRE([AC_PROG_RANLIB])dnl
+ AC_REQUIRE([AC_ISC_POSIX])dnl
+ AC_REQUIRE([AC_HEADER_STDC])dnl
+ AC_REQUIRE([AC_C_CONST])dnl
+ AC_REQUIRE([AC_C_INLINE])dnl
+ AC_REQUIRE([AC_TYPE_OFF_T])dnl
+ AC_REQUIRE([AC_TYPE_SIZE_T])dnl
+ AC_REQUIRE([AC_FUNC_ALLOCA])dnl
+ AC_REQUIRE([AC_FUNC_MMAP])dnl
+
+ AC_CHECK_HEADERS([argz.h limits.h locale.h nl_types.h malloc.h string.h \
+unistd.h sys/param.h])
+ AC_CHECK_FUNCS([getcwd munmap putenv setenv setlocale strchr strcasecmp \
+strdup __argz_count __argz_stringify __argz_next])
+
+ if test "${ac_cv_func_stpcpy+set}" != "set"; then
+ AC_CHECK_FUNCS(stpcpy)
+ fi
+ if test "${ac_cv_func_stpcpy}" = "yes"; then
+ AC_DEFINE(HAVE_STPCPY)
+ fi
+
+ AM_LC_MESSAGES
+ AM_WITH_NLS
+
+ if test "x$CATOBJEXT" != "x"; then
+ if test "x$ALL_LINGUAS" = "x"; then
+ LINGUAS=
+ else
+ AC_MSG_CHECKING(for catalogs to be installed)
+ NEW_LINGUAS=
+ for lang in ${LINGUAS=$ALL_LINGUAS}; do
+ case "$ALL_LINGUAS" in
+ *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;;
+ esac
+ done
+ LINGUAS=$NEW_LINGUAS
+ AC_MSG_RESULT($LINGUAS)
+ fi
+
+ dnl Construct list of names of catalog files to be constructed.
+ if test -n "$LINGUAS"; then
+ for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+ fi
+ fi
+
+ dnl The reference to <locale.h> in the installed <libintl.h> file
+ dnl must be resolved because we cannot expect the users of this
+ dnl to define HAVE_LOCALE_H.
+ if test $ac_cv_header_locale_h = yes; then
+ INCLUDE_LOCALE_H="#include <locale.h>"
+ else
+ INCLUDE_LOCALE_H="\
+/* The system does not provide the header <locale.h>. Take care yourself. */"
+ fi
+ AC_SUBST(INCLUDE_LOCALE_H)
+
+ dnl Determine which catalog format we have (if any is needed)
+ dnl For now we know about two different formats:
+ dnl Linux libc-5 and the normal X/Open format
+ test -d intl || mkdir intl
+ if test "$CATOBJEXT" = ".cat"; then
+ AC_CHECK_HEADER(linux/version.h, msgformat=linux, msgformat=xopen)
+
+ dnl Transform the SED scripts while copying because some dumb SEDs
+ dnl cannot handle comments.
+ sed -e '/^#/d' $srcdir/intl/$msgformat-msg.sed > intl/po2msg.sed
+ fi
+ dnl po2tbl.sed is always needed.
+ sed -e '/^#.*[^\\]$/d' -e '/^#$/d' \
+ $srcdir/intl/po2tbl.sed.in > intl/po2tbl.sed
+
+ dnl In the intl/Makefile.in we have a special dependency which makes
+ dnl only sense for gettext. We comment this out for non-gettext
+ dnl packages.
+ if test "$PACKAGE" = "gettext"; then
+ GT_NO="#NO#"
+ GT_YES=
+ else
+ GT_NO=
+ GT_YES="#YES#"
+ fi
+ AC_SUBST(GT_NO)
+ AC_SUBST(GT_YES)
+
+ dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
+ dnl find the mkinstalldirs script in another subdir but ($top_srcdir).
+ dnl Try to locate is.
+ MKINSTALLDIRS=
+ if test -n "$ac_aux_dir"; then
+ MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+ fi
+ if test -z "$MKINSTALLDIRS"; then
+ MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+ fi
+ AC_SUBST(MKINSTALLDIRS)
+
+ dnl *** For now the libtool support in intl/Makefile is not for real.
+ l=
+ AC_SUBST(l)
+
+ dnl Generate list of files to be processed by xgettext which will
+ dnl be included in po/Makefile.
+ test -d po || mkdir po
+ if test "x$srcdir" != "x."; then
+ if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+ posrcprefix="$srcdir/"
+ else
+ posrcprefix="../$srcdir/"
+ fi
+ else
+ posrcprefix="../"
+ fi
+ rm -f po/POTFILES
+ sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+ < $srcdir/po/POTFILES.in > po/POTFILES
+ ])
+
+# Search path for a program which passes the given test.
+# Ulrich Drepper <drepper@cygnus.com>, 1996.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+AC_DEFUN(AM_PATH_PROG_WITH_TEST,
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+ /*)
+ ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+ ;;
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in ifelse([$5], , $PATH, [$5]); do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if [$3]; then
+ ac_cv_path_$1="$ac_dir/$ac_word"
+ break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+ ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test -n "[$]$1"; then
+ AC_MSG_RESULT([$]$1)
+else
+ AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# Check whether LC_MESSAGES is available in <locale.h>.
+# Ulrich Drepper <drepper@cygnus.com>, 1995.
+#
+# This file can be copied and used freely without restrictions. It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+
+# serial 1
+
+AC_DEFUN(AM_LC_MESSAGES,
+ [if test $ac_cv_header_locale_h = yes; then
+ AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+ [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+ am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+ if test $am_cv_val_LC_MESSAGES = yes; then
+ AC_DEFINE(HAVE_LC_MESSAGES)
+ fi
+ fi])
+
diff --git a/install-sh b/install-sh
new file mode 100755
index 00000000..ab74c882
--- /dev/null
+++ b/install-sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/lib/COPYING.LIB b/lib/COPYING.LIB
new file mode 100644
index 00000000..bbe3fe19
--- /dev/null
+++ b/lib/COPYING.LIB
@@ -0,0 +1,481 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, 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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library 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 Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey 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 library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/lib/Makefile.am b/lib/Makefile.am
new file mode 100644
index 00000000..c7c06190
--- /dev/null
+++ b/lib/Makefile.am
@@ -0,0 +1,12 @@
+## Process this file with automake to produce Makefile.in
+noinst_LIBRARIES = libm4.a
+
+libm4_a_SOURCES = getopt.h obstack.h regex.h regex.c getopt.c \
+ getopt1.c error.c obstack.c xmalloc.c \
+ xstrdup.c alloca.c strtol.c
+
+noinst_HEADERS = getopt.h error.h getdate.h
+
+libm4_a_LIBADD =
+libm4_a_DEPENDENCIES = # $(libfu_a_LIBADD)
+
diff --git a/lib/Makefile.in b/lib/Makefile.in
new file mode 100644
index 00000000..82ea2ed7
--- /dev/null
+++ b/lib/Makefile.in
@@ -0,0 +1,92 @@
+# Makefile for GNU m4 library.
+# Copyright (C) 1992, 1993, 1994 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 2, 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, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+PRODUCT = @PRODUCT@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+AR = ar
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+DEFS = @DEFS@
+RANLIB = @RANLIB@
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+.c.o:
+ $(COMPILE) $<
+
+INCLUDES = -I.. -I$(srcdir)
+
+HEADERS = getopt.h obstack.h regex.h
+SOURCES = regex.c getopt.c getopt1.c error.c obstack.c xmalloc.c \
+xstrdup.c alloca.c strtol.c
+OBJECTS = regex.o getopt.o getopt1.o error.o obstack.o xmalloc.o \
+xstrdup.o @ALLOCA@ @LIBOBJS@
+
+DISTFILES = COPYING.LIB Makefile.in $(HEADERS) $(SOURCES) \
+TAGS
+
+all: libm4.a
+
+libm4.a: $(OBJECTS)
+ rm -f libm4.a
+ $(AR) cru libm4.a $(OBJECTS)
+ $(RANLIB) libm4.a
+
+$(OBJECTS): ../config.h
+
+install: all
+
+uninstall:
+
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES)
+ cd $(srcdir) && etags $(HEADERS) $(SOURCES)
+
+mostlyclean:
+ rm -f *.o
+
+clean: mostlyclean
+ rm -f libm4.a
+
+distclean: clean
+ rm -f Makefile
+
+realclean: distclean
+ rm -f TAGS
+
+dist: $(DISTFILES)
+ @echo "Copying distribution files"
+ @for file in $(DISTFILES); do \
+ ln $(srcdir)/$$file ../$(PRODUCT)-$(VERSION)/lib 2> /dev/null \
+ || cp -p $(srcdir)/$$file ../$(PRODUCT)-$(VERSION)/lib; \
+ done
+
+Makefile: Makefile.in ../config.status
+ cd .. && CONFIG_FILES=lib/$@ CONFIG_HEADERS= ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/lib/alloca.c b/lib/alloca.c
new file mode 100644
index 00000000..7020f32c
--- /dev/null
+++ b/lib/alloca.c
@@ -0,0 +1,492 @@
+/* alloca.c -- allocate automatically reclaimed memory
+ (Mostly) portable public-domain implementation -- D A Gwyn
+
+ This implementation of the PWB library alloca function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+ J.Otto Tennant <jot@cray.com> contributed the Cray support.
+
+ There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef emacs
+#include "blockinput.h"
+#endif
+
+/* If compiling with GCC 2, this file's not needed. */
+#if !defined (__GNUC__) || __GNUC__ < 2
+
+/* If someone has defined alloca as a macro,
+ there must be some other way alloca is supposed to work. */
+#ifndef alloca
+
+#ifdef emacs
+#ifdef static
+/* actually, only want this if static is defined as ""
+ -- this is for usg, in which emacs must undefine static
+ in order to make unexec workable
+ */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+/* If your stack is a linked list of frames, you have to
+ provide an "address metric" ADDRESS_FUNCTION macro. */
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
+#else
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+#define NULL 0
+
+/* Different portions of Emacs need to call different versions of
+ malloc. The Emacs executable needs alloca to call xmalloc, because
+ ordinary malloc isn't protected from input signals. On the other
+ hand, the utilities in lib-src need alloca to call malloc; some of
+ them are very simple, and don't have an xmalloc routine.
+
+ Non-Emacs programs expect this to call use xmalloc.
+
+ Callers below should use malloc. */
+
+#ifndef emacs
+#define malloc xmalloc
+#endif
+extern pointer malloc ();
+
+/* Define STACK_DIRECTION if you know the direction of stack
+ growth for your system; otherwise it will be automatically
+ deduced at run-time.
+
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+
+#ifndef STACK_DIRECTION
+#define STACK_DIRECTION 0 /* Direction unknown. */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
+
+#else /* STACK_DIRECTION == 0; need run-time code. */
+
+static int stack_dir; /* 1 or -1 once known. */
+#define STACK_DIR stack_dir
+
+static void
+find_stack_direction ()
+{
+ static char *addr = NULL; /* Address of first `dummy', once known. */
+ auto char dummy; /* To get stack address. */
+
+ if (addr == NULL)
+ { /* Initial entry. */
+ addr = ADDRESS_FUNCTION (dummy);
+
+ find_stack_direction (); /* Recurse once. */
+ }
+ else
+ {
+ /* Second entry. */
+ if (ADDRESS_FUNCTION (dummy) > addr)
+ stack_dir = 1; /* Stack grew upward. */
+ else
+ stack_dir = -1; /* Stack grew downward. */
+ }
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/* An "alloca header" is used to:
+ (a) chain together all alloca'ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc
+ alignment chunk size. The following default should work okay. */
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* To force sizeof(header). */
+ struct
+ {
+ union hdr *next; /* For chaining headers. */
+ char *deep; /* For stack depth measure. */
+ } h;
+} header;
+
+static header *last_alloca_header = NULL; /* -> last alloca header. */
+
+/* Return a pointer to at least SIZE bytes of storage,
+ which will be automatically reclaimed upon exit from
+ the procedure that called alloca. Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32. */
+
+pointer
+alloca (size)
+ unsigned size;
+{
+ auto char probe; /* Probes stack depth: */
+ register char *depth = ADDRESS_FUNCTION (probe);
+
+#if STACK_DIRECTION == 0
+ if (STACK_DIR == 0) /* Unknown growth direction. */
+ find_stack_direction ();
+#endif
+
+ /* Reclaim garbage, defined as all alloca'd storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* Traverses linked list. */
+
+#ifdef emacs
+ BLOCK_INPUT;
+#endif
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if ((STACK_DIR > 0 && hp->h.deep > depth)
+ || (STACK_DIR < 0 && hp->h.deep < depth))
+ {
+ register header *np = hp->h.next;
+
+ free ((pointer) hp); /* Collect garbage. */
+
+ hp = np; /* -> next header. */
+ }
+ else
+ break; /* Rest are not deeper. */
+
+ last_alloca_header = hp; /* -> last valid storage. */
+
+#ifdef emacs
+ UNBLOCK_INPUT;
+#endif
+ }
+
+ if (size == 0)
+ return NULL; /* No allocation required. */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = malloc (sizeof (header) + size);
+ /* Address of header. */
+
+ ((header *) new)->h.next = last_alloca_header;
+ ((header *) new)->h.deep = depth;
+
+ last_alloca_header = (header *) new;
+
+ /* User storage begins just after header. */
+
+ return (pointer) ((char *) new + sizeof (header));
+ }
+}
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
+struct stack_control_header
+ {
+ long shgrow:32; /* Number of times stack has grown. */
+ long shaseg:32; /* Size of increments to stack. */
+ long shhwm:32; /* High water mark of stack. */
+ long shsize:32; /* Current size of stack (all segments). */
+ };
+
+/* The stack segment linkage control information occurs at
+ the high-address end of a stack segment. (The stack
+ grows from low addresses to high addresses.) The initial
+ part of the stack segment linkage control information is
+ 0200 (octal) words. This provides for register storage
+ for the routine which overflows the stack. */
+
+struct stack_segment_linkage
+ {
+ long ss[0200]; /* 0200 overflow words. */
+ long sssize:32; /* Number of words in this segment. */
+ long ssbase:32; /* Offset to stack base. */
+ long:32;
+ long sspseg:32; /* Offset to linkage control of previous
+ segment of stack. */
+ long:32;
+ long sstcpt:32; /* Pointer to task common address block. */
+ long sscsnm; /* Private control structure number for
+ microtasking. */
+ long ssusr1; /* Reserved for user. */
+ long ssusr2; /* Reserved for user. */
+ long sstpid; /* Process ID for pid based multi-tasking. */
+ long ssgvup; /* Pointer to multitasking thread giveup. */
+ long sscray[7]; /* Reserved for Cray Research. */
+ long ssa0;
+ long ssa1;
+ long ssa2;
+ long ssa3;
+ long ssa4;
+ long ssa5;
+ long ssa6;
+ long ssa7;
+ long sss0;
+ long sss1;
+ long sss2;
+ long sss3;
+ long sss4;
+ long sss5;
+ long sss6;
+ long sss7;
+ };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+ returned by the STKSTAT library routine. */
+struct stk_stat
+ {
+ long now; /* Current total stack size. */
+ long maxc; /* Amount of contiguous space which would
+ be required to satisfy the maximum
+ stack demand to date. */
+ long high_water; /* Stack high-water mark. */
+ long overflows; /* Number of stack overflow ($STKOFEN) calls. */
+ long hits; /* Number of internal buffer hits. */
+ long extends; /* Number of block extensions. */
+ long stko_mallocs; /* Block allocations by $STKOFEN. */
+ long underflows; /* Number of stack underflow calls ($STKRETN). */
+ long stko_free; /* Number of deallocations by $STKRETN. */
+ long stkm_free; /* Number of deallocations by $STKMRET. */
+ long segments; /* Current number of stack segments. */
+ long maxs; /* Maximum number of stack segments so far. */
+ long pad_size; /* Stack pad size. */
+ long current_address; /* Current stack segment address. */
+ long current_size; /* Current stack segment size. This
+ number is actually corrupted by STKSTAT to
+ include the fifteen word trailer area. */
+ long initial_address; /* Address of initial segment. */
+ long initial_size; /* Size of initial segment. */
+ };
+
+/* The following structure describes the data structure which trails
+ any stack segment. I think that the description in 'asdef' is
+ out of date. I only describe the parts that I am sure about. */
+
+struct stk_trailer
+ {
+ long this_address; /* Address of this block. */
+ long this_size; /* Size of this block (does not include
+ this trailer). */
+ long unknown2;
+ long unknown3;
+ long link; /* Address of trailer block of previous
+ segment. */
+ long unknown5;
+ long unknown6;
+ long unknown7;
+ long unknown8;
+ long unknown9;
+ long unknown10;
+ long unknown11;
+ long unknown12;
+ long unknown13;
+ long unknown14;
+ };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+ I doubt that "lint" will like this much. */
+
+static long
+i00afunc (long *address)
+{
+ struct stk_stat status;
+ struct stk_trailer *trailer;
+ long *block, size;
+ long result = 0;
+
+ /* We want to iterate through all of the segments. The first
+ step is to get the stack status structure. We could do this
+ more quickly and more directly, perhaps, by referencing the
+ $LM00 common block, but I know that this works. */
+
+ STKSTAT (&status);
+
+ /* Set up the iteration. */
+
+ trailer = (struct stk_trailer *) (status.current_address
+ + status.current_size
+ - 15);
+
+ /* There must be at least one stack segment. Therefore it is
+ a fatal error if "trailer" is null. */
+
+ if (trailer == 0)
+ abort ();
+
+ /* Discard segments that do not contain our argument address. */
+
+ while (trailer != 0)
+ {
+ block = (long *) trailer->this_address;
+ size = trailer->this_size;
+ if (block == 0 || size == 0)
+ abort ();
+ trailer = (struct stk_trailer *) trailer->link;
+ if ((block <= address) && (address < (block + size)))
+ break;
+ }
+
+ /* Set the result to the offset in this segment and add the sizes
+ of all predecessor segments. */
+
+ result = address - block;
+
+ if (trailer == 0)
+ {
+ return result;
+ }
+
+ do
+ {
+ if (trailer->this_size <= 0)
+ abort ();
+ result += trailer->this_size;
+ trailer = (struct stk_trailer *) trailer->link;
+ }
+ while (trailer != 0);
+
+ /* We are done. Note that if you present a bogus address (one
+ not in any segment), you will get a different number back, formed
+ from subtracting the address of the first block. This is probably
+ not what you want. */
+
+ return (result);
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+ Determine the number of the cell within the stack,
+ given the address of the cell. The purpose of this
+ routine is to linearize, in some sense, stack addresses
+ for alloca. */
+
+static long
+i00afunc (long address)
+{
+ long stkl = 0;
+
+ long size, pseg, this_segment, stack;
+ long result = 0;
+
+ struct stack_segment_linkage *ssptr;
+
+ /* Register B67 contains the address of the end of the
+ current stack segment. If you (as a subprogram) store
+ your registers on the stack and find that you are past
+ the contents of B67, you have overflowed the segment.
+
+ B67 also points to the stack segment linkage control
+ area, which is what we are really interested in. */
+
+ stkl = CRAY_STACKSEG_END ();
+ ssptr = (struct stack_segment_linkage *) stkl;
+
+ /* If one subtracts 'size' from the end of the segment,
+ one has the address of the first word of the segment.
+
+ If this is not the first segment, 'pseg' will be
+ nonzero. */
+
+ pseg = ssptr->sspseg;
+ size = ssptr->sssize;
+
+ this_segment = stkl - size;
+
+ /* It is possible that calling this routine itself caused
+ a stack overflow. Discard stack segments which do not
+ contain the target address. */
+
+ while (!(this_segment <= address && address <= stkl))
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+ if (pseg == 0)
+ break;
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ this_segment = stkl - size;
+ }
+
+ result = address - this_segment;
+
+ /* If you subtract pseg from the current end of the stack,
+ you get the address of the previous stack segment's end.
+ This seems a little convoluted to me, but I'll bet you save
+ a cycle somewhere. */
+
+ while (pseg != 0)
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ result += size;
+ }
+ return (result);
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
+#endif /* no alloca */
+#endif /* not GCC version 2 */
diff --git a/lib/error.c b/lib/error.c
new file mode 100644
index 00000000..19c2ba88
--- /dev/null
+++ b/lib/error.c
@@ -0,0 +1,119 @@
+/* error.c -- error handler for noninteractive utilities
+ Copyright (C) 1990, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#if HAVE_VPRINTF || HAVE_DOPRNT
+# if __STDC__
+# include <stdarg.h>
+# define VA_START(args, lastarg) va_start(args, lastarg)
+# else
+# include <varargs.h>
+# define VA_START(args, lastarg) va_start(args)
+# endif
+#else
+# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
+# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
+#endif
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else
+void exit ();
+#endif
+
+/* If NULL, error will flush stdout, then print on stderr the program
+ name, a colon and a space. Otherwise, error will call this
+ function without parameters instead. */
+void (*error_print_progname) () = NULL;
+
+/* The calling program should define program_name and set it to the
+ name of the executing program. */
+extern char *program_name;
+
+#if HAVE_STRERROR
+char *strerror ();
+#else
+static char *
+private_strerror (errnum)
+ int errnum;
+{
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+
+ if (errnum > 0 && errnum <= sys_nerr)
+ return sys_errlist[errnum];
+ return "Unknown system error";
+}
+#define strerror private_strerror
+#endif
+
+/* Print the program name and error message MESSAGE, which is a printf-style
+ format string with optional args.
+ If ERRNUM is nonzero, print its corresponding system error message.
+ Exit with status STATUS if it is nonzero. */
+/* VARARGS */
+
+void
+#if defined(VA_START) && __STDC__
+error (int status, int errnum, const char *message, ...)
+#else
+error (status, errnum, message, va_alist)
+ int status;
+ int errnum;
+ char *message;
+ va_dcl
+#endif
+{
+#ifdef VA_START
+ va_list args;
+#endif
+
+ if (error_print_progname)
+ (*error_print_progname) ();
+ else
+ {
+ fflush (stdout);
+ fprintf (stderr, "%s: ", program_name);
+ }
+
+#ifdef VA_START
+ VA_START (args, message);
+# if HAVE_VPRINTF
+ vfprintf (stderr, message, args);
+# else
+ _doprnt (message, args, stderr);
+# endif
+ va_end (args);
+#else
+ fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
+#endif
+
+ if (errnum)
+ fprintf (stderr, ": %s", strerror (errnum));
+ putc ('\n', stderr);
+ fflush (stderr);
+ if (status)
+ exit (status);
+}
diff --git a/lib/error.h b/lib/error.h
new file mode 100644
index 00000000..7a803d0c
--- /dev/null
+++ b/lib/error.h
@@ -0,0 +1,65 @@
+/* error.h -- declaration for error-reporting function
+ Copyright (C) 1995, 1996 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 2, 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, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef ERROR_H_
+# define ERROR_H_
+
+# ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
+# define __attribute__(Spec) /* empty */
+# endif
+/* The __-protected variants of `format' and `printf' attributes
+ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+# define __format__ format
+# define __printf__ printf
+# endif
+# endif
+
+# if defined (__STDC__) && __STDC__
+
+/* Print a message with `fprintf (stderr, FORMAT, ...)';
+ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
+ If STATUS is nonzero, terminate the program with `exit (STATUS)'. */
+
+extern void error (int status, int errnum, const char *format, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
+
+extern void error_at_line (int status, int errnum, const char *fname,
+ unsigned int lineno, const char *format, ...)
+ __attribute__ ((__format__ (__printf__, 5, 6)));
+
+/* If NULL, error will flush stdout, then print on stderr the program
+ name, a colon and a space. Otherwise, error will call this
+ function without parameters instead. */
+extern void (*error_print_progname) (void);
+
+# else
+void error ();
+void error_at_line ();
+extern void (*error_print_progname) ();
+# endif
+
+/* This variable is incremented each time `error' is called. */
+extern unsigned int error_message_count;
+
+/* Sometimes we want to have at most one error per line. This
+ variable controls whether this mode is selected or not. */
+extern int error_one_per_line;
+
+#endif /* not ERROR_H_ */
diff --git a/lib/getdate.h b/lib/getdate.h
new file mode 100644
index 00000000..db2dba4b
--- /dev/null
+++ b/lib/getdate.h
@@ -0,0 +1,46 @@
+/* Copyright (C) 1995 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 2, 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, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+# ifndef PARAMS
+# if defined (__GNUC__) || __STDC__
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif
+# endif
+
+#if defined (vms)
+# include <types.h>
+# include <time.h>
+#else
+# include <sys/types.h>
+# ifdef TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
+# else
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# else
+# include <time.h>
+# endif
+# endif
+#endif /* defined (vms) */
+
+time_t get_date PARAMS ((const char *p, const time_t *now));
diff --git a/lib/getopt.c b/lib/getopt.c
new file mode 100644
index 00000000..43c0a6a9
--- /dev/null
+++ b/lib/getopt.c
@@ -0,0 +1,748 @@
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
+ before changing it!
+
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
+ 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 2, 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, write to the Free Software
+ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+#include <stdlib.h>
+#endif /* GNU C library. */
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg = NULL;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns EOF, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* XXX 1003.2 says this must be 1 before any call. */
+int optind = 0;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return EOF with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+#include <string.h>
+#define my_index strchr
+#else
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+char *getenv ();
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+#if !defined (__STDC__) || !__STDC__
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+#endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+static const char *
+_getopt_initialize (optstring)
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind = 1;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns `EOF'.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ optarg = NULL;
+
+ if (optind == 0)
+ optstring = _getopt_initialize (optstring);
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc
+ && (argv[optind][0] != '-' || argv[optind][1] == '\0'))
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return EOF;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
+ {
+ if (ordering == REQUIRE_ORDER)
+ return EOF;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if (nameend - nextchar == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, "%s: option `%s' is ambiguous\n",
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ {
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ "%s: option `--%s' doesn't allow an argument\n",
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ "%s: option `%c%s' doesn't allow an argument\n",
+ argv[0], argv[optind - 1][0], pfound->name);
+ }
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr, "%s: option `%s' requires an argument\n",
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (opterr)
+ {
+ if (argv[optind][1] == '-')
+ /* --option */
+ fprintf (stderr, "%s: unrecognized option `--%s'\n",
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, "%s: unrecognized option `%c%s'\n",
+ argv[0], argv[optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ optind++;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (opterr)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+ else
+ fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
+ }
+ optopt = c;
+ return '?';
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, "%s: option requires an argument -- %c\n",
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__. */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == EOF)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/lib/getopt.h b/lib/getopt.h
new file mode 100644
index 00000000..4ac33b71
--- /dev/null
+++ b/lib/getopt.h
@@ -0,0 +1,129 @@
+/* Declarations for getopt.
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _GETOPT_H
+#define _GETOPT_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns EOF, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+#if defined (__STDC__) && __STDC__
+ const char *name;
+#else
+ char *name;
+#endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+#define no_argument 0
+#define required_argument 1
+#define optional_argument 2
+
+#if defined (__STDC__) && __STDC__
+#ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int argc, char *const *argv, const char *shortopts);
+#else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+#endif /* __GNU_LIBRARY__ */
+extern int getopt_long (int argc, char *const *argv, const char *shortopts,
+ const struct option *longopts, int *longind);
+extern int getopt_long_only (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int argc, char *const *argv,
+ const char *shortopts,
+ const struct option *longopts, int *longind,
+ int long_only);
+#else /* not __STDC__ */
+extern int getopt ();
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _GETOPT_H */
diff --git a/lib/getopt1.c b/lib/getopt1.c
new file mode 100644
index 00000000..4580211c
--- /dev/null
+++ b/lib/getopt1.c
@@ -0,0 +1,180 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 1993, 1994
+ 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 2, 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, write to the Free Software
+ Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined (__STDC__) || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#else
+char *getenv ();
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* _LIBC or not __GNU_LIBRARY__. */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == EOF)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/lib/m4error.c b/lib/m4error.c
new file mode 100644
index 00000000..5a0d7bdd
--- /dev/null
+++ b/lib/m4error.c
@@ -0,0 +1,259 @@
+/* Error handler for noninteractive utilities
+ Copyright (C) 1990,91,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library. Its master source is NOT part of
+ the C library, however. The master source lives in /gd/gnu/lib.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC
+# if __STDC__
+# include <stdarg.h>
+# define VA_START(args, lastarg) va_start(args, lastarg)
+# else
+# include <varargs.h>
+# define VA_START(args, lastarg) va_start(args)
+# endif
+#else
+# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
+# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
+#endif
+
+#if STDC_HEADERS || _LIBC
+# include <stdlib.h>
+# include <string.h>
+#else
+void exit ();
+#endif
+
+#ifndef _
+# define _(String) String
+#endif
+
+/* Get prototypes for the functions defined here. */
+#include <m4error.h>
+
+#ifdef DLL_EXPORT
+# define M4_GLOBAL_DATA __declspec(dllexport)
+#else
+# define M4_GLOBAL_DATA
+#endif
+
+/* If NULL, error will flush stdout, then print on stderr the program
+ name, a colon and a space. Otherwise, error will call this
+ function without parameters instead. */
+M4_GLOBAL_DATA void (*error_print_progname) (
+#if __STDC__ - 0
+ void
+#endif
+ );
+
+/* This variable is incremented each time `error' is called. */
+M4_GLOBAL_DATA unsigned int error_message_count;
+
+#ifdef _LIBC
+/* In the GNU C library, there is a predefined variable for this. */
+
+# define program_name program_invocation_name
+# include <errno.h>
+
+/* In GNU libc we want do not want to use the common name `error' directly.
+ Instead make it a weak alias. */
+# define error __error
+# define error_at_line __error_at_line
+
+# ifdef USE_IN_LIBIO
+# include <libio/iolibio.h>
+# define fflush(s) _IO_fflush (s)
+# endif
+
+#else /* not _LIBC */
+
+/* The calling program should define program_name and set it to the
+ name of the executing program. */
+M4_GLOBAL_DATA char *program_name;
+
+# ifdef HAVE_STRERROR_R
+# define __strerror_r strerror_r
+# else
+# if HAVE_STRERROR
+# ifndef strerror /* On some systems, strerror is a macro */
+char *strerror ();
+# endif
+# else
+static char *
+private_strerror (errnum)
+ int errnum;
+{
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+
+ if (errnum > 0 && errnum <= sys_nerr)
+ return _(sys_errlist[errnum]);
+ return _("Unknown system error");
+}
+# define strerror private_strerror
+# endif /* HAVE_STRERROR */
+# endif /* HAVE_STRERROR_R */
+#endif /* not _LIBC */
+
+/* Print the program name and error message MESSAGE, which is a printf-style
+ format string with optional args.
+ If ERRNUM is nonzero, print its corresponding system error message.
+ Exit with status STATUS if it is nonzero. */
+/* VARARGS */
+
+void
+#if defined VA_START && __STDC__
+error (int status, int errnum, const char *message, ...)
+#else
+error (status, errnum, message, va_alist)
+ int status;
+ int errnum;
+ char *message;
+ va_dcl
+#endif
+{
+#ifdef VA_START
+ va_list args;
+#endif
+
+ if (error_print_progname)
+ (*error_print_progname) ();
+ else
+ {
+ fflush (stdout);
+ fprintf (stderr, "%s: ", program_name);
+ }
+
+#ifdef VA_START
+ VA_START (args, message);
+# if HAVE_VPRINTF || _LIBC
+ vfprintf (stderr, message, args);
+# else
+ _doprnt (message, args, stderr);
+# endif
+ va_end (args);
+#else
+ fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
+#endif
+
+ ++error_message_count;
+ if (errnum)
+ {
+#if defined HAVE_STRERROR_R || defined _LIBC
+ char errbuf[1024];
+ fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf));
+#else
+ fprintf (stderr, ": %s", strerror (errnum));
+#endif
+ }
+ putc ('\n', stderr);
+ fflush (stderr);
+ if (status)
+ exit (status);
+}
+
+/* Sometimes we want to have at most one error per line. This
+ variable controls whether this mode is selected or not. */
+int error_one_per_line;
+
+void
+#if defined VA_START && __STDC__
+error_at_line (int status, int errnum, const char *file_name,
+ unsigned int line_number, const char *message, ...)
+#else
+error_at_line (status, errnum, file_name, line_number, message, va_alist)
+ int status;
+ int errnum;
+ const char *file_name;
+ unsigned int line_number;
+ char *message;
+ va_dcl
+#endif
+{
+#ifdef VA_START
+ va_list args;
+#endif
+
+ if (error_one_per_line)
+ {
+ static const char *old_file_name;
+ static unsigned int old_line_number;
+
+ if (old_line_number == line_number &&
+ (file_name == old_file_name || !strcmp (old_file_name, file_name)))
+ /* Simply return and print nothing. */
+ return;
+
+ old_file_name = file_name;
+ old_line_number = line_number;
+ }
+
+ if (error_print_progname)
+ (*error_print_progname) ();
+ else
+ {
+ fflush (stdout);
+ fprintf (stderr, "%s:", program_name);
+ }
+
+ if (file_name != NULL)
+ fprintf (stderr, "%s:%d: ", file_name, line_number);
+
+#ifdef VA_START
+ VA_START (args, message);
+# if HAVE_VPRINTF || _LIBC
+ vfprintf (stderr, message, args);
+# else
+ _doprnt (message, args, stderr);
+# endif
+ va_end (args);
+#else
+ fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
+#endif
+
+ ++error_message_count;
+ if (errnum)
+ {
+#if defined HAVE_STRERROR_R || defined _LIBC
+ char errbuf[1024];
+ fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf));
+#else
+ fprintf (stderr, ": %s", strerror (errnum));
+#endif
+ }
+ putc ('\n', stderr);
+ fflush (stderr);
+ if (status)
+ exit (status);
+}
+
+#ifdef _LIBC
+/* Make the weak alias. */
+# undef error
+# undef error_at_line
+weak_alias (__error, error)
+weak_alias (__error_at_line, error_at_line)
+#endif
diff --git a/lib/m4error.h b/lib/m4error.h
new file mode 100644
index 00000000..066ffec4
--- /dev/null
+++ b/lib/m4error.h
@@ -0,0 +1,98 @@
+/* Declaration for error-reporting function
+ Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library. Its master source is NOT part of
+ the C library, however. The master source lives in /gd/gnu/lib.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef M4ERROR_H
+#define M4ERROR_H 1
+
+/* DLL building support on win32 hosts; mostly to workaround their
+ ridiculous implementation of data symbol exporting. */
+#ifndef M4_SCOPE
+# ifdef _WIN32
+ /* Incase we are linking a dll with this library, the
+ LIBM4_DLL_IMPORT takes precedence over a generic DLL_EXPORT
+ when defining the SCOPE variable for M4. */
+# ifdef LIBM4_DLL_IMPORT /* define if linking with this dll */
+# define M4_SCOPE extern __declspec(dllimport)
+# else
+# ifdef DLL_EXPORT /* defined by libtool (if required) */
+# define M4_SCOPE __declspec(dllexport)
+# endif /* DLL_EXPORT */
+# endif /* LIBM4_DLL_IMPORT */
+# endif /* M4_SCOPE */
+# ifndef M4_SCOPE /* static linking or !_WIN32 */
+# define M4_SCOPE extern
+# endif
+#endif
+
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
+# define __attribute__(Spec) /* empty */
+# endif
+/* The __-protected variants of `format' and `printf' attributes
+ are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+# define __format__ format
+# define __printf__ printf
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined (__STDC__) && __STDC__
+
+/* Print a message with `fprintf (stderr, FORMAT, ...)';
+ if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
+ If STATUS is nonzero, terminate the program with `exit (STATUS)'. */
+
+extern void error (int status, int errnum, const char *format, ...)
+ __attribute__ ((__format__ (__printf__, 3, 4)));
+
+extern void error_at_line (int status, int errnum, const char *fname,
+ unsigned int lineno, const char *format, ...)
+ __attribute__ ((__format__ (__printf__, 5, 6)));
+
+/* If NULL, error will flush stdout, then print on stderr the program
+ name, a colon and a space. Otherwise, error will call this
+ function without parameters instead. */
+M4_SCOPE void (*error_print_progname) (void);
+
+#else
+void error ();
+void error_at_line ();
+M4_SCOPE void (*error_print_progname) ();
+#endif
+
+/* This variable is incremented each time `error' is called. */
+M4_SCOPE unsigned int error_message_count;
+
+/* Sometimes we want to have at most one error per line. This
+ variable controls whether this mode is selected or not. */
+M4_SCOPE int error_one_per_line;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* m4error.h */
diff --git a/lib/m4module.c b/lib/m4module.c
new file mode 100644
index 00000000..b22d8b85
--- /dev/null
+++ b/lib/m4module.c
@@ -0,0 +1,214 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 98 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+
+#define COMPILING_M4
+#include "m4module.h"
+#include "m4private.h"
+
+#ifdef DLL_EXPORT
+# define M4_GLOBAL_DATA __declspec(dllexport)
+#else
+# define M4_GLOBAL_DATA
+#endif
+
+/* The name this program was run with. */
+M4_GLOBAL_DATA const char *program_name;
+
+/* Operate interactively (-e). */
+M4_GLOBAL_DATA int interactive = 0;
+
+/* Enable sync output for /lib/cpp (-s). */
+M4_GLOBAL_DATA int sync_output = 0;
+
+/* Debug (-d[flags]). */
+M4_GLOBAL_DATA int debug_level = 0;
+
+/* Hash table size (should be a prime) (-Hsize). */
+M4_GLOBAL_DATA int hash_table_size = HASHMAX;
+
+/* Disable GNU extensions (-G). */
+M4_GLOBAL_DATA int no_gnu_extensions = 0;
+
+/* Prefix all builtin functions by `m4_'. */
+M4_GLOBAL_DATA int prefix_all_builtins = 0;
+
+/* Max length of arguments in trace output (-lsize). */
+M4_GLOBAL_DATA int max_debug_argument_length = 0;
+
+/* Suppress warnings about missing arguments. */
+M4_GLOBAL_DATA int suppress_warnings = 0;
+
+/* If not zero, then value of exit status for warning diagnostics. */
+M4_GLOBAL_DATA int warning_status = 0;
+
+/* Artificial limit for expansion_level in macro.c. */
+M4_GLOBAL_DATA int nesting_limit = 250;
+
+/* User provided regexp for describing m4 words. */
+M4_GLOBAL_DATA const char *user_word_regexp = NULL;
+
+/* If nonzero, comments are discarded in the token parser. */
+M4_GLOBAL_DATA int discard_comments = 0;
+
+/* input syntax table. */
+M4_GLOBAL_DATA unsigned short syntax_table[256];
+
+/* Quote chars. */
+M4_GLOBAL_DATA STRING rquote;
+M4_GLOBAL_DATA STRING lquote;
+
+/* Comment chars. */
+M4_GLOBAL_DATA STRING bcomm;
+M4_GLOBAL_DATA STRING ecomm;
+
+
+/*------------------------------------------------------------------------.
+| Addressable function versions of the macros defined in m4private.h. |
+| Since they are functions the caller does not need access to the |
+| internal data structure, so they are safe to export for use in |
+| external modules. |
+`------------------------------------------------------------------------*/
+token_data_type
+m4_token_data_type (token_data *name)
+{
+ return TOKEN_DATA_TYPE(name);
+}
+
+char *
+m4_token_data_text (token_data *name)
+{
+ return TOKEN_DATA_TEXT(name);
+}
+
+char *
+m4_token_data_orig_text (token_data *name)
+{
+#ifdef ENABLE_CHANGEWORD
+ return TOKEN_DATA_ORIG_TEXT(name);
+#else
+ return NULL;
+#endif
+}
+
+builtin_func *
+m4_token_data_func (token_data *name)
+{
+ return TOKEN_DATA_FUNC(name);
+}
+
+boolean
+m4_token_data_func_traced (token_data *name)
+{
+ return TOKEN_DATA_FUNC_TRACED(name);
+}
+
+
+/*------------------------------------------------------------------------.
+| Give friendly warnings if a builtin macro is passed an inappropriate |
+| number of arguments. NAME is macro name for messages, ARGC is actual |
+| number of arguments, MIN is the minimum number of acceptable arguments, |
+| negative if not applicable, MAX is the maximum number, negative if not |
+| applicable. |
+`------------------------------------------------------------------------*/
+
+boolean
+m4_bad_argc (token_data *name, int argc, int min, int max)
+{
+ boolean isbad = FALSE;
+
+ if (min > 0 && argc < min)
+ {
+ if (!suppress_warnings)
+ M4ERROR ((warning_status, 0,
+ _("Warning: Too few arguments to built-in `%s'"),
+ TOKEN_DATA_TEXT (name)));
+ isbad = TRUE;
+ }
+ else if (max > 0 && argc > max && !suppress_warnings)
+ M4ERROR ((warning_status, 0,
+ _("Warning: Excess arguments to built-in `%s' ignored"),
+ TOKEN_DATA_TEXT (name)));
+
+ return isbad;
+}
+
+const char *
+m4_skip_space (const char *arg)
+{
+ while (IS_SPACE(*arg))
+ arg++;
+ return arg;
+}
+
+/*--------------------------------------------------------------------------.
+| The function m4_numeric_arg () converts ARG to an int pointed to by |
+| VALUEP. If the conversion fails, print error message for macro MACRO. |
+| Return TRUE iff conversion succeeds. |
+`--------------------------------------------------------------------------*/
+boolean
+m4_numeric_arg (token_data *macro, const char *arg, int *valuep)
+{
+ char *endp;
+
+ if (*arg == 0 || (*valuep = strtol (m4_skip_space(arg), &endp, 10),
+ *m4_skip_space(endp) != 0))
+ {
+ M4ERROR ((warning_status, 0,
+ _("Non-numeric argument to built-in `%s'"),
+ TOKEN_DATA_TEXT (macro)));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*----------------------------------------------------------------------.
+| Format an int VAL, and stuff it into an obstack OBS. Used for macros |
+| expanding to numbers. |
+`----------------------------------------------------------------------*/
+
+void
+m4_shipout_int (struct obstack *obs, int val)
+{
+ char buf[128];
+
+ sprintf(buf, "%d", val);
+ obstack_grow (obs, buf, strlen (buf));
+}
+
+void
+m4_shipout_string (struct obstack *obs, const char *s, int len, boolean quoted)
+{
+ if (s == NULL)
+ s = "";
+
+ if (len == 0)
+ len = strlen(s);
+
+ if (quoted)
+ obstack_grow (obs, lquote.string, lquote.length);
+ obstack_grow (obs, s, len);
+ if (quoted)
+ obstack_grow (obs, rquote.string, rquote.length);
+}
+
diff --git a/lib/m4module.h b/lib/m4module.h
new file mode 100644
index 00000000..74da7200
--- /dev/null
+++ b/lib/m4module.h
@@ -0,0 +1,240 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef M4MODULE_H
+#define M4MODULE_H
+
+#include <sys/types.h>
+#include <m4error.h>
+#include <m4obstack.h>
+
+#ifdef ENABLE_NLS
+#include <libintl.h>
+#define _(Text) gettext ((Text))
+#else
+#define _(Text) (Text)
+#endif
+
+#ifndef M4_PARAMS
+# ifdef __STDC__
+# define M4_PARAMS(Args) Args
+# else
+# define M4_PARAMS(Args) ()
+# endif
+#endif
+
+/* DLL building support on win32 hosts; mostly to workaround their
+ ridiculous implementation of data symbol exporting. */
+#ifndef M4_SCOPE
+# ifdef _WIN32
+ /* Incase we are linking a dll with this library, the
+ LIBM4_DLL_IMPORT takes precedence over a generic DLL_EXPORT
+ when defining the SCOPE variable for M4. */
+# ifdef LIBM4_DLL_IMPORT /* define if linking with this dll */
+# define M4_SCOPE extern __declspec(dllimport)
+# else
+# ifdef DLL_EXPORT /* defined by libtool (if required) */
+# define M4_SCOPE __declspec(dllexport)
+# endif /* DLL_EXPORT */
+# endif /* LIBM4_DLL_IMPORT */
+# endif /* M4_SCOPE */
+# ifndef M4_SCOPE /* static linking or !_WIN32 */
+# define M4_SCOPE extern
+# endif
+#endif
+
+#if __STDC__
+# define voidstar void *
+#else
+# define voidstar char *
+#endif
+
+/* If FALSE is defined, we presume TRUE is defined too. In this case,
+ merely typedef boolean as being int. Or else, define these all. */
+#ifndef FALSE
+/* Do not use `enum boolean': this tag is used in SVR4 <sys/types.h>. */
+typedef enum { FALSE = 0, TRUE = 1 } boolean;
+#else
+typedef int boolean;
+#endif
+
+
+/* Syntax table definitions. */
+/* Please read the comment at the top of input.c for details */
+M4_SCOPE unsigned short syntax_table[256];
+
+/* These are simple values, not bit masks. There is no overlap. */
+#define SYNTAX_OTHER (0x0000)
+
+#define SYNTAX_IGNORE (0x0001)
+#define SYNTAX_SPACE (0x0002)
+#define SYNTAX_OPEN (0x0003)
+#define SYNTAX_CLOSE (0x0004)
+#define SYNTAX_COMMA (0x0005)
+#define SYNTAX_DOLLAR (0x0006) /* not used yet */
+#define SYNTAX_ACTIVE (0x0007)
+#define SYNTAX_ESCAPE (0x0008)
+
+/* These are values to be assigned to syntax table entries, but they are
+ used as bit masks with IS_ALNUM.*/
+#define SYNTAX_ALPHA (0x0010)
+#define SYNTAX_NUM (0x0020)
+#define SYNTAX_ALNUM (SYNTAX_ALPHA|SYNTAX_NUM)
+
+/* These are bit masks to AND with other categories.
+ See input.c for details. */
+#define SYNTAX_LQUOTE (0x0100)
+#define SYNTAX_RQUOTE (0x0200)
+#define SYNTAX_BCOMM (0x0400)
+#define SYNTAX_ECOMM (0x0800)
+
+/* These bits define the syntax code of a character */
+#define SYNTAX_VALUE (0x00FF|SYNTAX_LQUOTE|SYNTAX_BCOMM)
+#define SYNTAX_MASKS (0xFF00)
+
+#define IS_OTHER(ch) ((syntax_table[(int)(ch)]&SYNTAX_VALUE) == SYNTAX_OTHER)
+#define IS_IGNORE(ch) ((syntax_table[(int)(ch)]) == SYNTAX_IGNORE)
+#define IS_SPACE(ch) ((syntax_table[(int)(ch)]&SYNTAX_VALUE) == SYNTAX_SPACE)
+
+#define IS_OPEN(ch) ((syntax_table[(int)(ch)]&SYNTAX_VALUE) == SYNTAX_OPEN)
+#define IS_CLOSE(ch) ((syntax_table[(int)(ch)]&SYNTAX_VALUE) == SYNTAX_CLOSE)
+#define IS_COMMA(ch) ((syntax_table[(int)(ch)]&SYNTAX_VALUE) == SYNTAX_COMMA)
+#define IS_DOLLAR(ch) ((syntax_table[(int)(ch)]&SYNTAX_VALUE) == SYNTAX_DOLLAR)
+#define IS_ACTIVE(ch) ((syntax_table[(int)(ch)]&SYNTAX_VALUE) == SYNTAX_ACTIVE)
+
+#define IS_ESCAPE(ch) ((syntax_table[(int)(ch)]&SYNTAX_VALUE) == SYNTAX_ESCAPE)
+#define IS_ALPHA(ch) ((syntax_table[(int)(ch)]&SYNTAX_VALUE) == SYNTAX_ALPHA)
+#define IS_NUM(ch) ((syntax_table[(int)(ch)]&SYNTAX_VALUE) == SYNTAX_NUM)
+#define IS_ALNUM(ch) (((syntax_table[(int)(ch)]) & SYNTAX_ALNUM) != 0)
+
+#define IS_LQUOTE(ch) (syntax_table[(int)(ch)] & SYNTAX_LQUOTE)
+#define IS_RQUOTE(ch) (syntax_table[(int)(ch)] & SYNTAX_RQUOTE)
+#define IS_BCOMM(ch) (syntax_table[(int)(ch)] & SYNTAX_BCOMM)
+#define IS_ECOMM(ch) (syntax_table[(int)(ch)] & SYNTAX_ECOMM)
+
+
+/* Various declarations. */
+
+struct string
+ {
+ unsigned char *string; /* characters of the string */
+ size_t length; /* length of the string */
+ };
+typedef struct string STRING;
+
+/* Memory allocation. */
+voidstar xmalloc M4_PARAMS((unsigned int));
+voidstar xrealloc M4_PARAMS((voidstar, unsigned int));
+void xfree M4_PARAMS((voidstar));
+char *xstrdup M4_PARAMS((const char *));
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free xfree
+
+/* Other library routines. */
+void error M4_PARAMS((int , int, const char *, ...));
+
+
+typedef void builtin_func ();
+
+typedef struct {
+ const char *name;
+ boolean gnu_extension;
+ boolean groks_macro_args;
+ boolean blind_if_no_args;
+ builtin_func *func;
+} builtin;
+
+/* Various different token types. */
+typedef enum {
+ TOKEN_EOF, /* end of file */
+ TOKEN_NONE, /* discardable token */
+ TOKEN_STRING, /* a quoted string */
+ TOKEN_SPACE, /* whitespace */
+ TOKEN_WORD, /* an identifier */
+ TOKEN_SIMPLE, /* a single character */
+ TOKEN_MACDEF /* a macros definition (see "defn") */
+} token_type;
+
+/* The data for a token, a macro argument, and a macro definition. */
+typedef enum {
+ TOKEN_VOID,
+ TOKEN_TEXT,
+ TOKEN_FUNC
+} token_data_type;
+
+typedef void module_init_t M4_PARAMS((struct obstack *));
+typedef void module_finish_t M4_PARAMS((void));
+
+#ifdef COMPILING_M4
+typedef struct token_data token_data;
+#else
+typedef voidstar token_data;
+#endif
+
+token_data_type m4_token_data_type M4_PARAMS((token_data *));
+char *m4_token_data_text M4_PARAMS((token_data *));
+char *m4_token_data_orig_text M4_PARAMS((token_data *));
+builtin_func *m4_token_data_func M4_PARAMS((token_data *));
+boolean m4_token_data_func_traced M4_PARAMS((token_data *));
+
+#define M4ARG(i) (argc > (i) ? m4_token_data_text (argv[i]) : "")
+
+#define M4BUILTIN(name) \
+ static void name M4_PARAMS((struct obstack *, int, token_data **))
+
+/* Error handling. */
+#define M4ERROR(Arglist) (error Arglist)
+
+#define HASHMAX 509 /* default, overridden by -Hsize */
+
+/* The name this program was run with. */
+M4_SCOPE const char *program_name;
+
+/* Option flags (defined in m4module.c; set in m4.c). */
+M4_SCOPE int interactive; /* -e */
+M4_SCOPE int sync_output; /* -s */
+M4_SCOPE int debug_level; /* -d */
+M4_SCOPE int hash_table_size; /* -H */
+M4_SCOPE int no_gnu_extensions; /* -G */
+M4_SCOPE int prefix_all_builtins; /* -P */
+M4_SCOPE int max_debug_argument_length; /* -l */
+M4_SCOPE int suppress_warnings; /* -Q */
+M4_SCOPE int warning_status; /* -E */
+M4_SCOPE int nesting_limit; /* -L */
+M4_SCOPE int discard_comments; /* -c */
+M4_SCOPE const char *user_word_regexp; /* -W */
+
+/* left and right quote, begin and end comment */
+M4_SCOPE STRING lquote;
+M4_SCOPE STRING rquote;
+
+M4_SCOPE STRING bcomm;
+M4_SCOPE STRING ecomm;
+
+#define DEF_LQUOTE "`"
+#define DEF_RQUOTE "\'"
+#define DEF_BCOMM "#"
+#define DEF_ECOMM "\n"
+
+boolean m4_bad_argc M4_PARAMS((token_data *, int, int, int));
+const char *m4_skip_space M4_PARAMS((const char *));
+boolean m4_numeric_arg M4_PARAMS((token_data *, const char *, int *));
+void m4_shipout_int M4_PARAMS((struct obstack *, int));
+void m4_shipout_string M4_PARAMS((struct obstack*, const char*, int, boolean));
+
+#endif /* M4MODULE_H */
diff --git a/lib/m4obstack.c b/lib/m4obstack.c
new file mode 100644
index 00000000..022b949f
--- /dev/null
+++ b/lib/m4obstack.c
@@ -0,0 +1,598 @@
+/* obstack.c - subroutines used implicitly by object stack macros
+ Copyright (C) 1988-1994,96,97,98,99 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library. Its master source is NOT part of
+ the C library, however. The master source lives in /gd/gnu/lib.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "m4obstack.h"
+
+/* NOTE BEFORE MODIFYING THIS FILE: This version number must be
+ incremented whenever callers compiled using an old obstack.h can no
+ longer properly call the functions in this obstack.c. */
+#define OBSTACK_INTERFACE_VERSION 1
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself, and the installed library
+ supports the same library interface we do. This code is part of the GNU
+ C Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object
+ files, it is simpler to just do this in the source for each such file. */
+
+#include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
+#if !defined (_LIBC) && defined (__GNU_LIBRARY__) && __GNU_LIBRARY__ > 1
+#include <gnu-versions.h>
+#if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+
+#ifndef ELIDE_CODE
+
+
+#if defined (__STDC__) && __STDC__
+#define POINTER void *
+#else
+#define POINTER char *
+#endif
+
+/* Determine default alignment. */
+struct fooalign {char x; double d;};
+#define DEFAULT_ALIGNMENT \
+ ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
+/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
+ But in fact it might be less smart and round addresses to as much as
+ DEFAULT_ROUNDING. So we prepare for it to do that. */
+union fooround {long x; double d;};
+#define DEFAULT_ROUNDING (sizeof (union fooround))
+
+/* When we copy a long block of data, this is the unit to do it with.
+ On some machines, copying successive ints does not work;
+ in such a case, redefine COPYING_UNIT to `long' (if that works)
+ or `char' as a last resort. */
+#ifndef COPYING_UNIT
+#define COPYING_UNIT int
+#endif
+
+
+/* The functions allocating more room by calling `obstack_chunk_alloc'
+ jump to the handler pointed to by `obstack_alloc_failed_handler'.
+ This can be set to a user defined function which should either
+ abort gracefully or use longjump - but shouldn't return. This
+ variable by default points to the internal function
+ `print_and_abort'. */
+#if defined (__STDC__) && __STDC__
+static void print_and_abort (void);
+void (*obstack_alloc_failed_handler) (void) = print_and_abort;
+#else
+static void print_and_abort ();
+void (*obstack_alloc_failed_handler) () = print_and_abort;
+#endif
+
+/* Exit value used when `print_and_abort' is used. */
+#if defined __GNU_LIBRARY__ || defined HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+int obstack_exit_failure = EXIT_FAILURE;
+
+/* The non-GNU-C macros copy the obstack into this global variable
+ to avoid multiple evaluation. */
+
+struct obstack *_obstack;
+
+/* Define a macro that either calls functions with the traditional malloc/free
+ calling interface, or calls functions with the mmalloc/mfree interface
+ (that adds an extra first argument), based on the state of use_extra_arg.
+ For free, do not use ?:, since some compilers, like the MIPS compilers,
+ do not allow (expr) ? void : void. */
+
+#if defined (__STDC__) && __STDC__
+#define CALL_CHUNKFUN(h, size) \
+ (((h) -> use_extra_arg) \
+ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
+ : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
+
+#define CALL_FREEFUN(h, old_chunk) \
+ do { \
+ if ((h) -> use_extra_arg) \
+ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
+ else \
+ (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
+ } while (0)
+#else
+#define CALL_CHUNKFUN(h, size) \
+ (((h) -> use_extra_arg) \
+ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
+ : (*(struct _obstack_chunk *(*) ()) (h)->chunkfun) ((size)))
+
+#define CALL_FREEFUN(h, old_chunk) \
+ do { \
+ if ((h) -> use_extra_arg) \
+ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
+ else \
+ (*(void (*) ()) (h)->freefun) ((old_chunk)); \
+ } while (0)
+#endif
+
+
+/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
+ Objects start on multiples of ALIGNMENT (0 means use default).
+ CHUNKFUN is the function to use to allocate chunks,
+ and FREEFUN the function to free them.
+
+ Return nonzero if successful, calls obstack_alloc_failed_handler if
+ allocation fails. */
+
+int
+_obstack_begin (h, size, alignment, chunkfun, freefun)
+ struct obstack *h;
+ int size;
+ int alignment;
+#if defined (__STDC__) && __STDC__
+ POINTER (*chunkfun) (long);
+ void (*freefun) (void *);
+#else
+ POINTER (*chunkfun) ();
+ void (*freefun) ();
+#endif
+{
+ register struct _obstack_chunk *chunk; /* points to new chunk */
+
+ if (alignment == 0)
+ alignment = (int) DEFAULT_ALIGNMENT;
+ if (size == 0)
+ /* Default size is what GNU malloc can fit in a 4096-byte block. */
+ {
+ /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+ Use the values for range checking, because if range checking is off,
+ the extra bytes won't be missed terribly, but if range checking is on
+ and we used a larger request, a whole extra 4096 bytes would be
+ allocated.
+
+ These number are irrelevant to the new GNU malloc. I suspect it is
+ less sensitive to the size of the request. */
+ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ + 4 + DEFAULT_ROUNDING - 1)
+ & ~(DEFAULT_ROUNDING - 1));
+ size = 4096 - extra;
+ }
+
+#if defined (__STDC__) && __STDC__
+ h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
+ h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
+#else
+ h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
+ h->freefun = freefun;
+#endif
+ h->chunk_size = size;
+ h->alignment_mask = alignment - 1;
+ h->use_extra_arg = 0;
+
+ chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->next_free = h->object_base = chunk->contents;
+ h->chunk_limit = chunk->limit
+ = (char *) chunk + h->chunk_size;
+ chunk->prev = 0;
+ /* The initial chunk now contains no empty object. */
+ h->maybe_empty_object = 0;
+ h->alloc_failed = 0;
+ return 1;
+}
+
+int
+_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
+ struct obstack *h;
+ int size;
+ int alignment;
+#if defined (__STDC__) && __STDC__
+ POINTER (*chunkfun) (POINTER, long);
+ void (*freefun) (POINTER, POINTER);
+#else
+ POINTER (*chunkfun) ();
+ void (*freefun) ();
+#endif
+ POINTER arg;
+{
+ register struct _obstack_chunk *chunk; /* points to new chunk */
+
+ if (alignment == 0)
+ alignment = (int) DEFAULT_ALIGNMENT;
+ if (size == 0)
+ /* Default size is what GNU malloc can fit in a 4096-byte block. */
+ {
+ /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+ Use the values for range checking, because if range checking is off,
+ the extra bytes won't be missed terribly, but if range checking is on
+ and we used a larger request, a whole extra 4096 bytes would be
+ allocated.
+
+ These number are irrelevant to the new GNU malloc. I suspect it is
+ less sensitive to the size of the request. */
+ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ + 4 + DEFAULT_ROUNDING - 1)
+ & ~(DEFAULT_ROUNDING - 1));
+ size = 4096 - extra;
+ }
+
+#if defined(__STDC__) && __STDC__
+ h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
+ h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
+#else
+ h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
+ h->freefun = freefun;
+#endif
+ h->chunk_size = size;
+ h->alignment_mask = alignment - 1;
+ h->extra_arg = arg;
+ h->use_extra_arg = 1;
+
+ chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->next_free = h->object_base = chunk->contents;
+ h->chunk_limit = chunk->limit
+ = (char *) chunk + h->chunk_size;
+ chunk->prev = 0;
+ /* The initial chunk now contains no empty object. */
+ h->maybe_empty_object = 0;
+ h->alloc_failed = 0;
+ return 1;
+}
+
+/* Allocate a new current chunk for the obstack *H
+ on the assumption that LENGTH bytes need to be added
+ to the current object, or a new object of length LENGTH allocated.
+ Copies any partial object from the end of the old chunk
+ to the beginning of the new one. */
+
+void
+_obstack_newchunk (h, length)
+ struct obstack *h;
+ int length;
+{
+ register struct _obstack_chunk *old_chunk = h->chunk;
+ register struct _obstack_chunk *new_chunk;
+ register long new_size;
+ register long obj_size = h->next_free - h->object_base;
+ register long i;
+ long already;
+
+ /* Compute size for new chunk. */
+ new_size = (obj_size + length) + (obj_size >> 3) + 100;
+ if (new_size < h->chunk_size)
+ new_size = h->chunk_size;
+
+ /* Allocate and initialize the new chunk. */
+ new_chunk = CALL_CHUNKFUN (h, new_size);
+ if (!new_chunk)
+ (*obstack_alloc_failed_handler) ();
+ h->chunk = new_chunk;
+ new_chunk->prev = old_chunk;
+ new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
+
+ /* Move the existing object to the new chunk.
+ Word at a time is fast and is safe if the object
+ is sufficiently aligned. */
+ if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
+ {
+ for (i = obj_size / sizeof (COPYING_UNIT) - 1;
+ i >= 0; i--)
+ ((COPYING_UNIT *)new_chunk->contents)[i]
+ = ((COPYING_UNIT *)h->object_base)[i];
+ /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
+ but that can cross a page boundary on a machine
+ which does not do strict alignment for COPYING_UNITS. */
+ already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
+ }
+ else
+ already = 0;
+ /* Copy remaining bytes one by one. */
+ for (i = already; i < obj_size; i++)
+ new_chunk->contents[i] = h->object_base[i];
+
+ /* If the object just copied was the only data in OLD_CHUNK,
+ free that chunk and remove it from the chain.
+ But not if that chunk might contain an empty object. */
+ if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
+ {
+ new_chunk->prev = old_chunk->prev;
+ CALL_FREEFUN (h, old_chunk);
+ }
+
+ h->object_base = new_chunk->contents;
+ h->next_free = h->object_base + obj_size;
+ /* The new chunk certainly contains no empty object yet. */
+ h->maybe_empty_object = 0;
+}
+
+/* Return nonzero if object OBJ has been allocated from obstack H.
+ This is here for debugging.
+ If you use it in a program, you are probably losing. */
+
+#if defined (__STDC__) && __STDC__
+/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
+ obstack.h because it is just for debugging. */
+int _obstack_allocated_p (struct obstack *h, POINTER obj);
+#endif
+
+int
+_obstack_allocated_p (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = (h)->chunk;
+ /* We use >= rather than > since the object cannot be exactly at
+ the beginning of the chunk but might be an empty object exactly
+ at the end of an adjacent chunk. */
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ lp = plp;
+ }
+ return lp != 0;
+}
+
+/* Free objects in obstack H, including OBJ and everything allocate
+ more recently than OBJ. If OBJ is zero, free everything in H. */
+
+#undef obstack_free
+
+/* This function has two names with identical definitions.
+ This is the first one, called from non-ANSI code. */
+
+void
+_obstack_free (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = h->chunk;
+ /* We use >= because there cannot be an object at the beginning of a chunk.
+ But there can be an empty object at that address
+ at the end of another chunk. */
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ CALL_FREEFUN (h, lp);
+ lp = plp;
+ /* If we switch chunks, we can't tell whether the new current
+ chunk contains an empty object, so assume that it may. */
+ h->maybe_empty_object = 1;
+ }
+ if (lp)
+ {
+ h->object_base = h->next_free = (char *) (obj);
+ h->chunk_limit = lp->limit;
+ h->chunk = lp;
+ }
+ else if (obj != 0)
+ /* obj is not in any of the chunks! */
+ abort ();
+}
+
+/* This function is used from ANSI code. */
+
+void
+obstack_free (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk *plp; /* point to previous chunk if any */
+
+ lp = h->chunk;
+ /* We use >= because there cannot be an object at the beginning of a chunk.
+ But there can be an empty object at that address
+ at the end of another chunk. */
+ while (lp != 0 && ((POINTER) lp >= obj || (POINTER) (lp)->limit < obj))
+ {
+ plp = lp->prev;
+ CALL_FREEFUN (h, lp);
+ lp = plp;
+ /* If we switch chunks, we can't tell whether the new current
+ chunk contains an empty object, so assume that it may. */
+ h->maybe_empty_object = 1;
+ }
+ if (lp)
+ {
+ h->object_base = h->next_free = (char *) (obj);
+ h->chunk_limit = lp->limit;
+ h->chunk = lp;
+ }
+ else if (obj != 0)
+ /* obj is not in any of the chunks! */
+ abort ();
+}
+
+int
+_obstack_memory_used (h)
+ struct obstack *h;
+{
+ register struct _obstack_chunk* lp;
+ register int nbytes = 0;
+
+ for (lp = h->chunk; lp != 0; lp = lp->prev)
+ {
+ nbytes += lp->limit - (char *) lp;
+ }
+ return nbytes;
+}
+
+/* Define the error handler. */
+#ifndef _
+# ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# ifndef _
+# define _(Str) gettext (Str)
+# endif
+# else
+# define _(Str) (Str)
+# endif
+#endif
+#if defined _LIBC && defined USE_IN_LIBIO
+# include <libio/iolibio.h>
+# define fputs(s, f) _IO_fputs (s, f)
+#endif
+
+static void
+print_and_abort ()
+{
+ fputs (_("memory exhausted"), stderr);
+ fputc ('\n', stderr);
+ exit (obstack_exit_failure);
+}
+
+#if 0
+/* These are now turned off because the applications do not use it
+ and it uses bcopy via obstack_grow, which causes trouble on sysV. */
+
+/* Now define the functional versions of the obstack macros.
+ Define them to simply use the corresponding macros to do the job. */
+
+#if defined (__STDC__) && __STDC__
+/* These function definitions do not work with non-ANSI preprocessors;
+ they won't pass through the macro names in parentheses. */
+
+/* The function names appear in parentheses in order to prevent
+ the macro-definitions of the names from being expanded there. */
+
+POINTER (obstack_base) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_base (obstack);
+}
+
+POINTER (obstack_next_free) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_next_free (obstack);
+}
+
+int (obstack_object_size) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_object_size (obstack);
+}
+
+int (obstack_room) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_room (obstack);
+}
+
+int (obstack_make_room) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ return obstack_make_room (obstack, length);
+}
+
+void (obstack_grow) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ obstack_grow (obstack, pointer, length);
+}
+
+void (obstack_grow0) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ obstack_grow0 (obstack, pointer, length);
+}
+
+void (obstack_1grow) (obstack, character)
+ struct obstack *obstack;
+ int character;
+{
+ obstack_1grow (obstack, character);
+}
+
+void (obstack_blank) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ obstack_blank (obstack, length);
+}
+
+void (obstack_1grow_fast) (obstack, character)
+ struct obstack *obstack;
+ int character;
+{
+ obstack_1grow_fast (obstack, character);
+}
+
+void (obstack_blank_fast) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ obstack_blank_fast (obstack, length);
+}
+
+POINTER (obstack_finish) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_finish (obstack);
+}
+
+POINTER (obstack_alloc) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ return obstack_alloc (obstack, length);
+}
+
+POINTER (obstack_copy) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ return obstack_copy (obstack, pointer, length);
+}
+
+POINTER (obstack_copy0) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ return obstack_copy0 (obstack, pointer, length);
+}
+
+#endif /* __STDC__ */
+
+#endif /* 0 */
+
+#endif /* !ELIDE_CODE */
diff --git a/lib/m4obstack.h b/lib/m4obstack.h
new file mode 100644
index 00000000..4d49ce02
--- /dev/null
+++ b/lib/m4obstack.h
@@ -0,0 +1,593 @@
+/* obstack.h - object stack macros
+ Copyright (C) 1988,89,90,91,92,93,94,96,97,98,99 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library. Its master source is NOT part of
+ the C library, however. The master source lives in /gd/gnu/lib.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* Summary:
+
+All the apparent functions defined here are macros. The idea
+is that you would use these pre-tested macros to solve a
+very specific set of problems, and they would run fast.
+Caution: no side-effects in arguments please!! They may be
+evaluated MANY times!!
+
+These macros operate a stack of objects. Each object starts life
+small, and may grow to maturity. (Consider building a word syllable
+by syllable.) An object can move while it is growing. Once it has
+been "finished" it never changes address again. So the "top of the
+stack" is typically an immature growing object, while the rest of the
+stack is of mature, fixed size and fixed address objects.
+
+These routines grab large chunks of memory, using a function you
+supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
+by calling `obstack_chunk_free'. You must define them and declare
+them before using any obstack macros.
+
+Each independent stack is represented by a `struct obstack'.
+Each of the obstack macros expects a pointer to such a structure
+as the first argument.
+
+One motivation for this package is the problem of growing char strings
+in symbol tables. Unless you are "fascist pig with a read-only mind"
+--Gosper's immortal quote from HAKMEM item 154, out of context--you
+would not like to put any arbitrary upper limit on the length of your
+symbols.
+
+In practice this often means you will build many short symbols and a
+few long symbols. At the time you are reading a symbol you don't know
+how long it is. One traditional method is to read a symbol into a
+buffer, realloc()ating the buffer every time you try to read a symbol
+that is longer than the buffer. This is beaut, but you still will
+want to copy the symbol from the buffer to a more permanent
+symbol-table entry say about half the time.
+
+With obstacks, you can work differently. Use one obstack for all symbol
+names. As you read a symbol, grow the name in the obstack gradually.
+When the name is complete, finalize it. Then, if the symbol exists already,
+free the newly read name.
+
+The way we do this is to take a large chunk, allocating memory from
+low addresses. When you want to build a symbol in the chunk you just
+add chars above the current "high water mark" in the chunk. When you
+have finished adding chars, because you got to the end of the symbol,
+you know how long the chars are, and you can create a new object.
+Mostly the chars will not burst over the highest address of the chunk,
+because you would typically expect a chunk to be (say) 100 times as
+long as an average object.
+
+In case that isn't clear, when we have enough chars to make up
+the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
+so we just point to it where it lies. No moving of chars is
+needed and this is the second win: potentially long strings need
+never be explicitly shuffled. Once an object is formed, it does not
+change its address during its lifetime.
+
+When the chars burst over a chunk boundary, we allocate a larger
+chunk, and then copy the partly formed object from the end of the old
+chunk to the beginning of the new larger chunk. We then carry on
+accreting characters to the end of the object as we normally would.
+
+A special macro is provided to add a single char at a time to a
+growing object. This allows the use of register variables, which
+break the ordinary 'growth' macro.
+
+Summary:
+ We allocate large chunks.
+ We carve out one object at a time from the current chunk.
+ Once carved, an object never moves.
+ We are free to append data of any size to the currently
+ growing object.
+ Exactly one object is growing in an obstack at any one time.
+ You can run one obstack per control block.
+ You may have as many control blocks as you dare.
+ Because of the way we do it, you can `unwind' an obstack
+ back to a previous state. (You may remove objects much
+ as you would with a stack.)
+*/
+
+
+/* Don't do the contents of this file more than once. */
+
+#ifndef _OBSTACK_H
+#define _OBSTACK_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* We use subtraction of (char *) 0 instead of casting to int
+ because on word-addressable machines a simple cast to int
+ may ignore the byte-within-word field of the pointer. */
+
+#ifndef __PTR_TO_INT
+# define __PTR_TO_INT(P) ((P) - (char *) 0)
+#endif
+
+#ifndef __INT_TO_PTR
+# define __INT_TO_PTR(P) ((P) + (char *) 0)
+#endif
+
+/* We need the type of the resulting object. If __PTRDIFF_TYPE__ is
+ defined, as with GNU C, use that; that way we don't pollute the
+ namespace with <stddef.h>'s symbols. Otherwise, if <stddef.h> is
+ available, include it and use ptrdiff_t. In traditional C, long is
+ the best that we can do. */
+
+#ifdef __PTRDIFF_TYPE__
+# define PTR_INT_TYPE __PTRDIFF_TYPE__
+#else
+# ifdef HAVE_STDDEF_H
+# include <stddef.h>
+# define PTR_INT_TYPE ptrdiff_t
+# else
+# define PTR_INT_TYPE long
+# endif
+#endif
+
+#if defined _LIBC || defined HAVE_STRING_H
+# include <string.h>
+# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N))
+#else
+# ifdef memcpy
+# define _obstack_memcpy(To, From, N) memcpy ((To), (From), (N))
+# else
+# define _obstack_memcpy(To, From, N) bcopy ((From), (To), (N))
+# endif
+#endif
+
+struct _obstack_chunk /* Lives at front of each chunk. */
+{
+ char *limit; /* 1 past end of this chunk */
+ struct _obstack_chunk *prev; /* address of prior chunk or NULL */
+ char contents[4]; /* objects begin here */
+};
+
+struct obstack /* control current object in current chunk */
+{
+ long chunk_size; /* preferred size to allocate chunks in */
+ struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
+ char *object_base; /* address of object we are building */
+ char *next_free; /* where to add next char to current object */
+ char *chunk_limit; /* address of char after current chunk */
+ PTR_INT_TYPE temp; /* Temporary for some macros. */
+ int alignment_mask; /* Mask of alignment for each object. */
+#if defined __STDC__ && __STDC__
+ /* These prototypes vary based on `use_extra_arg', and we use
+ casts to the prototypeless function type in all assignments,
+ but having prototypes here quiets -Wstrict-prototypes. */
+ struct _obstack_chunk *(*chunkfun) (void *, long);
+ void (*freefun) (void *, struct _obstack_chunk *);
+ void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
+#else
+ struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */
+ void (*freefun) (); /* User's function to free a chunk. */
+ char *extra_arg; /* first arg for chunk alloc/dealloc funcs */
+#endif
+ unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
+ unsigned maybe_empty_object:1;/* There is a possibility that the current
+ chunk contains a zero-length object. This
+ prevents freeing the chunk if we allocate
+ a bigger chunk to replace it. */
+ unsigned alloc_failed:1; /* No longer used, as we now call the failed
+ handler on error, but retained for binary
+ compatibility. */
+};
+
+/* Declare the external functions we use; they are in obstack.c. */
+
+#if defined __STDC__ && __STDC__
+extern void _obstack_newchunk (struct obstack *, int);
+extern void _obstack_free (struct obstack *, void *);
+extern int _obstack_begin (struct obstack *, int, int,
+ void *(*) (long), void (*) (void *));
+extern int _obstack_begin_1 (struct obstack *, int, int,
+ void *(*) (void *, long),
+ void (*) (void *, void *), void *);
+extern int _obstack_memory_used (struct obstack *);
+#else
+extern void _obstack_newchunk ();
+extern void _obstack_free ();
+extern int _obstack_begin ();
+extern int _obstack_begin_1 ();
+extern int _obstack_memory_used ();
+#endif
+
+#if defined __STDC__ && __STDC__
+
+/* Do the function-declarations after the structs
+ but before defining the macros. */
+
+void obstack_init (struct obstack *obstack);
+
+void * obstack_alloc (struct obstack *obstack, int size);
+
+void * obstack_copy (struct obstack *obstack, void *address, int size);
+void * obstack_copy0 (struct obstack *obstack, void *address, int size);
+
+void obstack_free (struct obstack *obstack, void *block);
+
+void obstack_blank (struct obstack *obstack, int size);
+
+void obstack_grow (struct obstack *obstack, void *data, int size);
+void obstack_grow0 (struct obstack *obstack, void *data, int size);
+
+void obstack_1grow (struct obstack *obstack, int data_char);
+void obstack_ptr_grow (struct obstack *obstack, void *data);
+void obstack_int_grow (struct obstack *obstack, int data);
+
+void * obstack_finish (struct obstack *obstack);
+
+int obstack_object_size (struct obstack *obstack);
+
+int obstack_room (struct obstack *obstack);
+void obstack_make_room (struct obstack *obstack, int size);
+void obstack_1grow_fast (struct obstack *obstack, int data_char);
+void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
+void obstack_int_grow_fast (struct obstack *obstack, int data);
+void obstack_blank_fast (struct obstack *obstack, int size);
+
+void * obstack_base (struct obstack *obstack);
+void * obstack_next_free (struct obstack *obstack);
+int obstack_alignment_mask (struct obstack *obstack);
+int obstack_chunk_size (struct obstack *obstack);
+int obstack_memory_used (struct obstack *obstack);
+
+#endif /* __STDC__ */
+
+/* Non-ANSI C cannot really support alternative functions for these macros,
+ so we do not declare them. */
+
+/* Error handler called when `obstack_chunk_alloc' failed to allocate
+ more memory. This can be set to a user defined function which
+ should either abort gracefully or use longjump - but shouldn't
+ return. The default action is to print a message and abort. */
+#if defined __STDC__ && __STDC__
+extern void (*obstack_alloc_failed_handler) (void);
+#else
+extern void (*obstack_alloc_failed_handler) ();
+#endif
+
+/* Exit value used when `print_and_abort' is used. */
+extern int obstack_exit_failure;
+
+/* Pointer to beginning of object being allocated or to be allocated next.
+ Note that this might not be the final address of the object
+ because a new chunk might be needed to hold the final size. */
+
+#define obstack_base(h) ((h)->object_base)
+
+/* Size for allocating ordinary chunks. */
+
+#define obstack_chunk_size(h) ((h)->chunk_size)
+
+/* Pointer to next byte not yet allocated in current chunk. */
+
+#define obstack_next_free(h) ((h)->next_free)
+
+/* Mask specifying low bits that should be clear in address of an object. */
+
+#define obstack_alignment_mask(h) ((h)->alignment_mask)
+
+/* To prevent prototype warnings provide complete argument list in
+ standard C version. */
+#if defined __STDC__ && __STDC__
+
+# define obstack_init(h) \
+ _obstack_begin ((h), 0, 0, \
+ (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
+
+# define obstack_begin(h, size) \
+ _obstack_begin ((h), (size), 0, \
+ (void *(*) (long)) obstack_chunk_alloc, (void (*) (void *)) obstack_chunk_free)
+
+# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
+ _obstack_begin ((h), (size), (alignment), \
+ (void *(*) (long)) (chunkfun), (void (*) (void *)) (freefun))
+
+# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
+ _obstack_begin_1 ((h), (size), (alignment), \
+ (void *(*) (void *, long)) (chunkfun), \
+ (void (*) (void *, void *)) (freefun), (arg))
+
+# define obstack_chunkfun(h, newchunkfun) \
+ ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
+
+# define obstack_freefun(h, newfreefun) \
+ ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
+
+#else
+
+# define obstack_init(h) \
+ _obstack_begin ((h), 0, 0, \
+ (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
+
+# define obstack_begin(h, size) \
+ _obstack_begin ((h), (size), 0, \
+ (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
+
+# define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
+ _obstack_begin ((h), (size), (alignment), \
+ (void *(*) ()) (chunkfun), (void (*) ()) (freefun))
+
+# define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
+ _obstack_begin_1 ((h), (size), (alignment), \
+ (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg))
+
+# define obstack_chunkfun(h, newchunkfun) \
+ ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun))
+
+# define obstack_freefun(h, newfreefun) \
+ ((h) -> freefun = (void (*)()) (newfreefun))
+
+#endif
+
+#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
+
+#define obstack_blank_fast(h,n) ((h)->next_free += (n))
+
+#define obstack_memory_used(h) _obstack_memory_used (h)
+
+#if defined __GNUC__ && defined __STDC__ && __STDC__
+/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
+ does not implement __extension__. But that compiler doesn't define
+ __GNUC_MINOR__. */
+# if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
+# define __extension__
+# endif
+
+/* For GNU C, if not -traditional,
+ we can define these macros to compute all args only once
+ without using a global variable.
+ Also, we can avoid using the `temp' slot, to make faster code. */
+
+# define obstack_object_size(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ (unsigned) (__o->next_free - __o->object_base); })
+
+# define obstack_room(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ (unsigned) (__o->chunk_limit - __o->next_free); })
+
+# define obstack_make_room(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->chunk_limit - __o->next_free < __len) \
+ _obstack_newchunk (__o, __len); \
+ (void) 0; })
+
+# define obstack_empty_p(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); })
+
+# define obstack_grow(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->next_free + __len > __o->chunk_limit) \
+ _obstack_newchunk (__o, __len); \
+ _obstack_memcpy (__o->next_free, (char *) (where), __len); \
+ __o->next_free += __len; \
+ (void) 0; })
+
+# define obstack_grow0(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->next_free + __len + 1 > __o->chunk_limit) \
+ _obstack_newchunk (__o, __len + 1); \
+ _obstack_memcpy (__o->next_free, (char *) (where), __len); \
+ __o->next_free += __len; \
+ *(__o->next_free)++ = 0; \
+ (void) 0; })
+
+# define obstack_1grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + 1 > __o->chunk_limit) \
+ _obstack_newchunk (__o, 1); \
+ *(__o->next_free)++ = (datum); \
+ (void) 0; })
+
+/* These assume that the obstack alignment is good enough for pointers or ints,
+ and that the data added so far to the current object
+ shares that much alignment. */
+
+# define obstack_ptr_grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
+ _obstack_newchunk (__o, sizeof (void *)); \
+ *((void **)__o->next_free)++ = ((void *)datum); \
+ (void) 0; })
+
+# define obstack_int_grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + sizeof (int) > __o->chunk_limit) \
+ _obstack_newchunk (__o, sizeof (int)); \
+ *((int *)__o->next_free)++ = ((int)datum); \
+ (void) 0; })
+
+# define obstack_ptr_grow_fast(h,aptr) (*((void **) (h)->next_free)++ = (void *)aptr)
+# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
+
+# define obstack_blank(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->chunk_limit - __o->next_free < __len) \
+ _obstack_newchunk (__o, __len); \
+ __o->next_free += __len; \
+ (void) 0; })
+
+# define obstack_alloc(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_blank (__h, (length)); \
+ obstack_finish (__h); })
+
+# define obstack_copy(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_grow (__h, (where), (length)); \
+ obstack_finish (__h); })
+
+# define obstack_copy0(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_grow0 (__h, (where), (length)); \
+ obstack_finish (__h); })
+
+/* The local variable is named __o1 to avoid a name conflict
+ when obstack_blank is called. */
+# define obstack_finish(OBSTACK) \
+__extension__ \
+({ struct obstack *__o1 = (OBSTACK); \
+ void *value; \
+ value = (void *) __o1->object_base; \
+ if (__o1->next_free == value) \
+ __o1->maybe_empty_object = 1; \
+ __o1->next_free \
+ = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
+ & ~ (__o1->alignment_mask)); \
+ if (__o1->next_free - (char *)__o1->chunk \
+ > __o1->chunk_limit - (char *)__o1->chunk) \
+ __o1->next_free = __o1->chunk_limit; \
+ __o1->object_base = __o1->next_free; \
+ value; })
+
+# define obstack_free(OBSTACK, OBJ) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ void *__obj = (OBJ); \
+ if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
+ __o->next_free = __o->object_base = (char *)__obj; \
+ else (obstack_free) (__o, __obj); })
+
+#else /* not __GNUC__ or not __STDC__ */
+
+# define obstack_object_size(h) \
+ (unsigned) ((h)->next_free - (h)->object_base)
+
+# define obstack_room(h) \
+ (unsigned) ((h)->chunk_limit - (h)->next_free)
+
+# define obstack_empty_p(h) \
+ ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0)
+
+/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
+ so that we can avoid having void expressions
+ in the arms of the conditional expression.
+ Casting the third operand to void was tried before,
+ but some compilers won't accept it. */
+
+# define obstack_make_room(h,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0))
+
+# define obstack_grow(h,where,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
+ _obstack_memcpy ((h)->next_free, (char *) (where), (h)->temp), \
+ (h)->next_free += (h)->temp)
+
+# define obstack_grow0(h,where,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \
+ _obstack_memcpy ((h)->next_free, (char *) (where), (h)->temp), \
+ (h)->next_free += (h)->temp, \
+ *((h)->next_free)++ = 0)
+
+# define obstack_1grow(h,datum) \
+( (((h)->next_free + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), 1), 0) : 0), \
+ (*((h)->next_free)++ = (datum)))
+
+# define obstack_ptr_grow(h,datum) \
+( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
+ (*((char **) (((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *) datum)))
+
+# define obstack_int_grow(h,datum) \
+( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
+ (*((int *) (((h)->next_free+=sizeof(int))-sizeof(int))) = ((int) datum)))
+
+# define obstack_ptr_grow_fast(h,aptr) (*((char **) (h)->next_free)++ = (char *) aptr)
+# define obstack_int_grow_fast(h,aint) (*((int *) (h)->next_free)++ = (int) aint)
+
+# define obstack_blank(h,length) \
+( (h)->temp = (length), \
+ (((h)->chunk_limit - (h)->next_free < (h)->temp) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
+ ((h)->next_free += (h)->temp))
+
+# define obstack_alloc(h,length) \
+ (obstack_blank ((h), (length)), obstack_finish ((h)))
+
+# define obstack_copy(h,where,length) \
+ (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
+
+# define obstack_copy0(h,where,length) \
+ (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
+
+# define obstack_finish(h) \
+( ((h)->next_free == (h)->object_base \
+ ? (((h)->maybe_empty_object = 1), 0) \
+ : 0), \
+ (h)->temp = __PTR_TO_INT ((h)->object_base), \
+ (h)->next_free \
+ = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \
+ & ~ ((h)->alignment_mask)), \
+ (((h)->next_free - (char *) (h)->chunk \
+ > (h)->chunk_limit - (char *) (h)->chunk) \
+ ? ((h)->next_free = (h)->chunk_limit) : 0), \
+ (h)->object_base = (h)->next_free, \
+ __INT_TO_PTR ((h)->temp))
+
+# if defined __STDC__ && __STDC__
+# define obstack_free(h,obj) \
+( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \
+ (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+ ? (int) ((h)->next_free = (h)->object_base \
+ = (h)->temp + (char *) (h)->chunk) \
+ : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
+# else
+# define obstack_free(h,obj) \
+( (h)->temp = (char *) (obj) - (char *) (h)->chunk, \
+ (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+ ? (int) ((h)->next_free = (h)->object_base \
+ = (h)->temp + (char *) (h)->chunk) \
+ : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0)))
+# endif
+
+#endif /* not __GNUC__ or not __STDC__ */
+
+#ifdef __cplusplus
+} /* C++ */
+#endif
+
+#endif /* obstack.h */
diff --git a/lib/m4private.h b/lib/m4private.h
new file mode 100644
index 00000000..03542d79
--- /dev/null
+++ b/lib/m4private.h
@@ -0,0 +1,68 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94, 98 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+struct token_data {
+ token_data_type type;
+ union {
+ struct {
+ char *text;
+#ifdef ENABLE_CHANGEWORD
+ char *original_text;
+#endif
+ } u_t;
+ struct {
+ builtin_func *func;
+ boolean traced;
+ } u_f;
+ } u;
+};
+
+#define TOKEN_DATA_TYPE(Td) ((Td)->type)
+#define TOKEN_DATA_TEXT(Td) ((Td)->u.u_t.text)
+#ifdef ENABLE_CHANGEWORD
+# define TOKEN_DATA_ORIG_TEXT(Td) ((Td)->u.u_t.original_text)
+#endif
+#define TOKEN_DATA_FUNC(Td) ((Td)->u.u_f.func)
+#define TOKEN_DATA_FUNC_TRACED(Td) ((Td)->u.u_f.traced)
+
+/* Redefine the exported function using macro to this faster
+ macro based version for internal use by the m4 code. */
+#undef M4ARG
+#define M4ARG(i) (argc > (i) ? TOKEN_DATA_TEXT (argv[i]) : "")
+
+struct symbol
+{
+ struct symbol *next;
+ boolean traced;
+ boolean shadowed;
+ boolean macro_args;
+ boolean blind_no_args;
+
+ char *name;
+ token_data data;
+};
+
+#define SYMBOL_NEXT(S) ((S)->next)
+#define SYMBOL_TRACED(S) ((S)->traced)
+#define SYMBOL_SHADOWED(S) ((S)->shadowed)
+#define SYMBOL_MACRO_ARGS(S) ((S)->macro_args)
+#define SYMBOL_BLIND_NO_ARGS(S) ((S)->blind_no_args)
+#define SYMBOL_NAME(S) ((S)->name)
+#define SYMBOL_TYPE(S) (TOKEN_DATA_TYPE (&(S)->data))
+#define SYMBOL_TEXT(S) (TOKEN_DATA_TEXT (&(S)->data))
+#define SYMBOL_FUNC(S) (TOKEN_DATA_FUNC (&(S)->data))
diff --git a/lib/m4regex.c b/lib/m4regex.c
new file mode 100644
index 00000000..36f7faca
--- /dev/null
+++ b/lib/m4regex.c
@@ -0,0 +1,5880 @@
+/* Extended regular expression matching and search library,
+ version 0.12.
+ (Implements POSIX draft P1003.2/D11.2, except for some of the
+ internationalization features.)
+ Copyright (C) 1993, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* AIX requires this to be the first thing in the file. */
+#if defined _AIX && !defined REGEX_MALLOC
+ #pragma alloca
+#endif
+
+#undef _GNU_SOURCE
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifndef PARAMS
+# if defined __GNUC__ || (defined __STDC__ && __STDC__)
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif /* GCC. */
+#endif /* Not PARAMS. */
+
+#if defined STDC_HEADERS && !defined emacs
+# include <stddef.h>
+#else
+/* We need this for `regex.h', and perhaps for the Emacs include files. */
+# include <sys/types.h>
+#endif
+
+#define WIDE_CHAR_SUPPORT (HAVE_WCTYPE_H && HAVE_WCHAR_H && HAVE_BTOWC)
+
+/* For platform which support the ISO C amendement 1 functionality we
+ support user defined character classes. */
+#if defined _LIBC || WIDE_CHAR_SUPPORT
+/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
+# include <wchar.h>
+# include <wctype.h>
+#endif
+
+#ifdef _LIBC
+/* We have to keep the namespace clean. */
+# define regfree(preg) __regfree (preg)
+# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef)
+# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags)
+# define regerror(errcode, preg, errbuf, errbuf_size) \
+ __regerror(errcode, preg, errbuf, errbuf_size)
+# define re_set_registers(bu, re, nu, st, en) \
+ __re_set_registers (bu, re, nu, st, en)
+# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \
+ __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+# define re_match(bufp, string, size, pos, regs) \
+ __re_match (bufp, string, size, pos, regs)
+# define re_search(bufp, string, size, startpos, range, regs) \
+ __re_search (bufp, string, size, startpos, range, regs)
+# define re_compile_pattern(pattern, length, bufp) \
+ __re_compile_pattern (pattern, length, bufp)
+# define re_set_syntax(syntax) __re_set_syntax (syntax)
+# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \
+ __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop)
+# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp)
+
+#define btowc __btowc
+#endif
+
+/* This is for other GNU distributions with internationalized messages. */
+#if HAVE_LIBINTL_H || defined _LIBC
+# include <libintl.h>
+#else
+# define gettext(msgid) (msgid)
+#endif
+
+#ifndef gettext_noop
+/* This define is so xgettext can find the internationalizable
+ strings. */
+# define gettext_noop(String) String
+#endif
+
+/* The `emacs' switch turns on certain matching commands
+ that make sense only in Emacs. */
+#ifdef emacs
+
+# include "lisp.h"
+# include "buffer.h"
+# include "syntax.h"
+
+#else /* not emacs */
+
+/* If we are not linking with Emacs proper,
+ we can't use the relocating allocator
+ even if config.h says that we can. */
+# undef REL_ALLOC
+
+# if defined STDC_HEADERS || defined _LIBC
+# include <stdlib.h>
+# else
+char *malloc ();
+char *realloc ();
+# endif
+
+/* When used in Emacs's lib-src, we need to get bzero and bcopy somehow.
+ If nothing else has been done, use the method below. */
+# ifdef INHIBIT_STRING_HEADER
+# if !(defined HAVE_BZERO && defined HAVE_BCOPY)
+# if !defined bzero && !defined bcopy
+# undef INHIBIT_STRING_HEADER
+# endif
+# endif
+# endif
+
+/* This is the normal way of making sure we have a bcopy and a bzero.
+ This is used in most programs--a few other programs avoid this
+ by defining INHIBIT_STRING_HEADER. */
+# ifndef INHIBIT_STRING_HEADER
+# if defined HAVE_STRING_H || defined STDC_HEADERS || defined _LIBC
+# include <string.h>
+# ifndef bzero
+# ifndef _LIBC
+# define bzero(s, n) (memset (s, '\0', n), (s))
+# else
+# define bzero(s, n) __bzero (s, n)
+# endif
+# endif
+# else
+# include <strings.h>
+# ifndef memcmp
+# define memcmp(s1, s2, n) bcmp (s1, s2, n)
+# endif
+# ifndef memcpy
+# define memcpy(d, s, n) (bcopy (s, d, n), (d))
+# endif
+# endif
+# endif
+
+/* Define the syntax stuff for \<, \>, etc. */
+
+/* This must be nonzero for the wordchar and notwordchar pattern
+ commands in re_match_2. */
+# ifndef Sword
+# define Sword 1
+# endif
+
+# ifdef SWITCH_ENUM_BUG
+# define SWITCH_ENUM_CAST(x) ((int)(x))
+# else
+# define SWITCH_ENUM_CAST(x) (x)
+# endif
+
+/* How many characters in the character set. */
+# define CHAR_SET_SIZE 256
+
+# ifdef SYNTAX_TABLE
+
+extern char *re_syntax_table;
+
+# else /* not SYNTAX_TABLE */
+
+static char re_syntax_table[CHAR_SET_SIZE];
+
+static void
+init_syntax_once ()
+{
+ register int c;
+ static int done;
+
+ if (done)
+ return;
+
+ bzero (re_syntax_table, sizeof re_syntax_table);
+
+ for (c = 'a'; c <= 'z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = 'A'; c <= 'Z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = '0'; c <= '9'; c++)
+ re_syntax_table[c] = Sword;
+
+ re_syntax_table['_'] = Sword;
+
+ done = 1;
+}
+
+# endif /* not SYNTAX_TABLE */
+
+# define SYNTAX(c) re_syntax_table[c]
+
+#endif /* not emacs */
+
+/* Get the interface, including the syntax bits. */
+#include <m4regex.h>
+
+/* isalpha etc. are used for the character classes. */
+#include <ctype.h>
+
+/* Jim Meyering writes:
+
+ "... Some ctype macros are valid only for character codes that
+ isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
+ using /bin/cc or gcc but without giving an ansi option). So, all
+ ctype uses should be through macros like ISPRINT... If
+ STDC_HEADERS is defined, then autoconf has verified that the ctype
+ macros don't need to be guarded with references to isascii. ...
+ Defining isascii to 1 should let any compiler worth its salt
+ eliminate the && through constant folding."
+ Solaris defines some of these symbols so we must undefine them first. */
+
+#undef ISASCII
+#if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
+# define ISASCII(c) 1
+#else
+# define ISASCII(c) isascii(c)
+#endif
+
+#ifdef isblank
+# define ISBLANK(c) (ISASCII (c) && isblank (c))
+#else
+# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+#ifdef isgraph
+# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
+#else
+# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
+#endif
+
+#undef ISPRINT
+#define ISPRINT(c) (ISASCII (c) && isprint (c))
+#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
+#define ISALNUM(c) (ISASCII (c) && isalnum (c))
+#define ISALPHA(c) (ISASCII (c) && isalpha (c))
+#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
+#define ISLOWER(c) (ISASCII (c) && islower (c))
+#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
+#define ISSPACE(c) (ISASCII (c) && isspace (c))
+#define ISUPPER(c) (ISASCII (c) && isupper (c))
+#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
+
+#ifdef _tolower
+# define TOLOWER(c) _tolower(c)
+#else
+# define TOLOWER(c) tolower(c)
+#endif
+
+#ifndef NULL
+# define NULL (void *)0
+#endif
+
+/* We remove any previous definition of `SIGN_EXTEND_CHAR',
+ since ours (we hope) works properly with all combinations of
+ machines, compilers, `char' and `unsigned char' argument types.
+ (Per Bothner suggested the basic approach.) */
+#undef SIGN_EXTEND_CHAR
+#if __STDC__
+# define SIGN_EXTEND_CHAR(c) ((signed char) (c))
+#else /* not __STDC__ */
+/* As in Harbison and Steele. */
+# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
+#endif
+
+/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
+ use `alloca' instead of `malloc'. This is because using malloc in
+ re_search* or re_match* could cause memory leaks when C-g is used in
+ Emacs; also, malloc is slower and causes storage fragmentation. On
+ the other hand, malloc is more portable, and easier to debug.
+
+ Because we sometimes use alloca, some routines have to be macros,
+ not functions -- `alloca'-allocated space disappears at the end of the
+ function it is called in. */
+
+#ifdef REGEX_MALLOC
+
+# define REGEX_ALLOCATE malloc
+# define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
+# define REGEX_FREE free
+
+#else /* not REGEX_MALLOC */
+
+/* Emacs already defines alloca, sometimes. */
+# ifndef alloca
+
+/* Make alloca work the best possible way. */
+# ifdef __GNUC__
+# define alloca __builtin_alloca
+# else /* not __GNUC__ */
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# endif /* HAVE_ALLOCA_H */
+# endif /* not __GNUC__ */
+
+# endif /* not alloca */
+
+# define REGEX_ALLOCATE alloca
+
+/* Assumes a `char *destination' variable. */
+# define REGEX_REALLOCATE(source, osize, nsize) \
+ (destination = (char *) alloca (nsize), \
+ memcpy (destination, source, osize))
+
+/* No need to do anything to free, after alloca. */
+# define REGEX_FREE(arg) ((void)0) /* Do nothing! But inhibit gcc warning. */
+
+#endif /* not REGEX_MALLOC */
+
+/* Define how to allocate the failure stack. */
+
+#if defined REL_ALLOC && defined REGEX_MALLOC
+
+# define REGEX_ALLOCATE_STACK(size) \
+ r_alloc (&failure_stack_ptr, (size))
+# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
+ r_re_alloc (&failure_stack_ptr, (nsize))
+# define REGEX_FREE_STACK(ptr) \
+ r_alloc_free (&failure_stack_ptr)
+
+#else /* not using relocating allocator */
+
+# ifdef REGEX_MALLOC
+
+# define REGEX_ALLOCATE_STACK malloc
+# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
+# define REGEX_FREE_STACK free
+
+# else /* not REGEX_MALLOC */
+
+# define REGEX_ALLOCATE_STACK alloca
+
+# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
+ REGEX_REALLOCATE (source, osize, nsize)
+/* No need to explicitly free anything. */
+# define REGEX_FREE_STACK(arg)
+
+# endif /* not REGEX_MALLOC */
+#endif /* not using relocating allocator */
+
+
+/* True if `size1' is non-NULL and PTR is pointing anywhere inside
+ `string1' or just past its end. This works if PTR is NULL, which is
+ a good thing. */
+#define FIRST_STRING_P(ptr) \
+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
+
+/* (Re)Allocate N items of type T using malloc, or fail. */
+#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
+#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
+#define RETALLOC_IF(addr, n, t) \
+ if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
+#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
+
+#define BYTEWIDTH 8 /* In bits. */
+
+#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
+
+#undef MAX
+#undef MIN
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+typedef char boolean;
+#define false 0
+#define true 1
+
+static int re_match_2_internal PARAMS ((struct re_pattern_buffer *bufp,
+ const char *string1, int size1,
+ const char *string2, int size2,
+ int pos,
+ struct re_registers *regs,
+ int stop));
+
+/* These are the command codes that appear in compiled regular
+ expressions. Some opcodes are followed by argument bytes. A
+ command code can specify any interpretation whatsoever for its
+ arguments. Zero bytes may appear in the compiled regular expression. */
+
+typedef enum
+{
+ no_op = 0,
+
+ /* Succeed right away--no more backtracking. */
+ succeed,
+
+ /* Followed by one byte giving n, then by n literal bytes. */
+ exactn,
+
+ /* Matches any (more or less) character. */
+ anychar,
+
+ /* Matches any one char belonging to specified set. First
+ following byte is number of bitmap bytes. Then come bytes
+ for a bitmap saying which chars are in. Bits in each byte
+ are ordered low-bit-first. A character is in the set if its
+ bit is 1. A character too large to have a bit in the map is
+ automatically not in the set. */
+ charset,
+
+ /* Same parameters as charset, but match any character that is
+ not one of those specified. */
+ charset_not,
+
+ /* Start remembering the text that is matched, for storing in a
+ register. Followed by one byte with the register number, in
+ the range 0 to one less than the pattern buffer's re_nsub
+ field. Then followed by one byte with the number of groups
+ inner to this one. (This last has to be part of the
+ start_memory only because we need it in the on_failure_jump
+ of re_match_2.) */
+ start_memory,
+
+ /* Stop remembering the text that is matched and store it in a
+ memory register. Followed by one byte with the register
+ number, in the range 0 to one less than `re_nsub' in the
+ pattern buffer, and one byte with the number of inner groups,
+ just like `start_memory'. (We need the number of inner
+ groups here because we don't have any easy way of finding the
+ corresponding start_memory when we're at a stop_memory.) */
+ stop_memory,
+
+ /* Match a duplicate of something remembered. Followed by one
+ byte containing the register number. */
+ duplicate,
+
+ /* Fail unless at beginning of line. */
+ begline,
+
+ /* Fail unless at end of line. */
+ endline,
+
+ /* Succeeds if at beginning of buffer (if emacs) or at beginning
+ of string to be matched (if not). */
+ begbuf,
+
+ /* Analogously, for end of buffer/string. */
+ endbuf,
+
+ /* Followed by two byte relative address to which to jump. */
+ jump,
+
+ /* Same as jump, but marks the end of an alternative. */
+ jump_past_alt,
+
+ /* Followed by two-byte relative address of place to resume at
+ in case of failure. */
+ on_failure_jump,
+
+ /* Like on_failure_jump, but pushes a placeholder instead of the
+ current string position when executed. */
+ on_failure_keep_string_jump,
+
+ /* Throw away latest failure point and then jump to following
+ two-byte relative address. */
+ pop_failure_jump,
+
+ /* Change to pop_failure_jump if know won't have to backtrack to
+ match; otherwise change to jump. This is used to jump
+ back to the beginning of a repeat. If what follows this jump
+ clearly won't match what the repeat does, such that we can be
+ sure that there is no use backtracking out of repetitions
+ already matched, then we change it to a pop_failure_jump.
+ Followed by two-byte address. */
+ maybe_pop_jump,
+
+ /* Jump to following two-byte address, and push a dummy failure
+ point. This failure point will be thrown away if an attempt
+ is made to use it for a failure. A `+' construct makes this
+ before the first repeat. Also used as an intermediary kind
+ of jump when compiling an alternative. */
+ dummy_failure_jump,
+
+ /* Push a dummy failure point and continue. Used at the end of
+ alternatives. */
+ push_dummy_failure,
+
+ /* Followed by two-byte relative address and two-byte number n.
+ After matching N times, jump to the address upon failure. */
+ succeed_n,
+
+ /* Followed by two-byte relative address, and two-byte number n.
+ Jump to the address N times, then fail. */
+ jump_n,
+
+ /* Set the following two-byte relative address to the
+ subsequent two-byte number. The address *includes* the two
+ bytes of number. */
+ set_number_at,
+
+ wordchar, /* Matches any word-constituent character. */
+ notwordchar, /* Matches any char that is not a word-constituent. */
+
+ wordbeg, /* Succeeds if at word beginning. */
+ wordend, /* Succeeds if at word end. */
+
+ wordbound, /* Succeeds if at a word boundary. */
+ notwordbound /* Succeeds if not at a word boundary. */
+
+#ifdef emacs
+ ,before_dot, /* Succeeds if before point. */
+ at_dot, /* Succeeds if at point. */
+ after_dot, /* Succeeds if after point. */
+
+ /* Matches any character whose syntax is specified. Followed by
+ a byte which contains a syntax code, e.g., Sword. */
+ syntaxspec,
+
+ /* Matches any character whose syntax is not that specified. */
+ notsyntaxspec
+#endif /* emacs */
+} re_opcode_t;
+
+/* Common operations on the compiled pattern. */
+
+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
+
+#define STORE_NUMBER(destination, number) \
+ do { \
+ (destination)[0] = (number) & 0377; \
+ (destination)[1] = (number) >> 8; \
+ } while (0)
+
+/* Same as STORE_NUMBER, except increment DESTINATION to
+ the byte after where the number is stored. Therefore, DESTINATION
+ must be an lvalue. */
+
+#define STORE_NUMBER_AND_INCR(destination, number) \
+ do { \
+ STORE_NUMBER (destination, number); \
+ (destination) += 2; \
+ } while (0)
+
+/* Put into DESTINATION a number stored in two contiguous bytes starting
+ at SOURCE. */
+
+#define EXTRACT_NUMBER(destination, source) \
+ do { \
+ (destination) = *(source) & 0377; \
+ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
+ } while (0)
+
+#ifdef DEBUG
+static void extract_number _RE_ARGS ((int *dest, unsigned char *source));
+static void
+extract_number (dest, source)
+ int *dest;
+ unsigned char *source;
+{
+ int temp = SIGN_EXTEND_CHAR (*(source + 1));
+ *dest = *source & 0377;
+ *dest += temp << 8;
+}
+
+# ifndef EXTRACT_MACROS /* To debug the macros. */
+# undef EXTRACT_NUMBER
+# define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
+# endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
+ SOURCE must be an lvalue. */
+
+#define EXTRACT_NUMBER_AND_INCR(destination, source) \
+ do { \
+ EXTRACT_NUMBER (destination, source); \
+ (source) += 2; \
+ } while (0)
+
+#ifdef DEBUG
+static void extract_number_and_incr _RE_ARGS ((int *destination,
+ unsigned char **source));
+static void
+extract_number_and_incr (destination, source)
+ int *destination;
+ unsigned char **source;
+{
+ extract_number (destination, *source);
+ *source += 2;
+}
+
+# ifndef EXTRACT_MACROS
+# undef EXTRACT_NUMBER_AND_INCR
+# define EXTRACT_NUMBER_AND_INCR(dest, src) \
+ extract_number_and_incr (&dest, &src)
+# endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* If DEBUG is defined, Regex prints many voluminous messages about what
+ it is doing (if the variable `debug' is nonzero). If linked with the
+ main program in `iregex.c', you can enter patterns and strings
+ interactively. And if linked with the main program in `main.c' and
+ the other test files, you can run the already-written tests. */
+
+#ifdef DEBUG
+
+/* We use standard I/O for debugging. */
+# include <stdio.h>
+
+/* It is useful to test things that ``must'' be true when debugging. */
+# include <assert.h>
+
+static int debug;
+
+# define DEBUG_STATEMENT(e) e
+# define DEBUG_PRINT1(x) if (debug) printf (x)
+# define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
+# define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
+# define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
+# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
+ if (debug) print_partial_compiled_pattern (s, e)
+# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
+ if (debug) print_double_string (w, s1, sz1, s2, sz2)
+
+
+/* Print the fastmap in human-readable form. */
+
+void
+print_fastmap (fastmap)
+ char *fastmap;
+{
+ unsigned was_a_range = 0;
+ unsigned i = 0;
+
+ while (i < (1 << BYTEWIDTH))
+ {
+ if (fastmap[i++])
+ {
+ was_a_range = 0;
+ putchar (i - 1);
+ while (i < (1 << BYTEWIDTH) && fastmap[i])
+ {
+ was_a_range = 1;
+ i++;
+ }
+ if (was_a_range)
+ {
+ printf ("-");
+ putchar (i - 1);
+ }
+ }
+ }
+ putchar ('\n');
+}
+
+
+/* Print a compiled pattern string in human-readable form, starting at
+ the START pointer into it and ending just before the pointer END. */
+
+void
+print_partial_compiled_pattern (start, end)
+ unsigned char *start;
+ unsigned char *end;
+{
+ int mcnt, mcnt2;
+ unsigned char *p1;
+ unsigned char *p = start;
+ unsigned char *pend = end;
+
+ if (start == NULL)
+ {
+ printf ("(null)\n");
+ return;
+ }
+
+ /* Loop over pattern commands. */
+ while (p < pend)
+ {
+ printf ("%d:\t", p - start);
+
+ switch ((re_opcode_t) *p++)
+ {
+ case no_op:
+ printf ("/no_op");
+ break;
+
+ case exactn:
+ mcnt = *p++;
+ printf ("/exactn/%d", mcnt);
+ do
+ {
+ putchar ('/');
+ putchar (*p++);
+ }
+ while (--mcnt);
+ break;
+
+ case start_memory:
+ mcnt = *p++;
+ printf ("/start_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case stop_memory:
+ mcnt = *p++;
+ printf ("/stop_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case duplicate:
+ printf ("/duplicate/%d", *p++);
+ break;
+
+ case anychar:
+ printf ("/anychar");
+ break;
+
+ case charset:
+ case charset_not:
+ {
+ register int c, last = -100;
+ register int in_range = 0;
+
+ printf ("/charset [%s",
+ (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
+
+ assert (p + *p < pend);
+
+ for (c = 0; c < 256; c++)
+ if (c / 8 < *p
+ && (p[1 + (c/8)] & (1 << (c % 8))))
+ {
+ /* Are we starting a range? */
+ if (last + 1 == c && ! in_range)
+ {
+ putchar ('-');
+ in_range = 1;
+ }
+ /* Have we broken a range? */
+ else if (last + 1 != c && in_range)
+ {
+ putchar (last);
+ in_range = 0;
+ }
+
+ if (! in_range)
+ putchar (c);
+
+ last = c;
+ }
+
+ if (in_range)
+ putchar (last);
+
+ putchar (']');
+
+ p += 1 + *p;
+ }
+ break;
+
+ case begline:
+ printf ("/begline");
+ break;
+
+ case endline:
+ printf ("/endline");
+ break;
+
+ case on_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case on_failure_keep_string_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_keep_string_jump to %d", p + mcnt - start);
+ break;
+
+ case dummy_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/dummy_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case push_dummy_failure:
+ printf ("/push_dummy_failure");
+ break;
+
+ case maybe_pop_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/maybe_pop_jump to %d", p + mcnt - start);
+ break;
+
+ case pop_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/pop_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case jump_past_alt:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump_past_alt to %d", p + mcnt - start);
+ break;
+
+ case jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump to %d", p + mcnt - start);
+ break;
+
+ case succeed_n:
+ extract_number_and_incr (&mcnt, &p);
+ p1 = p + mcnt;
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/succeed_n to %d, %d times", p1 - start, mcnt2);
+ break;
+
+ case jump_n:
+ extract_number_and_incr (&mcnt, &p);
+ p1 = p + mcnt;
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/jump_n to %d, %d times", p1 - start, mcnt2);
+ break;
+
+ case set_number_at:
+ extract_number_and_incr (&mcnt, &p);
+ p1 = p + mcnt;
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/set_number_at location %d to %d", p1 - start, mcnt2);
+ break;
+
+ case wordbound:
+ printf ("/wordbound");
+ break;
+
+ case notwordbound:
+ printf ("/notwordbound");
+ break;
+
+ case wordbeg:
+ printf ("/wordbeg");
+ break;
+
+ case wordend:
+ printf ("/wordend");
+
+# ifdef emacs
+ case before_dot:
+ printf ("/before_dot");
+ break;
+
+ case at_dot:
+ printf ("/at_dot");
+ break;
+
+ case after_dot:
+ printf ("/after_dot");
+ break;
+
+ case syntaxspec:
+ printf ("/syntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+
+ case notsyntaxspec:
+ printf ("/notsyntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+# endif /* emacs */
+
+ case wordchar:
+ printf ("/wordchar");
+ break;
+
+ case notwordchar:
+ printf ("/notwordchar");
+ break;
+
+ case begbuf:
+ printf ("/begbuf");
+ break;
+
+ case endbuf:
+ printf ("/endbuf");
+ break;
+
+ default:
+ printf ("?%d", *(p-1));
+ }
+
+ putchar ('\n');
+ }
+
+ printf ("%d:\tend of pattern.\n", p - start);
+}
+
+
+void
+print_compiled_pattern (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ unsigned char *buffer = bufp->buffer;
+
+ print_partial_compiled_pattern (buffer, buffer + bufp->used);
+ printf ("%ld bytes used/%ld bytes allocated.\n",
+ bufp->used, bufp->allocated);
+
+ if (bufp->fastmap_accurate && bufp->fastmap)
+ {
+ printf ("fastmap: ");
+ print_fastmap (bufp->fastmap);
+ }
+
+ printf ("re_nsub: %d\t", bufp->re_nsub);
+ printf ("regs_alloc: %d\t", bufp->regs_allocated);
+ printf ("can_be_null: %d\t", bufp->can_be_null);
+ printf ("newline_anchor: %d\n", bufp->newline_anchor);
+ printf ("no_sub: %d\t", bufp->no_sub);
+ printf ("not_bol: %d\t", bufp->not_bol);
+ printf ("not_eol: %d\t", bufp->not_eol);
+ printf ("syntax: %lx\n", bufp->syntax);
+ /* Perhaps we should print the translate table? */
+}
+
+
+void
+print_double_string (where, string1, size1, string2, size2)
+ const char *where;
+ const char *string1;
+ const char *string2;
+ int size1;
+ int size2;
+{
+ int this_char;
+
+ if (where == NULL)
+ printf ("(null)");
+ else
+ {
+ if (FIRST_STRING_P (where))
+ {
+ for (this_char = where - string1; this_char < size1; this_char++)
+ putchar (string1[this_char]);
+
+ where = string2;
+ }
+
+ for (this_char = where - string2; this_char < size2; this_char++)
+ putchar (string2[this_char]);
+ }
+}
+
+void
+printchar (c)
+ int c;
+{
+ putc (c, stderr);
+}
+
+#else /* not DEBUG */
+
+# undef assert
+# define assert(e)
+
+# define DEBUG_STATEMENT(e)
+# define DEBUG_PRINT1(x)
+# define DEBUG_PRINT2(x1, x2)
+# define DEBUG_PRINT3(x1, x2, x3)
+# define DEBUG_PRINT4(x1, x2, x3, x4)
+# define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
+# define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
+
+#endif /* not DEBUG */
+
+/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
+ also be assigned to arbitrarily: each pattern buffer stores its own
+ syntax, so it can be changed between regex compilations. */
+/* This has no initializer because initialized variables in Emacs
+ become read-only after dumping. */
+reg_syntax_t re_syntax_options;
+
+
+/* Specify the precise syntax of regexps for compilation. This provides
+ for compatibility for various utilities which historically have
+ different, incompatible syntaxes.
+
+ The argument SYNTAX is a bit mask comprised of the various bits
+ defined in regex.h. We return the old syntax. */
+
+reg_syntax_t
+re_set_syntax (syntax)
+ reg_syntax_t syntax;
+{
+ reg_syntax_t ret = re_syntax_options;
+
+ re_syntax_options = syntax;
+#ifdef DEBUG
+ if (syntax & RE_DEBUG)
+ debug = 1;
+ else if (debug) /* was on but now is not */
+ debug = 0;
+#endif /* DEBUG */
+ return ret;
+}
+#ifdef _LIBC
+weak_alias (__re_set_syntax, re_set_syntax)
+#endif
+
+/* This table gives an error message for each of the error codes listed
+ in regex.h. Obviously the order here has to be same as there.
+ POSIX doesn't require that we do anything for REG_NOERROR,
+ but why not be nice? */
+
+static const char re_error_msgid[] =
+ {
+#define REG_NOERROR_IDX 0
+ gettext_noop ("Success") /* REG_NOERROR */
+ "\0"
+#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success")
+ gettext_noop ("No match") /* REG_NOMATCH */
+ "\0"
+#define REG_BADPAT_IDX (REG_NOMATCH_IDX + sizeof "No match")
+ gettext_noop ("Invalid regular expression") /* REG_BADPAT */
+ "\0"
+#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression")
+ gettext_noop ("Invalid collation character") /* REG_ECOLLATE */
+ "\0"
+#define REG_ECTYPE_IDX (REG_ECOLLATE_IDX + sizeof "Invalid collation character")
+ gettext_noop ("Invalid character class name") /* REG_ECTYPE */
+ "\0"
+#define REG_EESCAPE_IDX (REG_ECTYPE_IDX + sizeof "Invalid character class name")
+ gettext_noop ("Trailing backslash") /* REG_EESCAPE */
+ "\0"
+#define REG_ESUBREG_IDX (REG_EESCAPE_IDX + sizeof "Trailing backslash")
+ gettext_noop ("Invalid back reference") /* REG_ESUBREG */
+ "\0"
+#define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference")
+ gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */
+ "\0"
+#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^")
+ gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
+ "\0"
+#define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(")
+ gettext_noop ("Unmatched \\{") /* REG_EBRACE */
+ "\0"
+#define REG_BADBR_IDX (REG_EBRACE_IDX + sizeof "Unmatched \\{")
+ gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */
+ "\0"
+#define REG_ERANGE_IDX (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}")
+ gettext_noop ("Invalid range end") /* REG_ERANGE */
+ "\0"
+#define REG_ESPACE_IDX (REG_ERANGE_IDX + sizeof "Invalid range end")
+ gettext_noop ("Memory exhausted") /* REG_ESPACE */
+ "\0"
+#define REG_BADRPT_IDX (REG_ESPACE_IDX + sizeof "Memory exhausted")
+ gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */
+ "\0"
+#define REG_EEND_IDX (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression")
+ gettext_noop ("Premature end of regular expression") /* REG_EEND */
+ "\0"
+#define REG_ESIZE_IDX (REG_EEND_IDX + sizeof "Premature end of regular expression")
+ gettext_noop ("Regular expression too big") /* REG_ESIZE */
+ "\0"
+#define REG_ERPAREN_IDX (REG_ESIZE_IDX + sizeof "Regular expression too big")
+ gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
+ };
+
+static const size_t re_error_msgid_idx[] =
+ {
+ REG_NOERROR_IDX,
+ REG_NOMATCH_IDX,
+ REG_BADPAT_IDX,
+ REG_ECOLLATE_IDX,
+ REG_ECTYPE_IDX,
+ REG_EESCAPE_IDX,
+ REG_ESUBREG_IDX,
+ REG_EBRACK_IDX,
+ REG_EPAREN_IDX,
+ REG_EBRACE_IDX,
+ REG_BADBR_IDX,
+ REG_ERANGE_IDX,
+ REG_ESPACE_IDX,
+ REG_BADRPT_IDX,
+ REG_EEND_IDX,
+ REG_ESIZE_IDX,
+ REG_ERPAREN_IDX
+ };
+
+/* Avoiding alloca during matching, to placate r_alloc. */
+
+/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
+ searching and matching functions should not call alloca. On some
+ systems, alloca is implemented in terms of malloc, and if we're
+ using the relocating allocator routines, then malloc could cause a
+ relocation, which might (if the strings being searched are in the
+ ralloc heap) shift the data out from underneath the regexp
+ routines.
+
+ Here's another reason to avoid allocation: Emacs
+ processes input from X in a signal handler; processing X input may
+ call malloc; if input arrives while a matching routine is calling
+ malloc, then we're scrod. But Emacs can't just block input while
+ calling matching routines; then we don't notice interrupts when
+ they come in. So, Emacs blocks input around all regexp calls
+ except the matching calls, which it leaves unprotected, in the
+ faith that they will not malloc. */
+
+/* Normally, this is fine. */
+#define MATCH_MAY_ALLOCATE
+
+/* When using GNU C, we are not REALLY using the C alloca, no matter
+ what config.h may say. So don't take precautions for it. */
+#ifdef __GNUC__
+# undef C_ALLOCA
+#endif
+
+/* The match routines may not allocate if (1) they would do it with malloc
+ and (2) it's not safe for them to use malloc.
+ Note that if REL_ALLOC is defined, matching would not use malloc for the
+ failure stack, but we would still use it for the register vectors;
+ so REL_ALLOC should not affect this. */
+#if (defined C_ALLOCA || defined REGEX_MALLOC) && defined emacs
+# undef MATCH_MAY_ALLOCATE
+#endif
+
+
+/* Failure stack declarations and macros; both re_compile_fastmap and
+ re_match_2 use a failure stack. These have to be macros because of
+ REGEX_ALLOCATE_STACK. */
+
+
+/* Number of failure points for which to initially allocate space
+ when matching. If this number is exceeded, we allocate more
+ space, so it is not a hard limit. */
+#ifndef INIT_FAILURE_ALLOC
+# define INIT_FAILURE_ALLOC 5
+#endif
+
+/* Roughly the maximum number of failure points on the stack. Would be
+ exactly that if always used MAX_FAILURE_ITEMS items each time we failed.
+ This is a variable only so users of regex can assign to it; we never
+ change it ourselves. */
+
+#ifdef INT_IS_16BIT
+
+# if defined MATCH_MAY_ALLOCATE
+/* 4400 was enough to cause a crash on Alpha OSF/1,
+ whose default stack limit is 2mb. */
+long int re_max_failures = 4000;
+# else
+long int re_max_failures = 2000;
+# endif
+
+union fail_stack_elt
+{
+ unsigned char *pointer;
+ long int integer;
+};
+
+typedef union fail_stack_elt fail_stack_elt_t;
+
+typedef struct
+{
+ fail_stack_elt_t *stack;
+ unsigned long int size;
+ unsigned long int avail; /* Offset of next open position. */
+} fail_stack_type;
+
+#else /* not INT_IS_16BIT */
+
+# if defined MATCH_MAY_ALLOCATE
+/* 4400 was enough to cause a crash on Alpha OSF/1,
+ whose default stack limit is 2mb. */
+int re_max_failures = 20000;
+# else
+int re_max_failures = 2000;
+# endif
+
+union fail_stack_elt
+{
+ unsigned char *pointer;
+ int integer;
+};
+
+typedef union fail_stack_elt fail_stack_elt_t;
+
+typedef struct
+{
+ fail_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} fail_stack_type;
+
+#endif /* INT_IS_16BIT */
+
+#define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
+#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
+#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
+
+
+/* Define macros to initialize and free the failure stack.
+ Do `return -2' if the alloc fails. */
+
+#ifdef MATCH_MAY_ALLOCATE
+# define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.stack = (fail_stack_elt_t *) \
+ REGEX_ALLOCATE_STACK (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \
+ \
+ if (fail_stack.stack == NULL) \
+ return -2; \
+ \
+ fail_stack.size = INIT_FAILURE_ALLOC; \
+ fail_stack.avail = 0; \
+ } while (0)
+
+# define RESET_FAIL_STACK() REGEX_FREE_STACK (fail_stack.stack)
+#else
+# define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.avail = 0; \
+ } while (0)
+
+# define RESET_FAIL_STACK()
+#endif
+
+
+/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
+
+ Return 1 if succeeds, and 0 if either ran out of memory
+ allocating space for it or it was already too large.
+
+ REGEX_REALLOCATE_STACK requires `destination' be declared. */
+
+#define DOUBLE_FAIL_STACK(fail_stack) \
+ ((fail_stack).size > (unsigned) (re_max_failures * MAX_FAILURE_ITEMS) \
+ ? 0 \
+ : ((fail_stack).stack = (fail_stack_elt_t *) \
+ REGEX_REALLOCATE_STACK ((fail_stack).stack, \
+ (fail_stack).size * sizeof (fail_stack_elt_t), \
+ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
+ \
+ (fail_stack).stack == NULL \
+ ? 0 \
+ : ((fail_stack).size <<= 1, \
+ 1)))
+
+
+/* Push pointer POINTER on FAIL_STACK.
+ Return 1 if was able to do so and 0 if ran out of memory allocating
+ space to do so. */
+#define PUSH_PATTERN_OP(POINTER, FAIL_STACK) \
+ ((FAIL_STACK_FULL () \
+ && !DOUBLE_FAIL_STACK (FAIL_STACK)) \
+ ? 0 \
+ : ((FAIL_STACK).stack[(FAIL_STACK).avail++].pointer = POINTER, \
+ 1))
+
+/* Push a pointer value onto the failure stack.
+ Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_POINTER(item) \
+ fail_stack.stack[fail_stack.avail++].pointer = (unsigned char *) (item)
+
+/* This pushes an integer-valued item onto the failure stack.
+ Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_INT(item) \
+ fail_stack.stack[fail_stack.avail++].integer = (item)
+
+/* Push a fail_stack_elt_t value onto the failure stack.
+ Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_ELT(item) \
+ fail_stack.stack[fail_stack.avail++] = (item)
+
+/* These three POP... operations complement the three PUSH... operations.
+ All assume that `fail_stack' is nonempty. */
+#define POP_FAILURE_POINTER() fail_stack.stack[--fail_stack.avail].pointer
+#define POP_FAILURE_INT() fail_stack.stack[--fail_stack.avail].integer
+#define POP_FAILURE_ELT() fail_stack.stack[--fail_stack.avail]
+
+/* Used to omit pushing failure point id's when we're not debugging. */
+#ifdef DEBUG
+# define DEBUG_PUSH PUSH_FAILURE_INT
+# define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_INT ()
+#else
+# define DEBUG_PUSH(item)
+# define DEBUG_POP(item_addr)
+#endif
+
+
+/* Push the information about the state we will need
+ if we ever fail back to it.
+
+ Requires variables fail_stack, regstart, regend, reg_info, and
+ num_regs_pushed be declared. DOUBLE_FAIL_STACK requires `destination'
+ be declared.
+
+ Does `return FAILURE_CODE' if runs out of memory. */
+
+#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
+ do { \
+ char *destination; \
+ /* Must be int, so when we don't save any registers, the arithmetic \
+ of 0 + -1 isn't done as unsigned. */ \
+ /* Can't be int, since there is not a shred of a guarantee that int \
+ is wide enough to hold a value of something to which pointer can \
+ be assigned */ \
+ active_reg_t this_reg; \
+ \
+ DEBUG_STATEMENT (failure_id++); \
+ DEBUG_STATEMENT (nfailure_points_pushed++); \
+ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
+ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
+ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
+ \
+ DEBUG_PRINT2 (" slots needed: %ld\n", NUM_FAILURE_ITEMS); \
+ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
+ \
+ /* Ensure we have enough space allocated for what we will push. */ \
+ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
+ { \
+ if (!DOUBLE_FAIL_STACK (fail_stack)) \
+ return failure_code; \
+ \
+ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
+ (fail_stack).size); \
+ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
+ } \
+ \
+ /* Push the info, starting with the registers. */ \
+ DEBUG_PRINT1 ("\n"); \
+ \
+ if (1) \
+ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
+ this_reg++) \
+ { \
+ DEBUG_PRINT2 (" Pushing reg: %lu\n", this_reg); \
+ DEBUG_STATEMENT (num_regs_pushed++); \
+ \
+ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \
+ PUSH_FAILURE_POINTER (regstart[this_reg]); \
+ \
+ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \
+ PUSH_FAILURE_POINTER (regend[this_reg]); \
+ \
+ DEBUG_PRINT2 (" info: %p\n ", \
+ reg_info[this_reg].word.pointer); \
+ DEBUG_PRINT2 (" match_null=%d", \
+ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" matched_something=%d", \
+ MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" ever_matched=%d", \
+ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT1 ("\n"); \
+ PUSH_FAILURE_ELT (reg_info[this_reg].word); \
+ } \
+ \
+ DEBUG_PRINT2 (" Pushing low active reg: %ld\n", lowest_active_reg);\
+ PUSH_FAILURE_INT (lowest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing high active reg: %ld\n", highest_active_reg);\
+ PUSH_FAILURE_INT (highest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing pattern %p:\n", pattern_place); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
+ PUSH_FAILURE_POINTER (pattern_place); \
+ \
+ DEBUG_PRINT2 (" Pushing string %p: `", string_place); \
+ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
+ size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ PUSH_FAILURE_POINTER (string_place); \
+ \
+ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
+ DEBUG_PUSH (failure_id); \
+ } while (0)
+
+/* This is the number of items that are pushed and popped on the stack
+ for each register. */
+#define NUM_REG_ITEMS 3
+
+/* Individual items aside from the registers. */
+#ifdef DEBUG
+# define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
+#else
+# define NUM_NONREG_ITEMS 4
+#endif
+
+/* We push at most this many items on the stack. */
+/* We used to use (num_regs - 1), which is the number of registers
+ this regexp will save; but that was changed to 5
+ to avoid stack overflow for a regexp with lots of parens. */
+#define MAX_FAILURE_ITEMS (5 * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
+
+/* We actually push this many items. */
+#define NUM_FAILURE_ITEMS \
+ (((0 \
+ ? 0 : highest_active_reg - lowest_active_reg + 1) \
+ * NUM_REG_ITEMS) \
+ + NUM_NONREG_ITEMS)
+
+/* How many items can still be added to the stack without overflowing it. */
+#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
+
+
+/* Pops what PUSH_FAIL_STACK pushes.
+
+ We restore into the parameters, all of which should be lvalues:
+ STR -- the saved data position.
+ PAT -- the saved pattern position.
+ LOW_REG, HIGH_REG -- the highest and lowest active registers.
+ REGSTART, REGEND -- arrays of string positions.
+ REG_INFO -- array of information about each subexpression.
+
+ Also assumes the variables `fail_stack' and (if debugging), `bufp',
+ `pend', `string1', `size1', `string2', and `size2'. */
+
+#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
+{ \
+ DEBUG_STATEMENT (unsigned failure_id;) \
+ active_reg_t this_reg; \
+ const unsigned char *string_temp; \
+ \
+ assert (!FAIL_STACK_EMPTY ()); \
+ \
+ /* Remove failure points and point to how many regs pushed. */ \
+ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
+ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
+ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
+ \
+ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
+ \
+ DEBUG_POP (&failure_id); \
+ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
+ \
+ /* If the saved string location is NULL, it came from an \
+ on_failure_keep_string_jump opcode, and we want to throw away the \
+ saved NULL, thus retaining our current position in the string. */ \
+ string_temp = POP_FAILURE_POINTER (); \
+ if (string_temp != NULL) \
+ str = (const char *) string_temp; \
+ \
+ DEBUG_PRINT2 (" Popping string %p: `", str); \
+ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ \
+ pat = (unsigned char *) POP_FAILURE_POINTER (); \
+ DEBUG_PRINT2 (" Popping pattern %p:\n", pat); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
+ \
+ /* Restore register info. */ \
+ high_reg = (active_reg_t) POP_FAILURE_INT (); \
+ DEBUG_PRINT2 (" Popping high active reg: %ld\n", high_reg); \
+ \
+ low_reg = (active_reg_t) POP_FAILURE_INT (); \
+ DEBUG_PRINT2 (" Popping low active reg: %ld\n", low_reg); \
+ \
+ if (1) \
+ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
+ { \
+ DEBUG_PRINT2 (" Popping reg: %ld\n", this_reg); \
+ \
+ reg_info[this_reg].word = POP_FAILURE_ELT (); \
+ DEBUG_PRINT2 (" info: %p\n", \
+ reg_info[this_reg].word.pointer); \
+ \
+ regend[this_reg] = (const char *) POP_FAILURE_POINTER (); \
+ DEBUG_PRINT2 (" end: %p\n", regend[this_reg]); \
+ \
+ regstart[this_reg] = (const char *) POP_FAILURE_POINTER (); \
+ DEBUG_PRINT2 (" start: %p\n", regstart[this_reg]); \
+ } \
+ else \
+ { \
+ for (this_reg = highest_active_reg; this_reg > high_reg; this_reg--) \
+ { \
+ reg_info[this_reg].word.integer = 0; \
+ regend[this_reg] = 0; \
+ regstart[this_reg] = 0; \
+ } \
+ highest_active_reg = high_reg; \
+ } \
+ \
+ set_regs_matched_done = 0; \
+ DEBUG_STATEMENT (nfailure_points_popped++); \
+} /* POP_FAILURE_POINT */
+
+
+
+/* Structure for per-register (a.k.a. per-group) information.
+ Other register information, such as the
+ starting and ending positions (which are addresses), and the list of
+ inner groups (which is a bits list) are maintained in separate
+ variables.
+
+ We are making a (strictly speaking) nonportable assumption here: that
+ the compiler will pack our bit fields into something that fits into
+ the type of `word', i.e., is something that fits into one item on the
+ failure stack. */
+
+
+/* Declarations and macros for re_match_2. */
+
+typedef union
+{
+ fail_stack_elt_t word;
+ struct
+ {
+ /* This field is one if this group can match the empty string,
+ zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
+#define MATCH_NULL_UNSET_VALUE 3
+ unsigned match_null_string_p : 2;
+ unsigned is_active : 1;
+ unsigned matched_something : 1;
+ unsigned ever_matched_something : 1;
+ } bits;
+} register_info_type;
+
+#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
+#define IS_ACTIVE(R) ((R).bits.is_active)
+#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
+#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
+
+
+/* Call this when have matched a real character; it sets `matched' flags
+ for the subexpressions which we are currently inside. Also records
+ that those subexprs have matched. */
+#define SET_REGS_MATCHED() \
+ do \
+ { \
+ if (!set_regs_matched_done) \
+ { \
+ active_reg_t r; \
+ set_regs_matched_done = 1; \
+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
+ { \
+ MATCHED_SOMETHING (reg_info[r]) \
+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
+ = 1; \
+ } \
+ } \
+ } \
+ while (0)
+
+/* Registers are set to a sentinel when they haven't yet matched. */
+static char reg_unset_dummy;
+#define REG_UNSET_VALUE (&reg_unset_dummy)
+#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
+
+/* Subroutine declarations and macros for regex_compile. */
+
+static reg_errcode_t regex_compile _RE_ARGS ((const char *pattern, size_t size,
+ reg_syntax_t syntax,
+ struct re_pattern_buffer *bufp));
+static void store_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc, int arg));
+static void store_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc,
+ int arg1, int arg2));
+static void insert_op1 _RE_ARGS ((re_opcode_t op, unsigned char *loc,
+ int arg, unsigned char *end));
+static void insert_op2 _RE_ARGS ((re_opcode_t op, unsigned char *loc,
+ int arg1, int arg2, unsigned char *end));
+static boolean at_begline_loc_p _RE_ARGS ((const char *pattern, const char *p,
+ reg_syntax_t syntax));
+static boolean at_endline_loc_p _RE_ARGS ((const char *p, const char *pend,
+ reg_syntax_t syntax));
+static reg_errcode_t compile_range _RE_ARGS ((const char **p_ptr,
+ const char *pend,
+ char *translate,
+ reg_syntax_t syntax,
+ unsigned char *b));
+
+/* Fetch the next character in the uncompiled pattern---translating it
+ if necessary. Also cast from a signed character in the constant
+ string passed to us by the user to an unsigned char that we can use
+ as an array index (in, e.g., `translate'). */
+#ifndef PATFETCH
+# define PATFETCH(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ if (translate) c = (unsigned char) translate[c]; \
+ } while (0)
+#endif
+
+/* Fetch the next character in the uncompiled pattern, with no
+ translation. */
+#define PATFETCH_RAW(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ } while (0)
+
+/* Go backwards one character in the pattern. */
+#define PATUNFETCH p--
+
+
+/* If `translate' is non-null, return translate[D], else just D. We
+ cast the subscript to translate because some data is declared as
+ `char *', to avoid warnings when a string constant is passed. But
+ when we use a character as a subscript we must make it unsigned. */
+#ifndef TRANSLATE
+# define TRANSLATE(d) \
+ (translate ? (char) translate[(unsigned char) (d)] : (d))
+#endif
+
+
+/* Macros for outputting the compiled pattern into `buffer'. */
+
+/* If the buffer isn't allocated when it comes in, use this. */
+#define INIT_BUF_SIZE 32
+
+/* Make sure we have at least N more bytes of space in buffer. */
+#define GET_BUFFER_SPACE(n) \
+ while ((unsigned long) (b - bufp->buffer + (n)) > bufp->allocated) \
+ EXTEND_BUFFER ()
+
+/* Make sure we have one more byte of buffer space and then add C to it. */
+#define BUF_PUSH(c) \
+ do { \
+ GET_BUFFER_SPACE (1); \
+ *b++ = (unsigned char) (c); \
+ } while (0)
+
+
+/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
+#define BUF_PUSH_2(c1, c2) \
+ do { \
+ GET_BUFFER_SPACE (2); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ } while (0)
+
+
+/* As with BUF_PUSH_2, except for three bytes. */
+#define BUF_PUSH_3(c1, c2, c3) \
+ do { \
+ GET_BUFFER_SPACE (3); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ *b++ = (unsigned char) (c3); \
+ } while (0)
+
+
+/* Store a jump with opcode OP at LOC to location TO. We store a
+ relative address offset by the three bytes the jump itself occupies. */
+#define STORE_JUMP(op, loc, to) \
+ store_op1 (op, loc, (int) ((to) - (loc) - 3))
+
+/* Likewise, for a two-argument jump. */
+#define STORE_JUMP2(op, loc, to, arg) \
+ store_op2 (op, loc, (int) ((to) - (loc) - 3), arg)
+
+/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP(op, loc, to) \
+ insert_op1 (op, loc, (int) ((to) - (loc) - 3), b)
+
+/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP2(op, loc, to, arg) \
+ insert_op2 (op, loc, (int) ((to) - (loc) - 3), arg, b)
+
+
+/* This is not an arbitrary limit: the arguments which represent offsets
+ into the pattern are two bytes long. So if 2^16 bytes turns out to
+ be too small, many things would have to change. */
+/* Any other compiler which, like MSC, has allocation limit below 2^16
+ bytes will have to use approach similar to what was done below for
+ MSC and drop MAX_BUF_SIZE a bit. Otherwise you may end up
+ reallocating to 0 bytes. Such thing is not going to work too well.
+ You have been warned!! */
+#if defined _MSC_VER && !defined WIN32
+/* Microsoft C 16-bit versions limit malloc to approx 65512 bytes.
+ The REALLOC define eliminates a flurry of conversion warnings,
+ but is not required. */
+# define MAX_BUF_SIZE 65500L
+# define REALLOC(p,s) realloc ((p), (size_t) (s))
+#else
+# define MAX_BUF_SIZE (1L << 16)
+# define REALLOC(p,s) realloc ((p), (s))
+#endif
+
+/* Extend the buffer by twice its current size via realloc and
+ reset the pointers that pointed into the old block to point to the
+ correct places in the new one. If extending the buffer results in it
+ being larger than MAX_BUF_SIZE, then flag memory exhausted. */
+#define EXTEND_BUFFER() \
+ do { \
+ unsigned char *old_buffer = bufp->buffer; \
+ if (bufp->allocated == MAX_BUF_SIZE) \
+ return REG_ESIZE; \
+ bufp->allocated <<= 1; \
+ if (bufp->allocated > MAX_BUF_SIZE) \
+ bufp->allocated = MAX_BUF_SIZE; \
+ bufp->buffer = (unsigned char *) REALLOC (bufp->buffer, bufp->allocated);\
+ if (bufp->buffer == NULL) \
+ return REG_ESPACE; \
+ /* If the buffer moved, move all the pointers into it. */ \
+ if (old_buffer != bufp->buffer) \
+ { \
+ b = (b - old_buffer) + bufp->buffer; \
+ begalt = (begalt - old_buffer) + bufp->buffer; \
+ if (fixup_alt_jump) \
+ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
+ if (laststart) \
+ laststart = (laststart - old_buffer) + bufp->buffer; \
+ if (pending_exact) \
+ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
+ } \
+ } while (0)
+
+
+/* Since we have one byte reserved for the register number argument to
+ {start,stop}_memory, the maximum number of groups we can report
+ things about is what fits in that byte. */
+#define MAX_REGNUM 255
+
+/* But patterns can have more than `MAX_REGNUM' registers. We just
+ ignore the excess. */
+typedef unsigned regnum_t;
+
+
+/* Macros for the compile stack. */
+
+/* Since offsets can go either forwards or backwards, this type needs to
+ be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
+/* int may be not enough when sizeof(int) == 2. */
+typedef long pattern_offset_t;
+
+typedef struct
+{
+ pattern_offset_t begalt_offset;
+ pattern_offset_t fixup_alt_jump;
+ pattern_offset_t inner_group_offset;
+ pattern_offset_t laststart_offset;
+ regnum_t regnum;
+} compile_stack_elt_t;
+
+
+typedef struct
+{
+ compile_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} compile_stack_type;
+
+
+#define INIT_COMPILE_STACK_SIZE 32
+
+#define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
+#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
+
+/* The next available element. */
+#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
+
+
+/* Set the bit for character C in a list. */
+#define SET_LIST_BIT(c) \
+ (b[((unsigned char) (c)) / BYTEWIDTH] \
+ |= 1 << (((unsigned char) c) % BYTEWIDTH))
+
+
+/* Get the next unsigned number in the uncompiled pattern. */
+#define GET_UNSIGNED_NUMBER(num) \
+ { if (p != pend) \
+ { \
+ PATFETCH (c); \
+ while (ISDIGIT (c)) \
+ { \
+ if (num < 0) \
+ num = 0; \
+ num = num * 10 + c - '0'; \
+ if (p == pend) \
+ break; \
+ PATFETCH (c); \
+ } \
+ } \
+ }
+
+#if defined _LIBC || WIDE_CHAR_SUPPORT
+/* The GNU C library provides support for user-defined character classes
+ and the functions from ISO C amendement 1. */
+# ifdef CHARCLASS_NAME_MAX
+# define CHAR_CLASS_MAX_LENGTH CHARCLASS_NAME_MAX
+# else
+/* This shouldn't happen but some implementation might still have this
+ problem. Use a reasonable default value. */
+# define CHAR_CLASS_MAX_LENGTH 256
+# endif
+
+# ifdef _LIBC
+# define IS_CHAR_CLASS(string) __wctype (string)
+# else
+# define IS_CHAR_CLASS(string) wctype (string)
+# endif
+#else
+# define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
+
+# define IS_CHAR_CLASS(string) \
+ (STREQ (string, "alpha") || STREQ (string, "upper") \
+ || STREQ (string, "lower") || STREQ (string, "digit") \
+ || STREQ (string, "alnum") || STREQ (string, "xdigit") \
+ || STREQ (string, "space") || STREQ (string, "print") \
+ || STREQ (string, "punct") || STREQ (string, "graph") \
+ || STREQ (string, "cntrl") || STREQ (string, "blank"))
+#endif
+
+#ifndef MATCH_MAY_ALLOCATE
+
+/* If we cannot allocate large objects within re_match_2_internal,
+ we make the fail stack and register vectors global.
+ The fail stack, we grow to the maximum size when a regexp
+ is compiled.
+ The register vectors, we adjust in size each time we
+ compile a regexp, according to the number of registers it needs. */
+
+static fail_stack_type fail_stack;
+
+/* Size with which the following vectors are currently allocated.
+ That is so we can make them bigger as needed,
+ but never make them smaller. */
+static int regs_allocated_size;
+
+static const char ** regstart, ** regend;
+static const char ** old_regstart, ** old_regend;
+static const char **best_regstart, **best_regend;
+static register_info_type *reg_info;
+static const char **reg_dummy;
+static register_info_type *reg_info_dummy;
+
+/* Make the register vectors big enough for NUM_REGS registers,
+ but don't make them smaller. */
+
+static
+regex_grow_registers (num_regs)
+ int num_regs;
+{
+ if (num_regs > regs_allocated_size)
+ {
+ RETALLOC_IF (regstart, num_regs, const char *);
+ RETALLOC_IF (regend, num_regs, const char *);
+ RETALLOC_IF (old_regstart, num_regs, const char *);
+ RETALLOC_IF (old_regend, num_regs, const char *);
+ RETALLOC_IF (best_regstart, num_regs, const char *);
+ RETALLOC_IF (best_regend, num_regs, const char *);
+ RETALLOC_IF (reg_info, num_regs, register_info_type);
+ RETALLOC_IF (reg_dummy, num_regs, const char *);
+ RETALLOC_IF (reg_info_dummy, num_regs, register_info_type);
+
+ regs_allocated_size = num_regs;
+ }
+}
+
+#endif /* not MATCH_MAY_ALLOCATE */
+
+static boolean group_in_compile_stack _RE_ARGS ((compile_stack_type
+ compile_stack,
+ regnum_t regnum));
+
+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
+ Returns one of error codes defined in `regex.h', or zero for success.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate'
+ fields are set in BUFP on entry.
+
+ If it succeeds, results are put in BUFP (if it returns an error, the
+ contents of BUFP are undefined):
+ `buffer' is the compiled pattern;
+ `syntax' is set to SYNTAX;
+ `used' is set to the length of the compiled pattern;
+ `fastmap_accurate' is zero;
+ `re_nsub' is the number of subexpressions in PATTERN;
+ `not_bol' and `not_eol' are zero;
+
+ The `fastmap' and `newline_anchor' fields are neither
+ examined nor set. */
+
+/* Return, freeing storage we allocated. */
+#define FREE_STACK_RETURN(value) \
+ return (free (compile_stack.stack), value)
+
+static reg_errcode_t
+regex_compile (pattern, size, syntax, bufp)
+ const char *pattern;
+ size_t size;
+ reg_syntax_t syntax;
+ struct re_pattern_buffer *bufp;
+{
+ /* We fetch characters from PATTERN here. Even though PATTERN is
+ `char *' (i.e., signed), we declare these variables as unsigned, so
+ they can be reliably used as array indices. */
+ register unsigned char c, c1;
+
+ /* A random temporary spot in PATTERN. */
+ const char *p1;
+
+ /* Points to the end of the buffer, where we should append. */
+ register unsigned char *b;
+
+ /* Keeps track of unclosed groups. */
+ compile_stack_type compile_stack;
+
+ /* Points to the current (ending) position in the pattern. */
+ const char *p = pattern;
+ const char *pend = pattern + size;
+
+ /* How to translate the characters in the pattern. */
+ RE_TRANSLATE_TYPE translate = bufp->translate;
+
+ /* Address of the count-byte of the most recently inserted `exactn'
+ command. This makes it possible to tell if a new exact-match
+ character can be added to that command or if the character requires
+ a new `exactn' command. */
+ unsigned char *pending_exact = 0;
+
+ /* Address of start of the most recently finished expression.
+ This tells, e.g., postfix * where to find the start of its
+ operand. Reset at the beginning of groups and alternatives. */
+ unsigned char *laststart = 0;
+
+ /* Address of beginning of regexp, or inside of last group. */
+ unsigned char *begalt;
+
+ /* Place in the uncompiled pattern (i.e., the {) to
+ which to go back if the interval is invalid. */
+ const char *beg_interval;
+
+ /* Address of the place where a forward jump should go to the end of
+ the containing expression. Each alternative of an `or' -- except the
+ last -- ends with a forward jump of this sort. */
+ unsigned char *fixup_alt_jump = 0;
+
+ /* Counts open-groups as they are encountered. Remembered for the
+ matching close-group on the compile stack, so the same register
+ number is put in the stop_memory as the start_memory. */
+ regnum_t regnum = 0;
+
+#ifdef DEBUG
+ DEBUG_PRINT1 ("\nCompiling pattern: ");
+ if (debug)
+ {
+ unsigned debug_count;
+
+ for (debug_count = 0; debug_count < size; debug_count++)
+ putchar (pattern[debug_count]);
+ putchar ('\n');
+ }
+#endif /* DEBUG */
+
+ /* Initialize the compile stack. */
+ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
+ if (compile_stack.stack == NULL)
+ return REG_ESPACE;
+
+ compile_stack.size = INIT_COMPILE_STACK_SIZE;
+ compile_stack.avail = 0;
+
+ /* Initialize the pattern buffer. */
+ bufp->syntax = syntax;
+ bufp->fastmap_accurate = 0;
+ bufp->not_bol = bufp->not_eol = 0;
+
+ /* Set `used' to zero, so that if we return an error, the pattern
+ printer (for debugging) will think there's no pattern. We reset it
+ at the end. */
+ bufp->used = 0;
+
+ /* Always count groups, whether or not bufp->no_sub is set. */
+ bufp->re_nsub = 0;
+
+#if !defined emacs && !defined SYNTAX_TABLE
+ /* Initialize the syntax table. */
+ init_syntax_once ();
+#endif
+
+ if (bufp->allocated == 0)
+ {
+ if (bufp->buffer)
+ { /* If zero allocated, but buffer is non-null, try to realloc
+ enough space. This loses if buffer's address is bogus, but
+ that is the user's responsibility. */
+ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
+ }
+ else
+ { /* Caller did not allocate a buffer. Do it for them. */
+ bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
+ }
+ if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE);
+
+ bufp->allocated = INIT_BUF_SIZE;
+ }
+
+ begalt = b = bufp->buffer;
+
+ /* Loop through the uncompiled pattern until we're at the end. */
+ while (p != pend)
+ {
+ PATFETCH (c);
+
+ switch (c)
+ {
+ case '^':
+ {
+ if ( /* If at start of pattern, it's an operator. */
+ p == pattern + 1
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's come before. */
+ || at_begline_loc_p (pattern, p, syntax))
+ BUF_PUSH (begline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '$':
+ {
+ if ( /* If at end of pattern, it's an operator. */
+ p == pend
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's next. */
+ || at_endline_loc_p (p, pend, syntax))
+ BUF_PUSH (endline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '+':
+ case '?':
+ if ((syntax & RE_BK_PLUS_QM)
+ || (syntax & RE_LIMITED_OPS))
+ goto normal_char;
+ handle_plus:
+ case '*':
+ /* If there is no previous pattern... */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ FREE_STACK_RETURN (REG_BADRPT);
+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ }
+
+ {
+ /* Are we optimizing this jump? */
+ boolean keep_string_p = false;
+
+ /* 1 means zero (many) matches is allowed. */
+ char zero_times_ok = 0, many_times_ok = 0;
+
+ /* If there is a sequence of repetition chars, collapse it
+ down to just one (the right one). We can't combine
+ interval operators with these because of, e.g., `a{2}*',
+ which should only match an even number of `a's. */
+
+ for (;;)
+ {
+ zero_times_ok |= c != '+';
+ many_times_ok |= c != '?';
+
+ if (p == pend)
+ break;
+
+ PATFETCH (c);
+
+ if (c == '*'
+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
+ ;
+
+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ PATFETCH (c1);
+ if (!(c1 == '+' || c1 == '?'))
+ {
+ PATUNFETCH;
+ PATUNFETCH;
+ break;
+ }
+
+ c = c1;
+ }
+ else
+ {
+ PATUNFETCH;
+ break;
+ }
+
+ /* If we get here, we found another repeat character. */
+ }
+
+ /* Star, etc. applied to an empty pattern is equivalent
+ to an empty pattern. */
+ if (!laststart)
+ break;
+
+ /* Now we know whether or not zero matches is allowed
+ and also whether or not two or more matches is allowed. */
+ if (many_times_ok)
+ { /* More than one repetition is allowed, so put in at the
+ end a backward relative jump from `b' to before the next
+ jump we're going to put in below (which jumps from
+ laststart to after this jump).
+
+ But if we are at the `*' in the exact sequence `.*\n',
+ insert an unconditional jump backwards to the .,
+ instead of the beginning of the loop. This way we only
+ push a failure point once, instead of every time
+ through the loop. */
+ assert (p - 1 > pattern);
+
+ /* Allocate the space for the jump. */
+ GET_BUFFER_SPACE (3);
+
+ /* We know we are not at the first character of the pattern,
+ because laststart was nonzero. And we've already
+ incremented `p', by the way, to be the character after
+ the `*'. Do we have to do something analogous here
+ for null bytes, because of RE_DOT_NOT_NULL? */
+ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
+ && zero_times_ok
+ && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
+ && !(syntax & RE_DOT_NEWLINE))
+ { /* We have .*\n. */
+ STORE_JUMP (jump, b, laststart);
+ keep_string_p = true;
+ }
+ else
+ /* Anything else. */
+ STORE_JUMP (maybe_pop_jump, b, laststart - 3);
+
+ /* We've added more stuff to the buffer. */
+ b += 3;
+ }
+
+ /* On failure, jump from laststart to b + 3, which will be the
+ end of the buffer after this jump is inserted. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
+ : on_failure_jump,
+ laststart, b + 3);
+ pending_exact = 0;
+ b += 3;
+
+ if (!zero_times_ok)
+ {
+ /* At least one repetition is required, so insert a
+ `dummy_failure_jump' before the initial
+ `on_failure_jump' instruction of the loop. This
+ effects a skip over that instruction the first time
+ we hit that loop. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
+ b += 3;
+ }
+ }
+ break;
+
+
+ case '.':
+ laststart = b;
+ BUF_PUSH (anychar);
+ break;
+
+
+ case '[':
+ {
+ boolean had_char_class = false;
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ /* Ensure that we have enough space to push a charset: the
+ opcode, the length count, and the bitset; 34 bytes in all. */
+ GET_BUFFER_SPACE (34);
+
+ laststart = b;
+
+ /* We test `*p == '^' twice, instead of using an if
+ statement, so we only need one BUF_PUSH. */
+ BUF_PUSH (*p == '^' ? charset_not : charset);
+ if (*p == '^')
+ p++;
+
+ /* Remember the first position in the bracket expression. */
+ p1 = p;
+
+ /* Push the number of bytes in the bitmap. */
+ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* Clear the whole map. */
+ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* charset_not matches newline according to a syntax bit. */
+ if ((re_opcode_t) b[-2] == charset_not
+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
+ SET_LIST_BIT ('\n');
+
+ /* Read in characters and ranges, setting map bits. */
+ for (;;)
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ PATFETCH (c);
+
+ /* \ might escape characters inside [...] and [^...]. */
+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ PATFETCH (c1);
+ SET_LIST_BIT (c1);
+ continue;
+ }
+
+ /* Could be the end of the bracket expression. If it's
+ not (i.e., when the bracket expression is `[]' so
+ far), the ']' character bit gets set way below. */
+ if (c == ']' && p != p1 + 1)
+ break;
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character class. */
+ if (had_char_class && c == '-' && *p != ']')
+ FREE_STACK_RETURN (REG_ERANGE);
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character: if this is a hyphen not at the
+ beginning or the end of a list, then it's the range
+ operator. */
+ if (c == '-'
+ && !(p - 2 >= pattern && p[-2] == '[')
+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
+ && *p != ']')
+ {
+ reg_errcode_t ret
+ = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
+ }
+
+ else if (p[0] == '-' && p[1] != ']')
+ { /* This handles ranges made up of characters only. */
+ reg_errcode_t ret;
+
+ /* Move past the `-'. */
+ PATFETCH (c1);
+
+ ret = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
+ }
+
+ /* See if we're at the beginning of a possible character
+ class. */
+
+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
+ { /* Leave room for the null. */
+ char str[CHAR_CLASS_MAX_LENGTH + 1];
+
+ PATFETCH (c);
+ c1 = 0;
+
+ /* If pattern is `[[:'. */
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (;;)
+ {
+ PATFETCH (c);
+ if ((c == ':' && *p == ']') || p == pend)
+ break;
+ if (c1 < CHAR_CLASS_MAX_LENGTH)
+ str[c1++] = c;
+ else
+ /* This is in any case an invalid class name. */
+ str[0] = '\0';
+ }
+ str[c1] = '\0';
+
+ /* If isn't a word bracketed by `[:' and `:]':
+ undo the ending character, the letters, and leave
+ the leading `:' and `[' (but set bits for them). */
+ if (c == ':' && *p == ']')
+ {
+#if defined _LIBC || WIDE_CHAR_SUPPORT
+ boolean is_lower = STREQ (str, "lower");
+ boolean is_upper = STREQ (str, "upper");
+ wctype_t wt;
+ int ch;
+
+ wt = IS_CHAR_CLASS (str);
+ if (wt == 0)
+ FREE_STACK_RETURN (REG_ECTYPE);
+
+ /* Throw away the ] at the end of the character
+ class. */
+ PATFETCH (c);
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (ch = 0; ch < 1 << BYTEWIDTH; ++ch)
+ {
+# ifdef _LIBC
+ if (__iswctype (__btowc (ch), wt))
+ SET_LIST_BIT (ch);
+# else
+ if (iswctype (btowc (ch), wt))
+ SET_LIST_BIT (ch);
+# endif
+
+ if (translate && (is_upper || is_lower)
+ && (ISUPPER (ch) || ISLOWER (ch)))
+ SET_LIST_BIT (ch);
+ }
+
+ had_char_class = true;
+#else
+ int ch;
+ boolean is_alnum = STREQ (str, "alnum");
+ boolean is_alpha = STREQ (str, "alpha");
+ boolean is_blank = STREQ (str, "blank");
+ boolean is_cntrl = STREQ (str, "cntrl");
+ boolean is_digit = STREQ (str, "digit");
+ boolean is_graph = STREQ (str, "graph");
+ boolean is_lower = STREQ (str, "lower");
+ boolean is_print = STREQ (str, "print");
+ boolean is_punct = STREQ (str, "punct");
+ boolean is_space = STREQ (str, "space");
+ boolean is_upper = STREQ (str, "upper");
+ boolean is_xdigit = STREQ (str, "xdigit");
+
+ if (!IS_CHAR_CLASS (str))
+ FREE_STACK_RETURN (REG_ECTYPE);
+
+ /* Throw away the ] at the end of the character
+ class. */
+ PATFETCH (c);
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
+ {
+ /* This was split into 3 if's to
+ avoid an arbitrary limit in some compiler. */
+ if ( (is_alnum && ISALNUM (ch))
+ || (is_alpha && ISALPHA (ch))
+ || (is_blank && ISBLANK (ch))
+ || (is_cntrl && ISCNTRL (ch)))
+ SET_LIST_BIT (ch);
+ if ( (is_digit && ISDIGIT (ch))
+ || (is_graph && ISGRAPH (ch))
+ || (is_lower && ISLOWER (ch))
+ || (is_print && ISPRINT (ch)))
+ SET_LIST_BIT (ch);
+ if ( (is_punct && ISPUNCT (ch))
+ || (is_space && ISSPACE (ch))
+ || (is_upper && ISUPPER (ch))
+ || (is_xdigit && ISXDIGIT (ch)))
+ SET_LIST_BIT (ch);
+ if ( translate && (is_upper || is_lower)
+ && (ISUPPER (ch) || ISLOWER (ch)))
+ SET_LIST_BIT (ch);
+ }
+ had_char_class = true;
+#endif /* libc || wctype.h */
+ }
+ else
+ {
+ c1++;
+ while (c1--)
+ PATUNFETCH;
+ SET_LIST_BIT ('[');
+ SET_LIST_BIT (':');
+ had_char_class = false;
+ }
+ }
+ else
+ {
+ had_char_class = false;
+ SET_LIST_BIT (c);
+ }
+ }
+
+ /* Discard any (non)matching list bytes that are all 0 at the
+ end of the map. Decrease the map-length byte too. */
+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+ b[-1]--;
+ b += b[-1];
+ }
+ break;
+
+
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_open;
+ else
+ goto normal_char;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_close;
+ else
+ goto normal_char;
+
+
+ case '\n':
+ if (syntax & RE_NEWLINE_ALT)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '|':
+ if (syntax & RE_NO_BK_VBAR)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '{':
+ if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
+ goto handle_interval;
+ else
+ goto normal_char;
+
+
+ case '\\':
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ /* Do not translate the character after the \, so that we can
+ distinguish, e.g., \B from \b, even if we normally would
+ translate, e.g., B to b. */
+ PATFETCH_RAW (c);
+
+ switch (c)
+ {
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto normal_backslash;
+
+ handle_open:
+ bufp->re_nsub++;
+ regnum++;
+
+ if (COMPILE_STACK_FULL)
+ {
+ RETALLOC (compile_stack.stack, compile_stack.size << 1,
+ compile_stack_elt_t);
+ if (compile_stack.stack == NULL) return REG_ESPACE;
+
+ compile_stack.size <<= 1;
+ }
+
+ /* These are the values to restore when we hit end of this
+ group. They are all relative offsets, so that if the
+ whole pattern moves because of realloc, they will still
+ be valid. */
+ COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
+ COMPILE_STACK_TOP.fixup_alt_jump
+ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
+ COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
+ COMPILE_STACK_TOP.regnum = regnum;
+
+ /* We will eventually replace the 0 with the number of
+ groups inner to this one. But do not push a
+ start_memory for groups beyond the last one we can
+ represent in the compiled pattern. */
+ if (regnum <= MAX_REGNUM)
+ {
+ COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
+ BUF_PUSH_3 (start_memory, regnum, 0);
+ }
+
+ compile_stack.avail++;
+
+ fixup_alt_jump = 0;
+ laststart = 0;
+ begalt = b;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+ break;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
+
+ if (COMPILE_STACK_EMPTY)
+ {
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_backslash;
+ else
+ FREE_STACK_RETURN (REG_ERPAREN);
+ }
+
+ handle_close:
+ if (fixup_alt_jump)
+ { /* Push a dummy failure point at the end of the
+ alternative for a possible future
+ `pop_failure_jump' to pop. See comments at
+ `push_dummy_failure' in `re_match_2'. */
+ BUF_PUSH (push_dummy_failure);
+
+ /* We allocated space for this jump when we assigned
+ to `fixup_alt_jump', in the `handle_alt' case below. */
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
+ }
+
+ /* See similar code for backslashed left paren above. */
+ if (COMPILE_STACK_EMPTY)
+ {
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_char;
+ else
+ FREE_STACK_RETURN (REG_ERPAREN);
+ }
+
+ /* Since we just checked for an empty stack above, this
+ ``can't happen''. */
+ assert (compile_stack.avail != 0);
+ {
+ /* We don't just want to restore into `regnum', because
+ later groups should continue to be numbered higher,
+ as in `(ab)c(de)' -- the second group is #2. */
+ regnum_t this_group_regnum;
+
+ compile_stack.avail--;
+ begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
+ fixup_alt_jump
+ = COMPILE_STACK_TOP.fixup_alt_jump
+ ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
+ : 0;
+ laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
+ this_group_regnum = COMPILE_STACK_TOP.regnum;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+
+ /* We're at the end of the group, so now we know how many
+ groups were inside this one. */
+ if (this_group_regnum <= MAX_REGNUM)
+ {
+ unsigned char *inner_group_loc
+ = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
+
+ *inner_group_loc = regnum - this_group_regnum;
+ BUF_PUSH_3 (stop_memory, this_group_regnum,
+ regnum - this_group_regnum);
+ }
+ }
+ break;
+
+
+ case '|': /* `\|'. */
+ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
+ goto normal_backslash;
+ handle_alt:
+ if (syntax & RE_LIMITED_OPS)
+ goto normal_char;
+
+ /* Insert before the previous alternative a jump which
+ jumps to this alternative if the former fails. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (on_failure_jump, begalt, b + 6);
+ pending_exact = 0;
+ b += 3;
+
+ /* The alternative before this one has a jump after it
+ which gets executed if it gets matched. Adjust that
+ jump so it will jump to this alternative's analogous
+ jump (put in below, which in turn will jump to the next
+ (if any) alternative's such jump, etc.). The last such
+ jump jumps to the correct final destination. A picture:
+ _____ _____
+ | | | |
+ | v | v
+ a | b | c
+
+ If we are at `b', then fixup_alt_jump right now points to a
+ three-byte space after `a'. We'll put in the jump, set
+ fixup_alt_jump to right after `b', and leave behind three
+ bytes which we'll fill in when we get to after `c'. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ /* Mark and leave space for a jump after this alternative,
+ to be filled in later either by next alternative or
+ when know we're at the end of a series of alternatives. */
+ fixup_alt_jump = b;
+ GET_BUFFER_SPACE (3);
+ b += 3;
+
+ laststart = 0;
+ begalt = b;
+ break;
+
+
+ case '{':
+ /* If \{ is a literal. */
+ if (!(syntax & RE_INTERVALS)
+ /* If we're at `\{' and it's not the open-interval
+ operator. */
+ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+ || (p - 2 == pattern && p == pend))
+ goto normal_backslash;
+
+ handle_interval:
+ {
+ /* If got here, then the syntax allows intervals. */
+
+ /* At least (most) this many matches must be made. */
+ int lower_bound = -1, upper_bound = -1;
+
+ beg_interval = p - 1;
+
+ if (p == pend)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_EBRACE);
+ }
+
+ GET_UNSIGNED_NUMBER (lower_bound);
+
+ if (c == ',')
+ {
+ GET_UNSIGNED_NUMBER (upper_bound);
+ if (upper_bound < 0) upper_bound = RE_DUP_MAX;
+ }
+ else
+ /* Interval such as `{1}' => match exactly once. */
+ upper_bound = lower_bound;
+
+ if (lower_bound < 0 || upper_bound > RE_DUP_MAX
+ || lower_bound > upper_bound)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_BADBR);
+ }
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (c != '\\') FREE_STACK_RETURN (REG_EBRACE);
+
+ PATFETCH (c);
+ }
+
+ if (c != '}')
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_BADBR);
+ }
+
+ /* We just parsed a valid interval. */
+
+ /* If it's invalid to have no preceding re. */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ FREE_STACK_RETURN (REG_BADRPT);
+ else if (syntax & RE_CONTEXT_INDEP_OPS)
+ laststart = b;
+ else
+ goto unfetch_interval;
+ }
+
+ /* If the upper bound is zero, don't want to succeed at
+ all; jump from `laststart' to `b + 3', which will be
+ the end of the buffer after we insert the jump. */
+ if (upper_bound == 0)
+ {
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (jump, laststart, b + 3);
+ b += 3;
+ }
+
+ /* Otherwise, we have a nontrivial interval. When
+ we're all done, the pattern will look like:
+ set_number_at <jump count> <upper bound>
+ set_number_at <succeed_n count> <lower bound>
+ succeed_n <after jump addr> <succeed_n count>
+ <body of loop>
+ jump_n <succeed_n addr> <jump count>
+ (The upper bound and `jump_n' are omitted if
+ `upper_bound' is 1, though.) */
+ else
+ { /* If the upper bound is > 1, we need to insert
+ more at the end of the loop. */
+ unsigned nbytes = 10 + (upper_bound > 1) * 10;
+
+ GET_BUFFER_SPACE (nbytes);
+
+ /* Initialize lower bound of the `succeed_n', even
+ though it will be set during matching by its
+ attendant `set_number_at' (inserted next),
+ because `re_compile_fastmap' needs to know.
+ Jump to the `jump_n' we might insert below. */
+ INSERT_JUMP2 (succeed_n, laststart,
+ b + 5 + (upper_bound > 1) * 5,
+ lower_bound);
+ b += 5;
+
+ /* Code to initialize the lower bound. Insert
+ before the `succeed_n'. The `5' is the last two
+ bytes of this `set_number_at', plus 3 bytes of
+ the following `succeed_n'. */
+ insert_op2 (set_number_at, laststart, 5, lower_bound, b);
+ b += 5;
+
+ if (upper_bound > 1)
+ { /* More than one repetition is allowed, so
+ append a backward jump to the `succeed_n'
+ that starts this interval.
+
+ When we've reached this during matching,
+ we'll have matched the interval once, so
+ jump back only `upper_bound - 1' times. */
+ STORE_JUMP2 (jump_n, b, laststart + 5,
+ upper_bound - 1);
+ b += 5;
+
+ /* The location we want to set is the second
+ parameter of the `jump_n'; that is `b-2' as
+ an absolute address. `laststart' will be
+ the `set_number_at' we're about to insert;
+ `laststart+3' the number to set, the source
+ for the relative address. But we are
+ inserting into the middle of the pattern --
+ so everything is getting moved up by 5.
+ Conclusion: (b - 2) - (laststart + 3) + 5,
+ i.e., b - laststart.
+
+ We insert this at the beginning of the loop
+ so that if we fail during matching, we'll
+ reinitialize the bounds. */
+ insert_op2 (set_number_at, laststart, b - laststart,
+ upper_bound - 1, b);
+ b += 5;
+ }
+ }
+ pending_exact = 0;
+ beg_interval = NULL;
+ }
+ break;
+
+ unfetch_interval:
+ /* If an invalid interval, match the characters as literals. */
+ assert (beg_interval);
+ p = beg_interval;
+ beg_interval = NULL;
+
+ /* normal_char and normal_backslash need `c'. */
+ PATFETCH (c);
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (p > pattern && p[-1] == '\\')
+ goto normal_backslash;
+ }
+ goto normal_char;
+
+#ifdef emacs
+ /* There is no way to specify the before_dot and after_dot
+ operators. rms says this is ok. --karl */
+ case '=':
+ BUF_PUSH (at_dot);
+ break;
+
+ case 's':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
+ break;
+
+ case 'S':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
+ break;
+#endif /* emacs */
+
+
+ case 'w':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ laststart = b;
+ BUF_PUSH (wordchar);
+ break;
+
+
+ case 'W':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ laststart = b;
+ BUF_PUSH (notwordchar);
+ break;
+
+
+ case '<':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (wordbeg);
+ break;
+
+ case '>':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (wordend);
+ break;
+
+ case 'b':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (wordbound);
+ break;
+
+ case 'B':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (notwordbound);
+ break;
+
+ case '`':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (begbuf);
+ break;
+
+ case '\'':
+ if (syntax & RE_NO_GNU_OPS)
+ goto normal_char;
+ BUF_PUSH (endbuf);
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ if (syntax & RE_NO_BK_REFS)
+ goto normal_char;
+
+ c1 = c - '0';
+
+ if (c1 > regnum)
+ FREE_STACK_RETURN (REG_ESUBREG);
+
+ /* Can't back reference to a subexpression if inside of it. */
+ if (group_in_compile_stack (compile_stack, (regnum_t) c1))
+ goto normal_char;
+
+ laststart = b;
+ BUF_PUSH_2 (duplicate, c1);
+ break;
+
+
+ case '+':
+ case '?':
+ if (syntax & RE_BK_PLUS_QM)
+ goto handle_plus;
+ else
+ goto normal_backslash;
+
+ default:
+ normal_backslash:
+ /* You might think it would be useful for \ to mean
+ not to translate; but if we don't translate it
+ it will never match anything. */
+ c = TRANSLATE (c);
+ goto normal_char;
+ }
+ break;
+
+
+ default:
+ /* Expects the character in `c'. */
+ normal_char:
+ /* If no exactn currently being built. */
+ if (!pending_exact
+
+ /* If last exactn not at current position. */
+ || pending_exact + *pending_exact + 1 != b
+
+ /* We have only one byte following the exactn for the count. */
+ || *pending_exact == (1 << BYTEWIDTH) - 1
+
+ /* If followed by a repetition operator. */
+ || *p == '*' || *p == '^'
+ || ((syntax & RE_BK_PLUS_QM)
+ ? *p == '\\' && (p[1] == '+' || p[1] == '?')
+ : (*p == '+' || *p == '?'))
+ || ((syntax & RE_INTERVALS)
+ && ((syntax & RE_NO_BK_BRACES)
+ ? *p == '{'
+ : (p[0] == '\\' && p[1] == '{'))))
+ {
+ /* Start building a new exactn. */
+
+ laststart = b;
+
+ BUF_PUSH_2 (exactn, 0);
+ pending_exact = b - 1;
+ }
+
+ BUF_PUSH (c);
+ (*pending_exact)++;
+ break;
+ } /* switch (c) */
+ } /* while p != pend */
+
+
+ /* Through the pattern now. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ if (!COMPILE_STACK_EMPTY)
+ FREE_STACK_RETURN (REG_EPAREN);
+
+ /* If we don't want backtracking, force success
+ the first time we reach the end of the compiled pattern. */
+ if (syntax & RE_NO_POSIX_BACKTRACKING)
+ BUF_PUSH (succeed);
+
+ free (compile_stack.stack);
+
+ /* We have succeeded; set the length of the buffer. */
+ bufp->used = b - bufp->buffer;
+
+#ifdef DEBUG
+ if (debug)
+ {
+ DEBUG_PRINT1 ("\nCompiled pattern: \n");
+ print_compiled_pattern (bufp);
+ }
+#endif /* DEBUG */
+
+#ifndef MATCH_MAY_ALLOCATE
+ /* Initialize the failure stack to the largest possible stack. This
+ isn't necessary unless we're trying to avoid calling alloca in
+ the search and match routines. */
+ {
+ int num_regs = bufp->re_nsub + 1;
+
+ /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
+ is strictly greater than re_max_failures, the largest possible stack
+ is 2 * re_max_failures failure points. */
+ if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
+ {
+ fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
+
+# ifdef emacs
+ if (! fail_stack.stack)
+ fail_stack.stack
+ = (fail_stack_elt_t *) xmalloc (fail_stack.size
+ * sizeof (fail_stack_elt_t));
+ else
+ fail_stack.stack
+ = (fail_stack_elt_t *) xrealloc (fail_stack.stack,
+ (fail_stack.size
+ * sizeof (fail_stack_elt_t)));
+# else /* not emacs */
+ if (! fail_stack.stack)
+ fail_stack.stack
+ = (fail_stack_elt_t *) malloc (fail_stack.size
+ * sizeof (fail_stack_elt_t));
+ else
+ fail_stack.stack
+ = (fail_stack_elt_t *) realloc (fail_stack.stack,
+ (fail_stack.size
+ * sizeof (fail_stack_elt_t)));
+# endif /* not emacs */
+ }
+
+ regex_grow_registers (num_regs);
+ }
+#endif /* not MATCH_MAY_ALLOCATE */
+
+ return REG_NOERROR;
+} /* regex_compile */
+
+/* Subroutines for `regex_compile'. */
+
+/* Store OP at LOC followed by two-byte integer parameter ARG. */
+
+static void
+store_op1 (op, loc, arg)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg);
+}
+
+
+/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+store_op2 (op, loc, arg1, arg2)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg1);
+ STORE_NUMBER (loc + 3, arg2);
+}
+
+
+/* Copy the bytes from LOC to END to open up three bytes of space at LOC
+ for OP followed by two-byte integer parameter ARG. */
+
+static void
+insert_op1 (op, loc, arg, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 3;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op1 (op, loc, arg);
+}
+
+
+/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+insert_op2 (op, loc, arg1, arg2, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 5;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op2 (op, loc, arg1, arg2);
+}
+
+
+/* P points to just after a ^ in PATTERN. Return true if that ^ comes
+ after an alternative or a begin-subexpression. We assume there is at
+ least one character before the ^. */
+
+static boolean
+at_begline_loc_p (pattern, p, syntax)
+ const char *pattern, *p;
+ reg_syntax_t syntax;
+{
+ const char *prev = p - 2;
+ boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
+
+ return
+ /* After a subexpression? */
+ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
+ /* After an alternative? */
+ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
+}
+
+
+/* The dual of at_begline_loc_p. This one is for $. We assume there is
+ at least one character after the $, i.e., `P < PEND'. */
+
+static boolean
+at_endline_loc_p (p, pend, syntax)
+ const char *p, *pend;
+ reg_syntax_t syntax;
+{
+ const char *next = p;
+ boolean next_backslash = *next == '\\';
+ const char *next_next = p + 1 < pend ? p + 1 : 0;
+
+ return
+ /* Before a subexpression? */
+ (syntax & RE_NO_BK_PARENS ? *next == ')'
+ : next_backslash && next_next && *next_next == ')')
+ /* Before an alternative? */
+ || (syntax & RE_NO_BK_VBAR ? *next == '|'
+ : next_backslash && next_next && *next_next == '|');
+}
+
+
+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
+ false if it's not. */
+
+static boolean
+group_in_compile_stack (compile_stack, regnum)
+ compile_stack_type compile_stack;
+ regnum_t regnum;
+{
+ int this_element;
+
+ for (this_element = compile_stack.avail - 1;
+ this_element >= 0;
+ this_element--)
+ if (compile_stack.stack[this_element].regnum == regnum)
+ return true;
+
+ return false;
+}
+
+
+/* Read the ending character of a range (in a bracket expression) from the
+ uncompiled pattern *P_PTR (which ends at PEND). We assume the
+ starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
+ Then we set the translation of all bits between the starting and
+ ending characters (inclusive) in the compiled pattern B.
+
+ Return an error code.
+
+ We use these short variable names so we can use the same macros as
+ `regex_compile' itself. */
+
+static reg_errcode_t
+compile_range (p_ptr, pend, translate, syntax, b)
+ const char **p_ptr, *pend;
+ RE_TRANSLATE_TYPE translate;
+ reg_syntax_t syntax;
+ unsigned char *b;
+{
+ unsigned this_char;
+
+ const char *p = *p_ptr;
+ unsigned int range_start, range_end;
+
+ if (p == pend)
+ return REG_ERANGE;
+
+ /* Even though the pattern is a signed `char *', we need to fetch
+ with unsigned char *'s; if the high bit of the pattern character
+ is set, the range endpoints will be negative if we fetch using a
+ signed char *.
+
+ We also want to fetch the endpoints without translating them; the
+ appropriate translation is done in the bit-setting loop below. */
+ /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *. */
+ range_start = ((const unsigned char *) p)[-2];
+ range_end = ((const unsigned char *) p)[0];
+
+ /* Have to increment the pointer into the pattern string, so the
+ caller isn't still at the ending character. */
+ (*p_ptr)++;
+
+ /* If the start is after the end, the range is empty. */
+ if (range_start > range_end)
+ return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
+
+ /* Here we see why `this_char' has to be larger than an `unsigned
+ char' -- the range is inclusive, so if `range_end' == 0xff
+ (assuming 8-bit characters), we would otherwise go into an infinite
+ loop, since all characters <= 0xff. */
+ for (this_char = range_start; this_char <= range_end; this_char++)
+ {
+ SET_LIST_BIT (TRANSLATE (this_char));
+ }
+
+ return REG_NOERROR;
+}
+
+/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
+ BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
+ characters can start a string that matches the pattern. This fastmap
+ is used by re_search to skip quickly over impossible starting points.
+
+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
+ area as BUFP->fastmap.
+
+ We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
+ the pattern buffer.
+
+ Returns 0 if we succeed, -2 if an internal error. */
+
+int
+re_compile_fastmap (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ int j, k;
+#ifdef MATCH_MAY_ALLOCATE
+ fail_stack_type fail_stack;
+#endif
+#ifndef REGEX_MALLOC
+ char *destination;
+#endif
+
+ register char *fastmap = bufp->fastmap;
+ unsigned char *pattern = bufp->buffer;
+ unsigned char *p = pattern;
+ register unsigned char *pend = pattern + bufp->used;
+
+#ifdef REL_ALLOC
+ /* This holds the pointer to the failure stack, when
+ it is allocated relocatably. */
+ fail_stack_elt_t *failure_stack_ptr;
+#endif
+
+ /* Assume that each path through the pattern can be null until
+ proven otherwise. We set this false at the bottom of switch
+ statement, to which we get only if a particular path doesn't
+ match the empty string. */
+ boolean path_can_be_null = true;
+
+ /* We aren't doing a `succeed_n' to begin with. */
+ boolean succeed_n_p = false;
+
+ assert (fastmap != NULL && p != NULL);
+
+ INIT_FAIL_STACK ();
+ bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
+ bufp->fastmap_accurate = 1; /* It will be when we're done. */
+ bufp->can_be_null = 0;
+
+ while (1)
+ {
+ if (p == pend || *p == succeed)
+ {
+ /* We have reached the (effective) end of pattern. */
+ if (!FAIL_STACK_EMPTY ())
+ {
+ bufp->can_be_null |= path_can_be_null;
+
+ /* Reset for next path. */
+ path_can_be_null = true;
+
+ p = fail_stack.stack[--fail_stack.avail].pointer;
+
+ continue;
+ }
+ else
+ break;
+ }
+
+ /* We should never be about to go beyond the end of the pattern. */
+ assert (p < pend);
+
+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
+ {
+
+ /* I guess the idea here is to simply not bother with a fastmap
+ if a backreference is used, since it's too hard to figure out
+ the fastmap for the corresponding group. Setting
+ `can_be_null' stops `re_search_2' from using the fastmap, so
+ that is all we do. */
+ case duplicate:
+ bufp->can_be_null = 1;
+ goto done;
+
+
+ /* Following are the cases which match a character. These end
+ with `break'. */
+
+ case exactn:
+ fastmap[p[1]] = 1;
+ break;
+
+
+ case charset:
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+ fastmap[j] = 1;
+ break;
+
+
+ case charset_not:
+ /* Chars beyond end of map must be allowed. */
+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+ fastmap[j] = 1;
+ break;
+
+
+ case wordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == Sword)
+ fastmap[j] = 1;
+ break;
+
+
+ case notwordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != Sword)
+ fastmap[j] = 1;
+ break;
+
+
+ case anychar:
+ {
+ int fastmap_newline = fastmap['\n'];
+
+ /* `.' matches anything ... */
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ /* ... except perhaps newline. */
+ if (!(bufp->syntax & RE_DOT_NEWLINE))
+ fastmap['\n'] = fastmap_newline;
+
+ /* Return if we have already set `can_be_null'; if we have,
+ then the fastmap is irrelevant. Something's wrong here. */
+ else if (bufp->can_be_null)
+ goto done;
+
+ /* Otherwise, have to check alternative paths. */
+ break;
+ }
+
+#ifdef emacs
+ case syntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+
+ case notsyntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+
+ /* All cases after this match the empty string. These end with
+ `continue'. */
+
+
+ case before_dot:
+ case at_dot:
+ case after_dot:
+ continue;
+#endif /* emacs */
+
+
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+ case push_dummy_failure:
+ continue;
+
+
+ case jump_n:
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case jump_past_alt:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+ if (j > 0)
+ continue;
+
+ /* Jump backward implies we just went through the body of a
+ loop and matched nothing. Opcode jumped to should be
+ `on_failure_jump' or `succeed_n'. Just treat it like an
+ ordinary jump. For a * loop, it has pushed its failure
+ point already; if so, discard that as redundant. */
+ if ((re_opcode_t) *p != on_failure_jump
+ && (re_opcode_t) *p != succeed_n)
+ continue;
+
+ p++;
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+
+ /* If what's on the stack is where we are now, pop it. */
+ if (!FAIL_STACK_EMPTY ()
+ && fail_stack.stack[fail_stack.avail - 1].pointer == p)
+ fail_stack.avail--;
+
+ continue;
+
+
+ case on_failure_jump:
+ case on_failure_keep_string_jump:
+ handle_on_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+
+ /* For some patterns, e.g., `(a?)?', `p+j' here points to the
+ end of the pattern. We don't want to push such a point,
+ since when we restore it above, entering the switch will
+ increment `p' past the end of the pattern. We don't need
+ to push such a point since we obviously won't find any more
+ fastmap entries beyond `pend'. Such a pattern can match
+ the null string, though. */
+ if (p + j < pend)
+ {
+ if (!PUSH_PATTERN_OP (p + j, fail_stack))
+ {
+ RESET_FAIL_STACK ();
+ return -2;
+ }
+ }
+ else
+ bufp->can_be_null = 1;
+
+ if (succeed_n_p)
+ {
+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
+ succeed_n_p = false;
+ }
+
+ continue;
+
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p += 2;
+
+ /* Increment p past the n for when k != 0. */
+ EXTRACT_NUMBER_AND_INCR (k, p);
+ if (k == 0)
+ {
+ p -= 4;
+ succeed_n_p = true; /* Spaghetti code alert. */
+ goto handle_on_failure_jump;
+ }
+ continue;
+
+
+ case set_number_at:
+ p += 4;
+ continue;
+
+
+ case start_memory:
+ case stop_memory:
+ p += 2;
+ continue;
+
+
+ default:
+ abort (); /* We have listed all the cases. */
+ } /* switch *p++ */
+
+ /* Getting here means we have found the possible starting
+ characters for one path of the pattern -- and that the empty
+ string does not match. We need not follow this path further.
+ Instead, look at the next alternative (remembered on the
+ stack), or quit if no more. The test at the top of the loop
+ does these things. */
+ path_can_be_null = false;
+ p = pend;
+ } /* while p */
+
+ /* Set `can_be_null' for the last path (also the first path, if the
+ pattern is empty). */
+ bufp->can_be_null |= path_can_be_null;
+
+ done:
+ RESET_FAIL_STACK ();
+ return 0;
+} /* re_compile_fastmap */
+#ifdef _LIBC
+weak_alias (__re_compile_fastmap, re_compile_fastmap)
+#endif
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
+ this memory for recording register information. STARTS and ENDS
+ must be allocated using the malloc library routine, and must each
+ be at least NUM_REGS * sizeof (regoff_t) bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+
+void
+re_set_registers (bufp, regs, num_regs, starts, ends)
+ struct re_pattern_buffer *bufp;
+ struct re_registers *regs;
+ unsigned num_regs;
+ regoff_t *starts, *ends;
+{
+ if (num_regs)
+ {
+ bufp->regs_allocated = REGS_REALLOCATE;
+ regs->num_regs = num_regs;
+ regs->start = starts;
+ regs->end = ends;
+ }
+ else
+ {
+ bufp->regs_allocated = REGS_UNALLOCATED;
+ regs->num_regs = 0;
+ regs->start = regs->end = (regoff_t *) 0;
+ }
+}
+#ifdef _LIBC
+weak_alias (__re_set_registers, re_set_registers)
+#endif
+
+/* Searching routines. */
+
+/* Like re_search_2, below, but only one string is specified, and
+ doesn't let you say where to stop matching. */
+
+int
+re_search (bufp, string, size, startpos, range, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, startpos, range;
+ struct re_registers *regs;
+{
+ return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
+ regs, size);
+}
+#ifdef _LIBC
+weak_alias (__re_search, re_search)
+#endif
+
+
+/* Using the compiled pattern in BUFP->buffer, first tries to match the
+ virtual concatenation of STRING1 and STRING2, starting first at index
+ STARTPOS, then at STARTPOS + 1, and so on.
+
+ STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
+
+ RANGE is how far to scan while trying to match. RANGE = 0 means try
+ only at STARTPOS; in general, the last start tried is STARTPOS +
+ RANGE.
+
+ In REGS, return the indices of the virtual concatenation of STRING1
+ and STRING2 that matched the entire BUFP->buffer and its contained
+ subexpressions.
+
+ Do not consider matching one past the index STOP in the virtual
+ concatenation of STRING1 and STRING2.
+
+ We return either the position in the strings at which the match was
+ found, -1 if no match, or -2 if error (such as failure
+ stack overflow). */
+
+int
+re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int startpos;
+ int range;
+ struct re_registers *regs;
+ int stop;
+{
+ int val;
+ register char *fastmap = bufp->fastmap;
+ register RE_TRANSLATE_TYPE translate = bufp->translate;
+ int total_size = size1 + size2;
+ int endpos = startpos + range;
+
+ /* Check for out-of-range STARTPOS. */
+ if (startpos < 0 || startpos > total_size)
+ return -1;
+
+ /* Fix up RANGE if it might eventually take us outside
+ the virtual concatenation of STRING1 and STRING2.
+ Make sure we won't move STARTPOS below 0 or above TOTAL_SIZE. */
+ if (endpos < 0)
+ range = 0 - startpos;
+ else if (endpos > total_size)
+ range = total_size - startpos;
+
+ /* If the search isn't to be a backwards one, don't waste time in a
+ search for a pattern that must be anchored. */
+ if (bufp->used > 0 && range > 0
+ && ((re_opcode_t) bufp->buffer[0] == begbuf
+ /* `begline' is like `begbuf' if it cannot match at newlines. */
+ || ((re_opcode_t) bufp->buffer[0] == begline
+ && !bufp->newline_anchor)))
+ {
+ if (startpos > 0)
+ return -1;
+ else
+ range = 1;
+ }
+
+#ifdef emacs
+ /* In a forward search for something that starts with \=.
+ don't keep searching past point. */
+ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == at_dot && range > 0)
+ {
+ range = PT - startpos;
+ if (range <= 0)
+ return -1;
+ }
+#endif /* emacs */
+
+ /* Update the fastmap now if not correct already. */
+ if (fastmap && !bufp->fastmap_accurate)
+ if (re_compile_fastmap (bufp) == -2)
+ return -2;
+
+ /* Loop through the string, looking for a place to start matching. */
+ for (;;)
+ {
+ /* If a fastmap is supplied, skip quickly over characters that
+ cannot be the start of a match. If the pattern can match the
+ null string, however, we don't need to skip characters; we want
+ the first null string. */
+ if (fastmap && startpos < total_size && !bufp->can_be_null)
+ {
+ if (range > 0) /* Searching forwards. */
+ {
+ register const char *d;
+ register int lim = 0;
+ int irange = range;
+
+ if (startpos < size1 && startpos + range >= size1)
+ lim = range - (size1 - startpos);
+
+ d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
+
+ /* Written out as an if-else to avoid testing `translate'
+ inside the loop. */
+ if (translate)
+ while (range > lim
+ && !fastmap[(unsigned char)
+ translate[(unsigned char) *d++]])
+ range--;
+ else
+ while (range > lim && !fastmap[(unsigned char) *d++])
+ range--;
+
+ startpos += irange - range;
+ }
+ else /* Searching backwards. */
+ {
+ register char c = (size1 == 0 || startpos >= size1
+ ? string2[startpos - size1]
+ : string1[startpos]);
+
+ if (!fastmap[(unsigned char) TRANSLATE (c)])
+ goto advance;
+ }
+ }
+
+ /* If can't match the null string, and that's all we have left, fail. */
+ if (range >= 0 && startpos == total_size && fastmap
+ && !bufp->can_be_null)
+ return -1;
+
+ val = re_match_2_internal (bufp, string1, size1, string2, size2,
+ startpos, regs, stop);
+#ifndef REGEX_MALLOC
+# ifdef C_ALLOCA
+ alloca (0);
+# endif
+#endif
+
+ if (val >= 0)
+ return startpos;
+
+ if (val == -2)
+ return -2;
+
+ advance:
+ if (!range)
+ break;
+ else if (range > 0)
+ {
+ range--;
+ startpos++;
+ }
+ else
+ {
+ range++;
+ startpos--;
+ }
+ }
+ return -1;
+} /* re_search_2 */
+#ifdef _LIBC
+weak_alias (__re_search_2, re_search_2)
+#endif
+
+/* This converts PTR, a pointer into one of the search strings `string1'
+ and `string2' into an offset from the beginning of that string. */
+#define POINTER_TO_OFFSET(ptr) \
+ (FIRST_STRING_P (ptr) \
+ ? ((regoff_t) ((ptr) - string1)) \
+ : ((regoff_t) ((ptr) - string2 + size1)))
+
+/* Macros for dealing with the split strings in re_match_2. */
+
+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
+
+/* Call before fetching a character with *d. This switches over to
+ string2 if necessary. */
+#define PREFETCH() \
+ while (d == dend) \
+ { \
+ /* End of string2 => fail. */ \
+ if (dend == end_match_2) \
+ goto fail; \
+ /* End of string1 => advance to string2. */ \
+ d = string2; \
+ dend = end_match_2; \
+ }
+
+
+/* Test if at very beginning or at very end of the virtual concatenation
+ of `string1' and `string2'. If only one string, it's `string2'. */
+#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
+#define AT_STRINGS_END(d) ((d) == end2)
+
+
+/* Test if D points to a character which is word-constituent. We have
+ two special cases to check for: if past the end of string1, look at
+ the first character in string2; and if before the beginning of
+ string2, look at the last character in string1. */
+#define WORDCHAR_P(d) \
+ (SYNTAX ((d) == end1 ? *string2 \
+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
+ == Sword)
+
+/* Disabled due to a compiler bug -- see comment at case wordbound */
+#if 0
+/* Test if the character before D and the one at D differ with respect
+ to being word-constituent. */
+#define AT_WORD_BOUNDARY(d) \
+ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
+ || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
+#endif
+
+/* Free everything we malloc. */
+#ifdef MATCH_MAY_ALLOCATE
+# define FREE_VAR(var) if (var) REGEX_FREE (var); var = NULL
+# define FREE_VARIABLES() \
+ do { \
+ REGEX_FREE_STACK (fail_stack.stack); \
+ FREE_VAR (regstart); \
+ FREE_VAR (regend); \
+ FREE_VAR (old_regstart); \
+ FREE_VAR (old_regend); \
+ FREE_VAR (best_regstart); \
+ FREE_VAR (best_regend); \
+ FREE_VAR (reg_info); \
+ FREE_VAR (reg_dummy); \
+ FREE_VAR (reg_info_dummy); \
+ } while (0)
+#else
+# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */
+#endif /* not MATCH_MAY_ALLOCATE */
+
+/* These values must meet several constraints. They must not be valid
+ register values; since we have a limit of 255 registers (because
+ we use only one byte in the pattern for the register number), we can
+ use numbers larger than 255. They must differ by 1, because of
+ NUM_FAILURE_ITEMS above. And the value for the lowest register must
+ be larger than the value for the highest register, so we do not try
+ to actually save any registers when none are active. */
+#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
+#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
+
+/* Matching routines. */
+
+#ifndef emacs /* Emacs never uses this. */
+/* re_match is like re_match_2 except it takes only a single string. */
+
+int
+re_match (bufp, string, size, pos, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, pos;
+ struct re_registers *regs;
+{
+ int result = re_match_2_internal (bufp, NULL, 0, string, size,
+ pos, regs, size);
+# ifndef REGEX_MALLOC
+# ifdef C_ALLOCA
+ alloca (0);
+# endif
+# endif
+ return result;
+}
+# ifdef _LIBC
+weak_alias (__re_match, re_match)
+# endif
+#endif /* not emacs */
+
+static boolean group_match_null_string_p _RE_ARGS ((unsigned char **p,
+ unsigned char *end,
+ register_info_type *reg_info));
+static boolean alt_match_null_string_p _RE_ARGS ((unsigned char *p,
+ unsigned char *end,
+ register_info_type *reg_info));
+static boolean common_op_match_null_string_p _RE_ARGS ((unsigned char **p,
+ unsigned char *end,
+ register_info_type *reg_info));
+static int bcmp_translate _RE_ARGS ((const char *s1, const char *s2,
+ int len, char *translate));
+
+/* re_match_2 matches the compiled pattern in BUFP against the
+ the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
+ and SIZE2, respectively). We start matching at POS, and stop
+ matching at STOP.
+
+ If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
+ store offsets for the substring each group matched in REGS. See the
+ documentation for exactly how many groups we fill.
+
+ We return -1 if no match, -2 if an internal error (such as the
+ failure stack overflowing). Otherwise, we return the length of the
+ matched substring. */
+
+int
+re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int pos;
+ struct re_registers *regs;
+ int stop;
+{
+ int result = re_match_2_internal (bufp, string1, size1, string2, size2,
+ pos, regs, stop);
+#ifndef REGEX_MALLOC
+# ifdef C_ALLOCA
+ alloca (0);
+# endif
+#endif
+ return result;
+}
+#ifdef _LIBC
+weak_alias (__re_match_2, re_match_2)
+#endif
+
+/* This is a separate function so that we can force an alloca cleanup
+ afterwards. */
+static int
+re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int pos;
+ struct re_registers *regs;
+ int stop;
+{
+ /* General temporaries. */
+ int mcnt;
+ unsigned char *p1;
+
+ /* Just past the end of the corresponding string. */
+ const char *end1, *end2;
+
+ /* Pointers into string1 and string2, just past the last characters in
+ each to consider matching. */
+ const char *end_match_1, *end_match_2;
+
+ /* Where we are in the data, and the end of the current string. */
+ const char *d, *dend;
+
+ /* Where we are in the pattern, and the end of the pattern. */
+ unsigned char *p = bufp->buffer;
+ register unsigned char *pend = p + bufp->used;
+
+ /* Mark the opcode just after a start_memory, so we can test for an
+ empty subpattern when we get to the stop_memory. */
+ unsigned char *just_past_start_mem = 0;
+
+ /* We use this to map every character in the string. */
+ RE_TRANSLATE_TYPE translate = bufp->translate;
+
+ /* Failure point stack. Each place that can handle a failure further
+ down the line pushes a failure point on this stack. It consists of
+ restart, regend, and reg_info for all registers corresponding to
+ the subexpressions we're currently inside, plus the number of such
+ registers, and, finally, two char *'s. The first char * is where
+ to resume scanning the pattern; the second one is where to resume
+ scanning the strings. If the latter is zero, the failure point is
+ a ``dummy''; if a failure happens and the failure point is a dummy,
+ it gets discarded and the next next one is tried. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
+ fail_stack_type fail_stack;
+#endif
+#ifdef DEBUG
+ static unsigned failure_id;
+ unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
+#endif
+
+#ifdef REL_ALLOC
+ /* This holds the pointer to the failure stack, when
+ it is allocated relocatably. */
+ fail_stack_elt_t *failure_stack_ptr;
+#endif
+
+ /* We fill all the registers internally, independent of what we
+ return, for use in backreferences. The number here includes
+ an element for register zero. */
+ size_t num_regs = bufp->re_nsub + 1;
+
+ /* The currently active registers. */
+ active_reg_t lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ active_reg_t highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+
+ /* Information on the contents of registers. These are pointers into
+ the input strings; they record just what was matched (on this
+ attempt) by a subexpression part of the pattern, that is, the
+ regnum-th regstart pointer points to where in the pattern we began
+ matching and the regnum-th regend points to right after where we
+ stopped matching the regnum-th subexpression. (The zeroth register
+ keeps track of what the whole pattern matches.) */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **regstart, **regend;
+#endif
+
+ /* If a group that's operated upon by a repetition operator fails to
+ match anything, then the register for its start will need to be
+ restored because it will have been set to wherever in the string we
+ are when we last see its open-group operator. Similarly for a
+ register's end. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **old_regstart, **old_regend;
+#endif
+
+ /* The is_active field of reg_info helps us keep track of which (possibly
+ nested) subexpressions we are currently in. The matched_something
+ field of reg_info[reg_num] helps us tell whether or not we have
+ matched any of the pattern so far this time through the reg_num-th
+ subexpression. These two fields get reset each time through any
+ loop their register is in. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
+ register_info_type *reg_info;
+#endif
+
+ /* The following record the register info as found in the above
+ variables when we find a match better than any we've seen before.
+ This happens as we backtrack through the failure points, which in
+ turn happens only if we have not yet matched the entire string. */
+ unsigned best_regs_set = false;
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **best_regstart, **best_regend;
+#endif
+
+ /* Logically, this is `best_regend[0]'. But we don't want to have to
+ allocate space for that if we're not allocating space for anything
+ else (see below). Also, we never need info about register 0 for
+ any of the other register vectors, and it seems rather a kludge to
+ treat `best_regend' differently than the rest. So we keep track of
+ the end of the best match so far in a separate variable. We
+ initialize this to NULL so that when we backtrack the first time
+ and need to test it, it's not garbage. */
+ const char *match_end = NULL;
+
+ /* This helps SET_REGS_MATCHED avoid doing redundant work. */
+ int set_regs_matched_done = 0;
+
+ /* Used when we pop values we don't care about. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **reg_dummy;
+ register_info_type *reg_info_dummy;
+#endif
+
+#ifdef DEBUG
+ /* Counts the total number of registers pushed. */
+ unsigned num_regs_pushed = 0;
+#endif
+
+ DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
+
+ INIT_FAIL_STACK ();
+
+#ifdef MATCH_MAY_ALLOCATE
+ /* Do not bother to initialize all the register variables if there are
+ no groups in the pattern, as it takes a fair amount of time. If
+ there are groups, we include space for register 0 (the whole
+ pattern), even though we never use it, since it simplifies the
+ array indexing. We should fix this. */
+ if (bufp->re_nsub)
+ {
+ regstart = REGEX_TALLOC (num_regs, const char *);
+ regend = REGEX_TALLOC (num_regs, const char *);
+ old_regstart = REGEX_TALLOC (num_regs, const char *);
+ old_regend = REGEX_TALLOC (num_regs, const char *);
+ best_regstart = REGEX_TALLOC (num_regs, const char *);
+ best_regend = REGEX_TALLOC (num_regs, const char *);
+ reg_info = REGEX_TALLOC (num_regs, register_info_type);
+ reg_dummy = REGEX_TALLOC (num_regs, const char *);
+ reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
+
+ if (!(regstart && regend && old_regstart && old_regend && reg_info
+ && best_regstart && best_regend && reg_dummy && reg_info_dummy))
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ }
+ else
+ {
+ /* We must initialize all our variables to NULL, so that
+ `FREE_VARIABLES' doesn't try to free them. */
+ regstart = regend = old_regstart = old_regend = best_regstart
+ = best_regend = reg_dummy = NULL;
+ reg_info = reg_info_dummy = (register_info_type *) NULL;
+ }
+#endif /* MATCH_MAY_ALLOCATE */
+
+ /* The starting position is bogus. */
+ if (pos < 0 || pos > size1 + size2)
+ {
+ FREE_VARIABLES ();
+ return -1;
+ }
+
+ /* Initialize subexpression text positions to -1 to mark ones that no
+ start_memory/stop_memory has been seen for. Also initialize the
+ register information struct. */
+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = regend[mcnt]
+ = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
+
+ REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
+ IS_ACTIVE (reg_info[mcnt]) = 0;
+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ }
+
+ /* We move `string1' into `string2' if the latter's empty -- but not if
+ `string1' is null. */
+ if (size2 == 0 && string1 != NULL)
+ {
+ string2 = string1;
+ size2 = size1;
+ string1 = 0;
+ size1 = 0;
+ }
+ end1 = string1 + size1;
+ end2 = string2 + size2;
+
+ /* Compute where to stop matching, within the two strings. */
+ if (stop <= size1)
+ {
+ end_match_1 = string1 + stop;
+ end_match_2 = string2;
+ }
+ else
+ {
+ end_match_1 = end1;
+ end_match_2 = string2 + stop - size1;
+ }
+
+ /* `p' scans through the pattern as `d' scans through the data.
+ `dend' is the end of the input string that `d' points within. `d'
+ is advanced into the following input string whenever necessary, but
+ this happens before fetching; therefore, at the beginning of the
+ loop, `d' can be pointing at the end of a string, but it cannot
+ equal `string2'. */
+ if (size1 > 0 && pos <= size1)
+ {
+ d = string1 + pos;
+ dend = end_match_1;
+ }
+ else
+ {
+ d = string2 + pos - size1;
+ dend = end_match_2;
+ }
+
+ DEBUG_PRINT1 ("The compiled pattern is:\n");
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
+ DEBUG_PRINT1 ("The string to match is: `");
+ DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
+ DEBUG_PRINT1 ("'\n");
+
+ /* This loops over pattern commands. It exits by returning from the
+ function if the match is complete, or it drops through if the match
+ fails at this starting point in the input data. */
+ for (;;)
+ {
+#ifdef _LIBC
+ DEBUG_PRINT2 ("\n%p: ", p);
+#else
+ DEBUG_PRINT2 ("\n0x%x: ", p);
+#endif
+
+ if (p == pend)
+ { /* End of pattern means we might have succeeded. */
+ DEBUG_PRINT1 ("end of pattern ... ");
+
+ /* If we haven't matched the entire string, and we want the
+ longest match, try backtracking. */
+ if (d != end_match_2)
+ {
+ /* 1 if this match ends in the same string (string1 or string2)
+ as the best previous match. */
+ boolean same_str_p = (FIRST_STRING_P (match_end)
+ == MATCHING_IN_FIRST_STRING);
+ /* 1 if this match is the best seen so far. */
+ boolean best_match_p;
+
+ /* AIX compiler got confused when this was combined
+ with the previous declaration. */
+ if (same_str_p)
+ best_match_p = d > match_end;
+ else
+ best_match_p = !MATCHING_IN_FIRST_STRING;
+
+ DEBUG_PRINT1 ("backtracking.\n");
+
+ if (!FAIL_STACK_EMPTY ())
+ { /* More failure points to try. */
+
+ /* If exceeds best match so far, save it. */
+ if (!best_regs_set || best_match_p)
+ {
+ best_regs_set = true;
+ match_end = d;
+
+ DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
+
+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
+ {
+ best_regstart[mcnt] = regstart[mcnt];
+ best_regend[mcnt] = regend[mcnt];
+ }
+ }
+ goto fail;
+ }
+
+ /* If no failure points, don't restore garbage. And if
+ last match is real best match, don't restore second
+ best one. */
+ else if (best_regs_set && !best_match_p)
+ {
+ restore_best_regs:
+ /* Restore best match. It may happen that `dend ==
+ end_match_1' while the restored d is in string2.
+ For example, the pattern `x.*y.*z' against the
+ strings `x-' and `y-z-', if the two strings are
+ not consecutive in memory. */
+ DEBUG_PRINT1 ("Restoring best registers.\n");
+
+ d = match_end;
+ dend = ((d >= string1 && d <= end1)
+ ? end_match_1 : end_match_2);
+
+ for (mcnt = 1; (unsigned) mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = best_regstart[mcnt];
+ regend[mcnt] = best_regend[mcnt];
+ }
+ }
+ } /* d != end_match_2 */
+
+ succeed_label:
+ DEBUG_PRINT1 ("Accepting match.\n");
+
+ /* If caller wants register contents data back, do it. */
+ if (regs && !bufp->no_sub)
+ {
+ /* Have the register data arrays been allocated? */
+ if (bufp->regs_allocated == REGS_UNALLOCATED)
+ { /* No. So allocate them with malloc. We need one
+ extra element beyond `num_regs' for the `-1' marker
+ GNU code uses. */
+ regs->num_regs = MAX (RE_NREGS, num_regs + 1);
+ regs->start = TALLOC (regs->num_regs, regoff_t);
+ regs->end = TALLOC (regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ bufp->regs_allocated = REGS_REALLOCATE;
+ }
+ else if (bufp->regs_allocated == REGS_REALLOCATE)
+ { /* Yes. If we need more elements than were already
+ allocated, reallocate them. If we need fewer, just
+ leave it alone. */
+ if (regs->num_regs < num_regs + 1)
+ {
+ regs->num_regs = num_regs + 1;
+ RETALLOC (regs->start, regs->num_regs, regoff_t);
+ RETALLOC (regs->end, regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ }
+ }
+ else
+ {
+ /* These braces fend off a "empty body in an else-statement"
+ warning under GCC when assert expands to nothing. */
+ assert (bufp->regs_allocated == REGS_FIXED);
+ }
+
+ /* Convert the pointer data in `regstart' and `regend' to
+ indices. Register zero has to be set differently,
+ since we haven't kept track of any info for it. */
+ if (regs->num_regs > 0)
+ {
+ regs->start[0] = pos;
+ regs->end[0] = (MATCHING_IN_FIRST_STRING
+ ? ((regoff_t) (d - string1))
+ : ((regoff_t) (d - string2 + size1)));
+ }
+
+ /* Go through the first `min (num_regs, regs->num_regs)'
+ registers, since that is all we initialized. */
+ for (mcnt = 1; (unsigned) mcnt < MIN (num_regs, regs->num_regs);
+ mcnt++)
+ {
+ if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ else
+ {
+ regs->start[mcnt]
+ = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
+ regs->end[mcnt]
+ = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
+ }
+ }
+
+ /* If the regs structure we return has more elements than
+ were in the pattern, set the extra elements to -1. If
+ we (re)allocated the registers, this is the case,
+ because we always allocate enough to have at least one
+ -1 at the end. */
+ for (mcnt = num_regs; (unsigned) mcnt < regs->num_regs; mcnt++)
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ } /* regs && !bufp->no_sub */
+
+ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
+ nfailure_points_pushed, nfailure_points_popped,
+ nfailure_points_pushed - nfailure_points_popped);
+ DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
+
+ mcnt = d - pos - (MATCHING_IN_FIRST_STRING
+ ? string1
+ : string2 - size1);
+
+ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
+
+ FREE_VARIABLES ();
+ return mcnt;
+ }
+
+ /* Otherwise match next pattern command. */
+ switch (SWITCH_ENUM_CAST ((re_opcode_t) *p++))
+ {
+ /* Ignore these. Used to ignore the n of succeed_n's which
+ currently have n == 0. */
+ case no_op:
+ DEBUG_PRINT1 ("EXECUTING no_op.\n");
+ break;
+
+ case succeed:
+ DEBUG_PRINT1 ("EXECUTING succeed.\n");
+ goto succeed_label;
+
+ /* Match the next n pattern characters exactly. The following
+ byte in the pattern defines n, and the n bytes after that
+ are the characters to match. */
+ case exactn:
+ mcnt = *p++;
+ DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
+
+ /* This is written out as an if-else so we don't waste time
+ testing `translate' inside the loop. */
+ if (translate)
+ {
+ do
+ {
+ PREFETCH ();
+ if ((unsigned char) translate[(unsigned char) *d++]
+ != (unsigned char) *p++)
+ goto fail;
+ }
+ while (--mcnt);
+ }
+ else
+ {
+ do
+ {
+ PREFETCH ();
+ if (*d++ != (char) *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ SET_REGS_MATCHED ();
+ break;
+
+
+ /* Match any character except possibly a newline or a null. */
+ case anychar:
+ DEBUG_PRINT1 ("EXECUTING anychar.\n");
+
+ PREFETCH ();
+
+ if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
+ || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
+ goto fail;
+
+ SET_REGS_MATCHED ();
+ DEBUG_PRINT2 (" Matched `%d'.\n", *d);
+ d++;
+ break;
+
+
+ case charset:
+ case charset_not:
+ {
+ register unsigned char c;
+ boolean not = (re_opcode_t) *(p - 1) == charset_not;
+
+ DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
+
+ PREFETCH ();
+ c = TRANSLATE (*d); /* The character to match. */
+
+ /* Cast to `unsigned' instead of `unsigned char' in case the
+ bit list is a full 32 bytes long. */
+ if (c < (unsigned) (*p * BYTEWIDTH)
+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ p += 1 + *p;
+
+ if (!not) goto fail;
+
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+ }
+
+
+ /* The beginning of a group is represented by start_memory.
+ The arguments are the register number in the next byte, and the
+ number of groups inner to this one in the next. The text
+ matched within the group is recorded (in the internal
+ registers data structure) under the register number. */
+ case start_memory:
+ DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]);
+
+ /* Find out if this group can match the empty string. */
+ p1 = p; /* To send to group_match_null_string_p. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[*p])
+ = group_match_null_string_p (&p1, pend, reg_info);
+
+ /* Save the position in the string where we were the last time
+ we were at this open-group operator in case the group is
+ operated upon by a repetition operator, e.g., with `(a*)*b'
+ against `ab'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
+ : regstart[*p];
+ DEBUG_PRINT2 (" old_regstart: %d\n",
+ POINTER_TO_OFFSET (old_regstart[*p]));
+
+ regstart[*p] = d;
+ DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
+
+ IS_ACTIVE (reg_info[*p]) = 1;
+ MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* Clear this whenever we change the register activity status. */
+ set_regs_matched_done = 0;
+
+ /* This is the new highest active register. */
+ highest_active_reg = *p;
+
+ /* If nothing was active before, this is the new lowest active
+ register. */
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *p;
+
+ /* Move past the register number and inner group count. */
+ p += 2;
+ just_past_start_mem = p;
+
+ break;
+
+
+ /* The stop_memory opcode represents the end of a group. Its
+ arguments are the same as start_memory's: the register
+ number, and the number of inner groups. */
+ case stop_memory:
+ DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
+
+ /* We need to save the string position the last time we were at
+ this close-group operator in case the group is operated
+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
+ against `aba'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
+ : regend[*p];
+ DEBUG_PRINT2 (" old_regend: %d\n",
+ POINTER_TO_OFFSET (old_regend[*p]));
+
+ regend[*p] = d;
+ DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
+
+ /* This register isn't active anymore. */
+ IS_ACTIVE (reg_info[*p]) = 0;
+
+ /* Clear this whenever we change the register activity status. */
+ set_regs_matched_done = 0;
+
+ /* If this was the only register active, nothing is active
+ anymore. */
+ if (lowest_active_reg == highest_active_reg)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ { /* We must scan for the new highest active register, since
+ it isn't necessarily one less than now: consider
+ (a(b)c(d(e)f)g). When group 3 ends, after the f), the
+ new highest active register is 1. */
+ unsigned char r = *p - 1;
+ while (r > 0 && !IS_ACTIVE (reg_info[r]))
+ r--;
+
+ /* If we end up at register zero, that means that we saved
+ the registers as the result of an `on_failure_jump', not
+ a `start_memory', and we jumped to past the innermost
+ `stop_memory'. For example, in ((.)*) we save
+ registers 1 and 2 as a result of the *, but when we pop
+ back to the second ), we are at the stop_memory 1.
+ Thus, nothing is active. */
+ if (r == 0)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ highest_active_reg = r;
+ }
+
+ /* If just failed to match something this time around with a
+ group that's operated on by a repetition operator, try to
+ force exit from the ``loop'', and restore the register
+ information for this group that we had before trying this
+ last match. */
+ if ((!MATCHED_SOMETHING (reg_info[*p])
+ || just_past_start_mem == p - 1)
+ && (p + 2) < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ p1 = p + 2;
+ mcnt = 0;
+ switch ((re_opcode_t) *p1++)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (is_a_jump_n)
+ p1 += 2;
+ break;
+
+ default:
+ /* do nothing */ ;
+ }
+ p1 += mcnt;
+
+ /* If the next operation is a jump backwards in the pattern
+ to an on_failure_jump right before the start_memory
+ corresponding to this stop_memory, exit from the loop
+ by forcing a failure after pushing on the stack the
+ on_failure_jump's jump in the pattern, and d. */
+ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
+ && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
+ {
+ /* If this group ever matched anything, then restore
+ what its registers were before trying this last
+ failed match, e.g., with `(a*)*b' against `ab' for
+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
+ against `aba' for regend[3].
+
+ Also restore the registers for inner groups for,
+ e.g., `((a*)(b*))*' against `aba' (register 3 would
+ otherwise get trashed). */
+
+ if (EVER_MATCHED_SOMETHING (reg_info[*p]))
+ {
+ unsigned r;
+
+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* Restore this and inner groups' (if any) registers. */
+ for (r = *p; r < (unsigned) *p + (unsigned) *(p + 1);
+ r++)
+ {
+ regstart[r] = old_regstart[r];
+
+ /* xx why this test? */
+ if (old_regend[r] >= regstart[r])
+ regend[r] = old_regend[r];
+ }
+ }
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
+
+ goto fail;
+ }
+ }
+
+ /* Move past the register number and the inner group count. */
+ p += 2;
+ break;
+
+
+ /* \<digit> has been turned into a `duplicate' command which is
+ followed by the numeric value of <digit> as the register number. */
+ case duplicate:
+ {
+ register const char *d2, *dend2;
+ int regno = *p++; /* Get which register to match against. */
+ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
+
+ /* Can't back reference a group which we've never matched. */
+ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
+ goto fail;
+
+ /* Where in input to try to start matching. */
+ d2 = regstart[regno];
+
+ /* Where to stop matching; if both the place to start and
+ the place to stop matching are in the same string, then
+ set to the place to stop, otherwise, for now have to use
+ the end of the first string. */
+
+ dend2 = ((FIRST_STRING_P (regstart[regno])
+ == FIRST_STRING_P (regend[regno]))
+ ? regend[regno] : end_match_1);
+ for (;;)
+ {
+ /* If necessary, advance to next segment in register
+ contents. */
+ while (d2 == dend2)
+ {
+ if (dend2 == end_match_2) break;
+ if (dend2 == regend[regno]) break;
+
+ /* End of string1 => advance to string2. */
+ d2 = string2;
+ dend2 = regend[regno];
+ }
+ /* At end of register contents => success */
+ if (d2 == dend2) break;
+
+ /* If necessary, advance to next segment in data. */
+ PREFETCH ();
+
+ /* How many characters left in this segment to match. */
+ mcnt = dend - d;
+
+ /* Want how many consecutive characters we can match in
+ one shot, so, if necessary, adjust the count. */
+ if (mcnt > dend2 - d2)
+ mcnt = dend2 - d2;
+
+ /* Compare that many; failure if mismatch, else move
+ past them. */
+ if (translate
+ ? bcmp_translate (d, d2, mcnt, translate)
+ : memcmp (d, d2, mcnt))
+ goto fail;
+ d += mcnt, d2 += mcnt;
+
+ /* Do this because we've match some characters. */
+ SET_REGS_MATCHED ();
+ }
+ }
+ break;
+
+
+ /* begline matches the empty string at the beginning of the string
+ (unless `not_bol' is set in `bufp'), and, if
+ `newline_anchor' is set, after newlines. */
+ case begline:
+ DEBUG_PRINT1 ("EXECUTING begline.\n");
+
+ if (AT_STRINGS_BEG (d))
+ {
+ if (!bufp->not_bol) break;
+ }
+ else if (d[-1] == '\n' && bufp->newline_anchor)
+ {
+ break;
+ }
+ /* In all other cases, we fail. */
+ goto fail;
+
+
+ /* endline is the dual of begline. */
+ case endline:
+ DEBUG_PRINT1 ("EXECUTING endline.\n");
+
+ if (AT_STRINGS_END (d))
+ {
+ if (!bufp->not_eol) break;
+ }
+
+ /* We have to ``prefetch'' the next character. */
+ else if ((d == end1 ? *string2 : *d) == '\n'
+ && bufp->newline_anchor)
+ {
+ break;
+ }
+ goto fail;
+
+
+ /* Match at the very beginning of the data. */
+ case begbuf:
+ DEBUG_PRINT1 ("EXECUTING begbuf.\n");
+ if (AT_STRINGS_BEG (d))
+ break;
+ goto fail;
+
+
+ /* Match at the very end of the data. */
+ case endbuf:
+ DEBUG_PRINT1 ("EXECUTING endbuf.\n");
+ if (AT_STRINGS_END (d))
+ break;
+ goto fail;
+
+
+ /* on_failure_keep_string_jump is used to optimize `.*\n'. It
+ pushes NULL as the value for the string on the stack. Then
+ `pop_failure_point' will keep the current value for the
+ string, instead of restoring it. To see why, consider
+ matching `foo\nbar' against `.*\n'. The .* matches the foo;
+ then the . fails against the \n. But the next thing we want
+ to do is match the \n against the \n; if we restored the
+ string value, we would be back at the foo.
+
+ Because this is used only in specific cases, we don't need to
+ check all the things that `on_failure_jump' does, to make
+ sure the right things get saved on the stack. Hence we don't
+ share its code. The only reason to push anything on the
+ stack at all is that otherwise we would have to change
+ `anychar's code to do something besides goto fail in this
+ case; that seems worse than this. */
+ case on_failure_keep_string_jump:
+ DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+#ifdef _LIBC
+ DEBUG_PRINT3 (" %d (to %p):\n", mcnt, p + mcnt);
+#else
+ DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
+#endif
+
+ PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
+ break;
+
+
+ /* Uses of on_failure_jump:
+
+ Each alternative starts with an on_failure_jump that points
+ to the beginning of the next alternative. Each alternative
+ except the last ends with a jump that in effect jumps past
+ the rest of the alternatives. (They really jump to the
+ ending jump of the following alternative, because tensioning
+ these jumps is a hassle.)
+
+ Repeats start with an on_failure_jump that points past both
+ the repetition text and either the following jump or
+ pop_failure_jump back to this on_failure_jump. */
+ case on_failure_jump:
+ on_failure:
+ DEBUG_PRINT1 ("EXECUTING on_failure_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+#ifdef _LIBC
+ DEBUG_PRINT3 (" %d (to %p)", mcnt, p + mcnt);
+#else
+ DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
+#endif
+
+ /* If this on_failure_jump comes right before a group (i.e.,
+ the original * applied to a group), save the information
+ for that group and all inner ones, so that if we fail back
+ to this point, the group's information will be correct.
+ For example, in \(a*\)*\1, we need the preceding group,
+ and in \(zz\(a*\)b*\)\2, we need the inner group. */
+
+ /* We can't use `p' to check ahead because we push
+ a failure point to `p + mcnt' after we do this. */
+ p1 = p;
+
+ /* We need to skip no_op's before we look for the
+ start_memory in case this on_failure_jump is happening as
+ the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
+ against aba. */
+ while (p1 < pend && (re_opcode_t) *p1 == no_op)
+ p1++;
+
+ if (p1 < pend && (re_opcode_t) *p1 == start_memory)
+ {
+ /* We have a new highest active register now. This will
+ get reset at the start_memory we are about to get to,
+ but we will have saved all the registers relevant to
+ this repetition op, as described above. */
+ highest_active_reg = *(p1 + 1) + *(p1 + 2);
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *(p1 + 1);
+ }
+
+ DEBUG_PRINT1 (":\n");
+ PUSH_FAILURE_POINT (p + mcnt, d, -2);
+ break;
+
+
+ /* A smart repeat ends with `maybe_pop_jump'.
+ We change it to either `pop_failure_jump' or `jump'. */
+ case maybe_pop_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
+ {
+ register unsigned char *p2 = p;
+
+ /* Compare the beginning of the repeat with what in the
+ pattern follows its end. If we can establish that there
+ is nothing that they would both match, i.e., that we
+ would have to backtrack because of (as in, e.g., `a*a')
+ then we can change to pop_failure_jump, because we'll
+ never have to backtrack.
+
+ This is not true in the case of alternatives: in
+ `(a|ab)*' we do need to backtrack to the `ab' alternative
+ (e.g., if the string was `ab'). But instead of trying to
+ detect that here, the alternative has put on a dummy
+ failure point which is what we will end up popping. */
+
+ /* Skip over open/close-group commands.
+ If what follows this loop is a ...+ construct,
+ look at what begins its body, since we will have to
+ match at least one of that. */
+ while (1)
+ {
+ if (p2 + 2 < pend
+ && ((re_opcode_t) *p2 == stop_memory
+ || (re_opcode_t) *p2 == start_memory))
+ p2 += 3;
+ else if (p2 + 6 < pend
+ && (re_opcode_t) *p2 == dummy_failure_jump)
+ p2 += 6;
+ else
+ break;
+ }
+
+ p1 = p + mcnt;
+ /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
+ to the `maybe_finalize_jump' of this case. Examine what
+ follows. */
+
+ /* If we're at the end of the pattern, we can change. */
+ if (p2 == pend)
+ {
+ /* Consider what happens when matching ":\(.*\)"
+ against ":/". I don't really understand this code
+ yet. */
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1
+ (" End of pattern: change to `pop_failure_jump'.\n");
+ }
+
+ else if ((re_opcode_t) *p2 == exactn
+ || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
+ {
+ register unsigned char c
+ = *p2 == (unsigned char) endline ? '\n' : p2[2];
+
+ if ((re_opcode_t) p1[3] == exactn && p1[5] != c)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
+ c, p1[5]);
+ }
+
+ else if ((re_opcode_t) p1[3] == charset
+ || (re_opcode_t) p1[3] == charset_not)
+ {
+ int not = (re_opcode_t) p1[3] == charset_not;
+
+ if (c < (unsigned char) (p1[4] * BYTEWIDTH)
+ && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ /* `not' is equal to 1 if c would match, which means
+ that we can't change to pop_failure_jump. */
+ if (!not)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ }
+ else if ((re_opcode_t) *p2 == charset)
+ {
+ /* We win if the first character of the loop is not part
+ of the charset. */
+ if ((re_opcode_t) p1[3] == exactn
+ && ! ((int) p2[1] * BYTEWIDTH > (int) p1[5]
+ && (p2[2 + p1[5] / BYTEWIDTH]
+ & (1 << (p1[5] % BYTEWIDTH)))))
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+
+ else if ((re_opcode_t) p1[3] == charset_not)
+ {
+ int idx;
+ /* We win if the charset_not inside the loop
+ lists every character listed in the charset after. */
+ for (idx = 0; idx < (int) p2[1]; idx++)
+ if (! (p2[2 + idx] == 0
+ || (idx < (int) p1[4]
+ && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
+ break;
+
+ if (idx == p2[1])
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ else if ((re_opcode_t) p1[3] == charset)
+ {
+ int idx;
+ /* We win if the charset inside the loop
+ has no overlap with the one after the loop. */
+ for (idx = 0;
+ idx < (int) p2[1] && idx < (int) p1[4];
+ idx++)
+ if ((p2[2 + idx] & p1[5 + idx]) != 0)
+ break;
+
+ if (idx == p2[1] || idx == p1[4])
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ }
+ }
+ p -= 2; /* Point at relative address again. */
+ if ((re_opcode_t) p[-1] != pop_failure_jump)
+ {
+ p[-1] = (unsigned char) jump;
+ DEBUG_PRINT1 (" Match => jump.\n");
+ goto unconditional_jump;
+ }
+ /* Note fall through. */
+
+
+ /* The end of a simple repeat has a pop_failure_jump back to
+ its matching on_failure_jump, where the latter will push a
+ failure point. The pop_failure_jump takes off failure
+ points put on by this pop_failure_jump's matching
+ on_failure_jump; we got through the pattern to here from the
+ matching on_failure_jump, so didn't fail. */
+ case pop_failure_jump:
+ {
+ /* We need to pass separate storage for the lowest and
+ highest registers, even though we don't care about the
+ actual values. Otherwise, we will restore only one
+ register from the stack, since lowest will == highest in
+ `pop_failure_point'. */
+ active_reg_t dummy_low_reg, dummy_high_reg;
+ unsigned char *pdummy;
+ const char *sdummy;
+
+ DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
+ POP_FAILURE_POINT (sdummy, pdummy,
+ dummy_low_reg, dummy_high_reg,
+ reg_dummy, reg_dummy, reg_info_dummy);
+ }
+ /* Note fall through. */
+
+ unconditional_jump:
+#ifdef _LIBC
+ DEBUG_PRINT2 ("\n%p: ", p);
+#else
+ DEBUG_PRINT2 ("\n0x%x: ", p);
+#endif
+ /* Note fall through. */
+
+ /* Unconditionally jump (without popping any failure points). */
+ case jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
+ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
+ p += mcnt; /* Do the jump. */
+#ifdef _LIBC
+ DEBUG_PRINT2 ("(to %p).\n", p);
+#else
+ DEBUG_PRINT2 ("(to 0x%x).\n", p);
+#endif
+ break;
+
+
+ /* We need this opcode so we can detect where alternatives end
+ in `group_match_null_string_p' et al. */
+ case jump_past_alt:
+ DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
+ goto unconditional_jump;
+
+
+ /* Normally, the on_failure_jump pushes a failure point, which
+ then gets popped at pop_failure_jump. We will end up at
+ pop_failure_jump, also, and with a pattern of, say, `a+', we
+ are skipping over the on_failure_jump, so we have to push
+ something meaningless for pop_failure_jump to pop. */
+ case dummy_failure_jump:
+ DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
+ /* It doesn't matter what we push for the string here. What
+ the code at `fail' tests is the value for the pattern. */
+ PUSH_FAILURE_POINT (NULL, NULL, -2);
+ goto unconditional_jump;
+
+
+ /* At the end of an alternative, we need to push a dummy failure
+ point in case we are followed by a `pop_failure_jump', because
+ we don't want the failure point for the alternative to be
+ popped. For example, matching `(a|ab)*' against `aab'
+ requires that we match the `ab' alternative. */
+ case push_dummy_failure:
+ DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
+ /* See comments just above at `dummy_failure_jump' about the
+ two zeroes. */
+ PUSH_FAILURE_POINT (NULL, NULL, -2);
+ break;
+
+ /* Have to succeed matching what follows at least n times.
+ After that, handle like `on_failure_jump'. */
+ case succeed_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
+
+ assert (mcnt >= 0);
+ /* Originally, this is how many times we HAVE to succeed. */
+ if (mcnt > 0)
+ {
+ mcnt--;
+ p += 2;
+ STORE_NUMBER_AND_INCR (p, mcnt);
+#ifdef _LIBC
+ DEBUG_PRINT3 (" Setting %p to %d.\n", p - 2, mcnt);
+#else
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p - 2, mcnt);
+#endif
+ }
+ else if (mcnt == 0)
+ {
+#ifdef _LIBC
+ DEBUG_PRINT2 (" Setting two bytes from %p to no_op.\n", p+2);
+#else
+ DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2);
+#endif
+ p[2] = (unsigned char) no_op;
+ p[3] = (unsigned char) no_op;
+ goto on_failure;
+ }
+ break;
+
+ case jump_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
+
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt)
+ {
+ mcnt--;
+ STORE_NUMBER (p + 2, mcnt);
+#ifdef _LIBC
+ DEBUG_PRINT3 (" Setting %p to %d.\n", p + 2, mcnt);
+#else
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p + 2, mcnt);
+#endif
+ goto unconditional_jump;
+ }
+ /* If don't have to jump any more, skip over the rest of command. */
+ else
+ p += 4;
+ break;
+
+ case set_number_at:
+ {
+ DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p1 = p + mcnt;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+#ifdef _LIBC
+ DEBUG_PRINT3 (" Setting %p to %d.\n", p1, mcnt);
+#else
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
+#endif
+ STORE_NUMBER (p1, mcnt);
+ break;
+ }
+
+#if 0
+ /* The DEC Alpha C compiler 3.x generates incorrect code for the
+ test WORDCHAR_P (d - 1) != WORDCHAR_P (d) in the expansion of
+ AT_WORD_BOUNDARY, so this code is disabled. Expanding the
+ macro and introducing temporary variables works around the bug. */
+
+ case wordbound:
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
+ break;
+ goto fail;
+
+ case notwordbound:
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
+ goto fail;
+ break;
+#else
+ case wordbound:
+ {
+ boolean prevchar, thischar;
+
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
+ break;
+
+ prevchar = WORDCHAR_P (d - 1);
+ thischar = WORDCHAR_P (d);
+ if (prevchar != thischar)
+ break;
+ goto fail;
+ }
+
+ case notwordbound:
+ {
+ boolean prevchar, thischar;
+
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+ if (AT_STRINGS_BEG (d) || AT_STRINGS_END (d))
+ goto fail;
+
+ prevchar = WORDCHAR_P (d - 1);
+ thischar = WORDCHAR_P (d);
+ if (prevchar != thischar)
+ goto fail;
+ break;
+ }
+#endif
+
+ case wordbeg:
+ DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
+ if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
+ break;
+ goto fail;
+
+ case wordend:
+ DEBUG_PRINT1 ("EXECUTING wordend.\n");
+ if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
+ && (!WORDCHAR_P (d) || AT_STRINGS_END (d)))
+ break;
+ goto fail;
+
+#ifdef emacs
+ case before_dot:
+ DEBUG_PRINT1 ("EXECUTING before_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) >= point)
+ goto fail;
+ break;
+
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) != point)
+ goto fail;
+ break;
+
+ case after_dot:
+ DEBUG_PRINT1 ("EXECUTING after_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) <= point)
+ goto fail;
+ break;
+
+ case syntaxspec:
+ DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
+ mcnt = *p++;
+ goto matchsyntax;
+
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
+ mcnt = (int) Sword;
+ matchsyntax:
+ PREFETCH ();
+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
+ d++;
+ if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+ case notsyntaxspec:
+ DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
+ mcnt = *p++;
+ goto matchnotsyntax;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
+ mcnt = (int) Sword;
+ matchnotsyntax:
+ PREFETCH ();
+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
+ d++;
+ if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+#else /* not emacs */
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
+ PREFETCH ();
+ if (!WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
+ PREFETCH ();
+ if (WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+#endif /* not emacs */
+
+ default:
+ abort ();
+ }
+ continue; /* Successfully executed one pattern command; keep going. */
+
+
+ /* We goto here if a matching operation fails. */
+ fail:
+ if (!FAIL_STACK_EMPTY ())
+ { /* A restart point is known. Restore to that state. */
+ DEBUG_PRINT1 ("\nFAIL:\n");
+ POP_FAILURE_POINT (d, p,
+ lowest_active_reg, highest_active_reg,
+ regstart, regend, reg_info);
+
+ /* If this failure point is a dummy, try the next one. */
+ if (!p)
+ goto fail;
+
+ /* If we failed to the end of the pattern, don't examine *p. */
+ assert (p <= pend);
+ if (p < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ /* If failed to a backwards jump that's part of a repetition
+ loop, need to pop this failure point and use the next one. */
+ switch ((re_opcode_t) *p)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case maybe_pop_jump:
+ case pop_failure_jump:
+ case jump:
+ p1 = p + 1;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+
+ if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
+ || (!is_a_jump_n
+ && (re_opcode_t) *p1 == on_failure_jump))
+ goto fail;
+ break;
+ default:
+ /* do nothing */ ;
+ }
+ }
+
+ if (d >= string1 && d <= end1)
+ dend = end_match_1;
+ }
+ else
+ break; /* Matching at this starting point really fails. */
+ } /* for (;;) */
+
+ if (best_regs_set)
+ goto restore_best_regs;
+
+ FREE_VARIABLES ();
+
+ return -1; /* Failure to match. */
+} /* re_match_2 */
+
+/* Subroutine definitions for re_match_2. */
+
+
+/* We are passed P pointing to a register number after a start_memory.
+
+ Return true if the pattern up to the corresponding stop_memory can
+ match the empty string, and false otherwise.
+
+ If we find the matching stop_memory, sets P to point to one past its number.
+ Otherwise, sets P to an undefined byte less than or equal to END.
+
+ We don't handle duplicates properly (yet). */
+
+static boolean
+group_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ /* Point to after the args to the start_memory. */
+ unsigned char *p1 = *p + 2;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and return true or
+ false, as appropriate, when we get to one that can't, or to the
+ matching stop_memory. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* Could be either a loop or a series of alternatives. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ /* If the next operation is not a jump backwards in the
+ pattern. */
+
+ if (mcnt >= 0)
+ {
+ /* Go through the on_failure_jumps of the alternatives,
+ seeing if any of the alternatives cannot match nothing.
+ The last alternative starts with only a jump,
+ whereas the rest start with on_failure_jump and end
+ with a jump, e.g., here is the pattern for `a|b|c':
+
+ /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
+ /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
+ /exactn/1/c
+
+ So, we have to first go through the first (n-1)
+ alternatives and then deal with the last one separately. */
+
+
+ /* Deal with the first (n-1) alternatives, which start
+ with an on_failure_jump (see above) that jumps to right
+ past a jump_past_alt. */
+
+ while ((re_opcode_t) p1[mcnt-3] == jump_past_alt)
+ {
+ /* `mcnt' holds how many bytes long the alternative
+ is, including the ending `jump_past_alt' and
+ its number. */
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
+ reg_info))
+ return false;
+
+ /* Move to right after this alternative, including the
+ jump_past_alt. */
+ p1 += mcnt;
+
+ /* Break if it's the beginning of an n-th alternative
+ that doesn't begin with an on_failure_jump. */
+ if ((re_opcode_t) *p1 != on_failure_jump)
+ break;
+
+ /* Still have to check that it's not an n-th
+ alternative that starts with an on_failure_jump. */
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if ((re_opcode_t) p1[mcnt-3] != jump_past_alt)
+ {
+ /* Get to the beginning of the n-th alternative. */
+ p1 -= 3;
+ break;
+ }
+ }
+
+ /* Deal with the last alternative: go back and get number
+ of the `jump_past_alt' just before it. `mcnt' contains
+ the length of the alternative. */
+ EXTRACT_NUMBER (mcnt, p1 - 2);
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
+ return false;
+
+ p1 += mcnt; /* Get past the n-th alternative. */
+ } /* if mcnt > 0 */
+ break;
+
+
+ case stop_memory:
+ assert (p1[1] == **p);
+ *p = p1 + 2;
+ return true;
+
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return false;
+} /* group_match_null_string_p */
+
+
+/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
+ It expects P to be the first byte of a single alternative and END one
+ byte past the last. The alternative can contain groups. */
+
+static boolean
+alt_match_null_string_p (p, end, reg_info)
+ unsigned char *p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ unsigned char *p1 = p;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and break when we get
+ to one that can't. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* It's a loop. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ break;
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return true;
+} /* alt_match_null_string_p */
+
+
+/* Deals with the ops common to group_match_null_string_p and
+ alt_match_null_string_p.
+
+ Sets P to one after the op and its arguments, if any. */
+
+static boolean
+common_op_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ boolean ret;
+ int reg_no;
+ unsigned char *p1 = *p;
+
+ switch ((re_opcode_t) *p1++)
+ {
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbeg:
+ case wordend:
+ case wordbound:
+ case notwordbound:
+#ifdef emacs
+ case before_dot:
+ case at_dot:
+ case after_dot:
+#endif
+ break;
+
+ case start_memory:
+ reg_no = *p1;
+ assert (reg_no > 0 && reg_no <= MAX_REGNUM);
+ ret = group_match_null_string_p (&p1, end, reg_info);
+
+ /* Have to set this here in case we're checking a group which
+ contains a group and a back reference to it. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
+
+ if (!ret)
+ return false;
+ break;
+
+ /* If this is an optimized succeed_n for zero times, make the jump. */
+ case jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (mcnt >= 0)
+ p1 += mcnt;
+ else
+ return false;
+ break;
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p1 += 2;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ if (mcnt == 0)
+ {
+ p1 -= 4;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ }
+ else
+ return false;
+ break;
+
+ case duplicate:
+ if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
+ return false;
+ break;
+
+ case set_number_at:
+ p1 += 4;
+
+ default:
+ /* All other opcodes mean we cannot match the empty string. */
+ return false;
+ }
+
+ *p = p1;
+ return true;
+} /* common_op_match_null_string_p */
+
+
+/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
+ bytes; nonzero otherwise. */
+
+static int
+bcmp_translate (s1, s2, len, translate)
+ const char *s1, *s2;
+ register int len;
+ RE_TRANSLATE_TYPE translate;
+{
+ register const unsigned char *p1 = (const unsigned char *) s1;
+ register const unsigned char *p2 = (const unsigned char *) s2;
+ while (len)
+ {
+ if (translate[*p1++] != translate[*p2++]) return 1;
+ len--;
+ }
+ return 0;
+}
+
+/* Entry points for GNU code. */
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+ compiles PATTERN (of length SIZE) and puts the result in BUFP.
+ Returns 0 if the pattern was valid, otherwise an error string.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+ are set in BUFP on entry.
+
+ We call regex_compile to do the actual compilation. */
+
+const char *
+re_compile_pattern (pattern, length, bufp)
+ const char *pattern;
+ size_t length;
+ struct re_pattern_buffer *bufp;
+{
+ reg_errcode_t ret;
+
+ /* GNU code is written to assume at least RE_NREGS registers will be set
+ (and at least one extra will be -1). */
+ bufp->regs_allocated = REGS_UNALLOCATED;
+
+ /* And GNU code determines whether or not to get register information
+ by passing null for the REGS argument to re_match, etc., not by
+ setting no_sub. */
+ bufp->no_sub = 0;
+
+ /* Match anchors at newline. */
+ bufp->newline_anchor = 1;
+
+ ret = regex_compile (pattern, length, re_syntax_options, bufp);
+
+ if (!ret)
+ return NULL;
+ return gettext (re_error_msgid + re_error_msgid_idx[(int) ret]);
+}
+#ifdef _LIBC
+weak_alias (__re_compile_pattern, re_compile_pattern)
+#endif
+
+/* Entry points compatible with 4.2 BSD regex library. We don't define
+ them unless specifically requested. */
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+
+/* BSD has one and only one pattern buffer. */
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+#ifdef _LIBC
+/* Make these definitions weak in libc, so POSIX programs can redefine
+ these names if they don't use our functions, and still use
+ regcomp/regexec below without link errors. */
+weak_function
+#endif
+re_comp (s)
+ const char *s;
+{
+ reg_errcode_t ret;
+
+ if (!s)
+ {
+ if (!re_comp_buf.buffer)
+ return gettext ("No previous regular expression");
+ return 0;
+ }
+
+ if (!re_comp_buf.buffer)
+ {
+ re_comp_buf.buffer = (unsigned char *) malloc (200);
+ if (re_comp_buf.buffer == NULL)
+ return (char *) gettext (re_error_msgid
+ + re_error_msgid_idx[(int) REG_ESPACE]);
+ re_comp_buf.allocated = 200;
+
+ re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
+ if (re_comp_buf.fastmap == NULL)
+ return (char *) gettext (re_error_msgid
+ + re_error_msgid_idx[(int) REG_ESPACE]);
+ }
+
+ /* Since `re_exec' always passes NULL for the `regs' argument, we
+ don't need to initialize the pattern buffer fields which affect it. */
+
+ /* Match anchors at newlines. */
+ re_comp_buf.newline_anchor = 1;
+
+ ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
+
+ if (!ret)
+ return NULL;
+
+ /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */
+ return (char *) gettext (re_error_msgid + re_error_msgid_idx[(int) ret]);
+}
+
+
+int
+#ifdef _LIBC
+weak_function
+#endif
+re_exec (s)
+ const char *s;
+{
+ const int len = strlen (s);
+ return
+ 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
+}
+
+#endif /* _REGEX_RE_COMP */
+
+/* POSIX.2 functions. Don't define these for Emacs. */
+
+#ifndef emacs
+
+/* regcomp takes a regular expression as a string and compiles it.
+
+ PREG is a regex_t *. We do not expect any fields to be initialized,
+ since POSIX says we shouldn't. Thus, we set
+
+ `buffer' to the compiled pattern;
+ `used' to the length of the compiled pattern;
+ `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+ REG_EXTENDED bit in CFLAGS is set; otherwise, to
+ RE_SYNTAX_POSIX_BASIC;
+ `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+ `fastmap' to an allocated space for the fastmap;
+ `fastmap_accurate' to zero;
+ `re_nsub' to the number of subexpressions in PATTERN.
+
+ PATTERN is the address of the pattern string.
+
+ CFLAGS is a series of bits which affect compilation.
+
+ If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+ use POSIX basic syntax.
+
+ If REG_NEWLINE is set, then . and [^...] don't match newline.
+ Also, regexec will try a match beginning after every newline.
+
+ If REG_ICASE is set, then we considers upper- and lowercase
+ versions of letters to be equivalent when matching.
+
+ If REG_NOSUB is set, then when PREG is passed to regexec, that
+ routine will report only success or failure, and nothing about the
+ registers.
+
+ It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for
+ the return codes and their meanings.) */
+
+int
+regcomp (preg, pattern, cflags)
+ regex_t *preg;
+ const char *pattern;
+ int cflags;
+{
+ reg_errcode_t ret;
+ reg_syntax_t syntax
+ = (cflags & REG_EXTENDED) ?
+ RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
+
+ /* regex_compile will allocate the space for the compiled pattern. */
+ preg->buffer = 0;
+ preg->allocated = 0;
+ preg->used = 0;
+
+ /* Try to allocate space for the fastmap. */
+ preg->fastmap = (char *) malloc (1 << BYTEWIDTH);
+
+ if (cflags & REG_ICASE)
+ {
+ unsigned i;
+
+ preg->translate
+ = (RE_TRANSLATE_TYPE) malloc (CHAR_SET_SIZE
+ * sizeof (*(RE_TRANSLATE_TYPE)0));
+ if (preg->translate == NULL)
+ return (int) REG_ESPACE;
+
+ /* Map uppercase characters to corresponding lowercase ones. */
+ for (i = 0; i < CHAR_SET_SIZE; i++)
+ preg->translate[i] = ISUPPER (i) ? TOLOWER (i) : i;
+ }
+ else
+ preg->translate = NULL;
+
+ /* If REG_NEWLINE is set, newlines are treated differently. */
+ if (cflags & REG_NEWLINE)
+ { /* REG_NEWLINE implies neither . nor [^...] match newline. */
+ syntax &= ~RE_DOT_NEWLINE;
+ syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+ /* It also changes the matching behavior. */
+ preg->newline_anchor = 1;
+ }
+ else
+ preg->newline_anchor = 0;
+
+ preg->no_sub = !!(cflags & REG_NOSUB);
+
+ /* POSIX says a null character in the pattern terminates it, so we
+ can use strlen here in compiling the pattern. */
+ ret = regex_compile (pattern, strlen (pattern), syntax, preg);
+
+ /* POSIX doesn't distinguish between an unmatched open-group and an
+ unmatched close-group: both are REG_EPAREN. */
+ if (ret == REG_ERPAREN) ret = REG_EPAREN;
+
+ if (ret == REG_NOERROR && preg->fastmap)
+ {
+ /* Compute the fastmap now, since regexec cannot modify the pattern
+ buffer. */
+ if (re_compile_fastmap (preg) == -2)
+ {
+ /* Some error occured while computing the fastmap, just forget
+ about it. */
+ free (preg->fastmap);
+ preg->fastmap = NULL;
+ }
+ }
+
+ return (int) ret;
+}
+#ifdef _LIBC
+weak_alias (__regcomp, regcomp)
+#endif
+
+
+/* regexec searches for a given pattern, specified by PREG, in the
+ string STRING.
+
+ If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+ `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
+ least NMATCH elements, and we set them to the offsets of the
+ corresponding matched substrings.
+
+ EFLAGS specifies `execution flags' which affect matching: if
+ REG_NOTBOL is set, then ^ does not match at the beginning of the
+ string; if REG_NOTEOL is set, then $ does not match at the end.
+
+ We return 0 if we find a match and REG_NOMATCH if not. */
+
+int
+regexec (preg, string, nmatch, pmatch, eflags)
+ const regex_t *preg;
+ const char *string;
+ size_t nmatch;
+ regmatch_t pmatch[];
+ int eflags;
+{
+ int ret;
+ struct re_registers regs;
+ regex_t private_preg;
+ int len = strlen (string);
+ boolean want_reg_info = !preg->no_sub && nmatch > 0;
+
+ private_preg = *preg;
+
+ private_preg.not_bol = !!(eflags & REG_NOTBOL);
+ private_preg.not_eol = !!(eflags & REG_NOTEOL);
+
+ /* The user has told us exactly how many registers to return
+ information about, via `nmatch'. We have to pass that on to the
+ matching routines. */
+ private_preg.regs_allocated = REGS_FIXED;
+
+ if (want_reg_info)
+ {
+ regs.num_regs = nmatch;
+ regs.start = TALLOC (nmatch * 2, regoff_t);
+ if (regs.start == NULL)
+ return (int) REG_NOMATCH;
+ regs.end = regs.start + nmatch;
+ }
+
+ /* Perform the searching operation. */
+ ret = re_search (&private_preg, string, len,
+ /* start: */ 0, /* range: */ len,
+ want_reg_info ? &regs : (struct re_registers *) 0);
+
+ /* Copy the register information to the POSIX structure. */
+ if (want_reg_info)
+ {
+ if (ret >= 0)
+ {
+ unsigned r;
+
+ for (r = 0; r < nmatch; r++)
+ {
+ pmatch[r].rm_so = regs.start[r];
+ pmatch[r].rm_eo = regs.end[r];
+ }
+ }
+
+ /* If we needed the temporary register info, free the space now. */
+ free (regs.start);
+ }
+
+ /* We want zero return to mean success, unlike `re_search'. */
+ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
+}
+#ifdef _LIBC
+weak_alias (__regexec, regexec)
+#endif
+
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+ from either regcomp or regexec. We don't use PREG here. */
+
+size_t
+regerror (errcode, preg, errbuf, errbuf_size)
+ int errcode;
+ const regex_t *preg;
+ char *errbuf;
+ size_t errbuf_size;
+{
+ const char *msg;
+ size_t msg_size;
+
+ if (errcode < 0
+ || errcode >= (int) (sizeof (re_error_msgid_idx)
+ / sizeof (re_error_msgid_idx[0])))
+ /* Only error codes returned by the rest of the code should be passed
+ to this routine. If we are given anything else, or if other regex
+ code generates an invalid error code, then the program has a bug.
+ Dump core so we can fix it. */
+ abort ();
+
+ msg = gettext (re_error_msgid + re_error_msgid_idx[errcode]);
+
+ msg_size = strlen (msg) + 1; /* Includes the null. */
+
+ if (errbuf_size != 0)
+ {
+ if (msg_size > errbuf_size)
+ {
+#if defined HAVE_MEMPCPY || defined _LIBC
+ *((char *) __mempcpy (errbuf, msg, errbuf_size - 1)) = '\0';
+#else
+ memcpy (errbuf, msg, errbuf_size - 1);
+ errbuf[errbuf_size - 1] = 0;
+#endif
+ }
+ else
+ memcpy (errbuf, msg, msg_size);
+ }
+
+ return msg_size;
+}
+#ifdef _LIBC
+weak_alias (__regerror, regerror)
+#endif
+
+
+/* Free dynamically allocated space used by PREG. */
+
+void
+regfree (preg)
+ regex_t *preg;
+{
+ if (preg->buffer != NULL)
+ free (preg->buffer);
+ preg->buffer = NULL;
+
+ preg->allocated = 0;
+ preg->used = 0;
+
+ if (preg->fastmap != NULL)
+ free (preg->fastmap);
+ preg->fastmap = NULL;
+ preg->fastmap_accurate = 0;
+
+ if (preg->translate != NULL)
+ free (preg->translate);
+ preg->translate = NULL;
+}
+#ifdef _LIBC
+weak_alias (__regfree, regfree)
+#endif
+
+#endif /* not emacs */
diff --git a/lib/m4regex.h b/lib/m4regex.h
new file mode 100644
index 00000000..d88ab92b
--- /dev/null
+++ b/lib/m4regex.h
@@ -0,0 +1,542 @@
+/* Definitions for data structures and routines for the regular
+ expression library, version 0.12.
+ Copyright (C) 1985,89,90,91,92,93,95,96,97,98 Free Software Foundation, Inc.
+
+ This file is part of the GNU C Library. Its master source is NOT part of
+ the C library, however. The master source lives in /gd/gnu/lib.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _REGEX_H
+#define _REGEX_H 1
+
+/* Allow the use in C++ code. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* POSIX says that <sys/types.h> must be included (by the caller) before
+ <regex.h>. */
+
+#if !defined _POSIX_C_SOURCE && !defined _POSIX_SOURCE && defined VMS
+/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
+ should be there. */
+# include <stddef.h>
+#endif
+
+/* The following two types have to be signed and unsigned integer type
+ wide enough to hold a value of a pointer. For most ANSI compilers
+ ptrdiff_t and size_t should be likely OK. Still size of these two
+ types is 2 for Microsoft C. Ugh... */
+typedef long int s_reg_t;
+typedef unsigned long int active_reg_t;
+
+/* The following bits are used to determine the regexp syntax we
+ recognize. The set/not-set meanings are chosen so that Emacs syntax
+ remains the value 0. The bits are given in alphabetical order, and
+ the definitions shifted by one from the previous bit; thus, when we
+ add or remove a bit, only one other definition need change. */
+typedef unsigned long int reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+ If set, then such a \ quotes the following character. */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+ literals.
+ If set, then \+ and \? are operators and + and ? are literals. */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported. They are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+ expressions, of course).
+ If this bit is not set, then it depends:
+ ^ is an anchor if it is at the beginning of a regular
+ expression or after an open-group or an alternation operator;
+ $ is an anchor if it is at the end of a regular expression, or
+ before a close-group or an alternation operator.
+
+ This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+ POSIX draft 11.2 says that * etc. in leading positions is undefined.
+ We already implemented a previous draft which made those constructs
+ invalid, though, so we haven't changed the code back. */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+ regardless of where they are in the pattern.
+ If this bit is not set, then special characters are special only in
+ some contexts; otherwise they are ordinary. Specifically,
+ * + ? and intervals are only special when not after the beginning,
+ open-group, or alternation operator. */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+ If not set, then it doesn't. */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+ If not set, then it does. */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+ If not set, they do. */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+ interval, depending on RE_NO_BK_BRACES.
+ If not set, \{, \}, {, and } are literals. */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+ If not set, they are. */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+ If not set, newline is literal. */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+ are literals.
+ If not set, then `\{...\}' defines an interval. */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+ If not set, \(...\) defines a group, and ( and ) are literals. */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+ If not set, then \<digit> is a back-reference. */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+ If not set, then \| is an alternation operator, and | is literal. */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+ than the starting range point, as in [z-a], is invalid.
+ If not set, then when ending range point collates higher than the
+ starting range point, the range is ignored. */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+ If not set, then an unmatched ) is invalid. */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* If this bit is set, succeed as soon as we match the whole pattern,
+ without further backtracking. */
+#define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
+
+/* If this bit is set, do not process the GNU regex operators.
+ If not set, then the GNU regex operators are recognized. */
+#define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
+
+/* If this bit is set, turn on internal regex debugging.
+ If not set, and debugging was on, turn it off.
+ This only works if regex.c is compiled -DDEBUG.
+ We define this bit always, so that all that's needed to turn on
+ debugging is to recompile regex.c; the calling code can always have
+ this bit set, and it won't affect anything in the normal case. */
+#define RE_DEBUG (RE_NO_GNU_OPS << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+ some interfaces). When a regexp is compiled, the syntax used is
+ stored in the pattern buffer, so changing this does not affect
+ already-compiled regexps. */
+extern reg_syntax_t re_syntax_options;
+
+/* Define combinations of the above bits for the standard possibilities.
+ (The [[[ comments delimit what gets put into the Texinfo file, so
+ don't delete them!) */
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK \
+ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
+ | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GNU_AWK \
+ ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DEBUG) \
+ & ~(RE_DOT_NOT_NULL | RE_INTERVALS | RE_CONTEXT_INDEP_OPS))
+
+#define RE_SYNTAX_POSIX_AWK \
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \
+ | RE_INTERVALS | RE_NO_GNU_OPS)
+
+#define RE_SYNTAX_GREP \
+ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
+ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
+ | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP \
+ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
+ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
+ | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP \
+ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax. */
+#define _RE_SYNTAX_POSIX_COMMON \
+ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
+ | RE_INTERVALS | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+ RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
+ isn't minimal, since other operators, such as \`, aren't disabled. */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+ replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+/* Maximum number of duplicates an interval can allow. Some systems
+ (erroneously) define this in other header files, but we want our
+ value, so remove any previous define. */
+#ifdef RE_DUP_MAX
+# undef RE_DUP_MAX
+#endif
+/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */
+#define RE_DUP_MAX (0x7fff)
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp'). */
+
+/* If this bit is set, then use extended regular expression syntax.
+ If not set, then use basic regular expression syntax. */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+ characters in the string.
+ If not set, then anchors do match at newlines. */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+ If not set, then returns differ between not matching and errors. */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec). */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+ the beginning of the string (presumably because it's not the
+ beginning of a line).
+ If not set, then the beginning-of-line operator does match the
+ beginning of the string. */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line. */
+#define REG_NOTEOL (1 << 1)
+
+
+/* If any error codes are removed, changed, or added, update the
+ `re_error_msg' table in regex.c. */
+typedef enum
+{
+#ifdef _XOPEN_SOURCE
+ REG_ENOSYS = -1, /* This will never happen for this implementation. */
+#endif
+
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT, /* Invalid pattern. */
+ REG_ECOLLATE, /* Not implemented. */
+ REG_ECTYPE, /* Invalid character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* Unmatched left bracket. */
+ REG_EPAREN, /* Parenthesis imbalance. */
+ REG_EBRACE, /* Unmatched \{. */
+ REG_BADBR, /* Invalid contents of \{\}. */
+ REG_ERANGE, /* Invalid range end. */
+ REG_ESPACE, /* Ran out of memory. */
+ REG_BADRPT, /* No preceding re for repetition op. */
+
+ /* Error codes we've added. */
+ REG_EEND, /* Premature end. */
+ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
+ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
+} reg_errcode_t;
+
+/* This data structure represents a compiled pattern. Before calling
+ the pattern compiler, the fields `buffer', `allocated', `fastmap',
+ `translate', and `no_sub' can be set. After the pattern has been
+ compiled, the `re_nsub' field is available. All other fields are
+ private to the regex routines. */
+
+#ifndef RE_TRANSLATE_TYPE
+# define RE_TRANSLATE_TYPE char *
+#endif
+
+struct re_pattern_buffer
+{
+/* [[[begin pattern_buffer]]] */
+ /* Space that holds the compiled pattern. It is declared as
+ `unsigned char *' because its elements are
+ sometimes used as array indexes. */
+ unsigned char *buffer;
+
+ /* Number of bytes to which `buffer' points. */
+ unsigned long int allocated;
+
+ /* Number of bytes actually used in `buffer'. */
+ unsigned long int used;
+
+ /* Syntax setting with which the pattern was compiled. */
+ reg_syntax_t syntax;
+
+ /* Pointer to a fastmap, if any, otherwise zero. re_search uses
+ the fastmap, if there is one, to skip over impossible
+ starting points for matches. */
+ char *fastmap;
+
+ /* Either a translate table to apply to all characters before
+ comparing them, or zero for no translation. The translation
+ is applied to a pattern when it is compiled and to a string
+ when it is matched. */
+ RE_TRANSLATE_TYPE translate;
+
+ /* Number of subexpressions found by the compiler. */
+ size_t re_nsub;
+
+ /* Zero if this pattern cannot match the empty string, one else.
+ Well, in truth it's used only in `re_search_2', to see
+ whether or not we should use the fastmap, so we don't set
+ this absolutely perfectly; see `re_compile_fastmap' (the
+ `duplicate' case). */
+ unsigned can_be_null : 1;
+
+ /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+ for `max (RE_NREGS, re_nsub + 1)' groups.
+ If REGS_REALLOCATE, reallocate space if necessary.
+ If REGS_FIXED, use what's there. */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+ unsigned regs_allocated : 2;
+
+ /* Set to zero when `regex_compile' compiles a pattern; set to one
+ by `re_compile_fastmap' if it updates the fastmap. */
+ unsigned fastmap_accurate : 1;
+
+ /* If set, `re_match_2' does not return information about
+ subexpressions. */
+ unsigned no_sub : 1;
+
+ /* If set, a beginning-of-line anchor doesn't match at the
+ beginning of the string. */
+ unsigned not_bol : 1;
+
+ /* Similarly for an end-of-line anchor. */
+ unsigned not_eol : 1;
+
+ /* If true, an anchor at a newline matches. */
+ unsigned newline_anchor : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+/* Type for byte offsets within the string. POSIX mandates this. */
+typedef int regoff_t;
+
+
+/* This is the structure we store register match data in. See
+ regex.texinfo for a full description of what registers match. */
+struct re_registers
+{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+ `re_match_2' returns information about at least this many registers
+ the first time a `regs' structure is passed. */
+#ifndef RE_NREGS
+# define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers. Aside from the different names than
+ `re_registers', POSIX uses an array of structures, instead of a
+ structure of arrays. */
+typedef struct
+{
+ regoff_t rm_so; /* Byte offset from string's start to substring's start. */
+ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
+} regmatch_t;
+
+/* Declarations for routines. */
+
+/* To avoid duplicating every routine declaration -- once with a
+ prototype (if we are ANSI), and once without (if we aren't) -- we
+ use the following macro to declare argument types. This
+ unfortunately clutters up the declarations a bit, but I think it's
+ worth it. */
+
+#if __STDC__
+
+# define _RE_ARGS(args) args
+
+#else /* not __STDC__ */
+
+# define _RE_ARGS(args) ()
+
+#endif /* not __STDC__ */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+ You can also simply assign to the `re_syntax_options' variable. */
+extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
+
+/* Compile the regular expression PATTERN, with length LENGTH
+ and syntax given by the global `re_syntax_options', into the buffer
+ BUFFER. Return NULL if successful, and an error string if not. */
+extern const char *re_compile_pattern
+ _RE_ARGS ((const char *pattern, size_t length,
+ struct re_pattern_buffer *buffer));
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+ accelerate searches. Return 0 if successful and -2 if was an
+ internal error. */
+extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+ compiled into BUFFER. Start searching at position START, for RANGE
+ characters. Return the starting position of the match, -1 for no
+ match, or -2 for an internal error. Also return register
+ information in REGS (if REGS and BUFFER->no_sub are nonzero). */
+extern int re_search
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, int range, struct re_registers *regs));
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+ STRING2. Also, stop searching at index START + STOP. */
+extern int re_search_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, int range, struct re_registers *regs, int stop));
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+ in BUFFER matched, starting at position START. */
+extern int re_match
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, struct re_registers *regs));
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
+extern int re_match_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, struct re_registers *regs, int stop));
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using BUFFER and REGS will use this memory
+ for recording register information. STARTS and ENDS must be
+ allocated with malloc, and must each be at least `NUM_REGS * sizeof
+ (regoff_t)' bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+extern void re_set_registers
+ _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
+ unsigned num_regs, regoff_t *starts, regoff_t *ends));
+
+#if defined _REGEX_RE_COMP || defined _LIBC
+# ifndef _CRAY
+/* 4.2 bsd compatibility. */
+extern char *re_comp _RE_ARGS ((const char *));
+extern int re_exec _RE_ARGS ((const char *));
+# endif
+#endif
+
+/* POSIX compatibility. */
+extern int regcomp _RE_ARGS ((regex_t *__preg, const char *__pattern,
+ int __cflags));
+
+extern int regexec _RE_ARGS ((const regex_t *__preg,
+ const char *__string, size_t __nmatch,
+ regmatch_t __pmatch[], int __eflags));
+
+extern size_t regerror _RE_ARGS ((int __errcode, const regex_t *__preg,
+ char *__errbuf, size_t __errbuf_size));
+
+extern void regfree _RE_ARGS ((regex_t *__preg));
+
+
+#ifdef __cplusplus
+}
+#endif /* C++ */
+
+#endif /* regex.h */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/lib/obstack.c b/lib/obstack.c
new file mode 100644
index 00000000..bf18ddc8
--- /dev/null
+++ b/lib/obstack.c
@@ -0,0 +1,485 @@
+/* obstack.c - subroutines used implicitly by object stack macros
+ Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "obstack.h"
+
+/* This is just to get __GNU_LIBRARY__ defined. */
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
+
+
+#if defined (__STDC__) && __STDC__
+#define POINTER void *
+#else
+#define POINTER char *
+#endif
+
+/* Determine default alignment. */
+struct fooalign {char x; double d;};
+#define DEFAULT_ALIGNMENT \
+ ((PTR_INT_TYPE) ((char *)&((struct fooalign *) 0)->d - (char *)0))
+/* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
+ But in fact it might be less smart and round addresses to as much as
+ DEFAULT_ROUNDING. So we prepare for it to do that. */
+union fooround {long x; double d;};
+#define DEFAULT_ROUNDING (sizeof (union fooround))
+
+/* When we copy a long block of data, this is the unit to do it with.
+ On some machines, copying successive ints does not work;
+ in such a case, redefine COPYING_UNIT to `long' (if that works)
+ or `char' as a last resort. */
+#ifndef COPYING_UNIT
+#define COPYING_UNIT int
+#endif
+
+/* The non-GNU-C macros copy the obstack into this global variable
+ to avoid multiple evaluation. */
+
+struct obstack *_obstack;
+
+/* Define a macro that either calls functions with the traditional malloc/free
+ calling interface, or calls functions with the mmalloc/mfree interface
+ (that adds an extra first argument), based on the state of use_extra_arg.
+ For free, do not use ?:, since some compilers, like the MIPS compilers,
+ do not allow (expr) ? void : void. */
+
+#define CALL_CHUNKFUN(h, size) \
+ (((h) -> use_extra_arg) \
+ ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
+ : (*(h)->chunkfun) ((size)))
+
+#define CALL_FREEFUN(h, old_chunk) \
+ do { \
+ if ((h) -> use_extra_arg) \
+ (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
+ else \
+ (*(h)->freefun) ((old_chunk)); \
+ } while (0)
+
+
+/* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
+ Objects start on multiples of ALIGNMENT (0 means use default).
+ CHUNKFUN is the function to use to allocate chunks,
+ and FREEFUN the function to free them.
+
+ Return nonzero if successful, zero if out of memory.
+ To recover from an out of memory error,
+ free up some memory, then call this again. */
+
+int
+_obstack_begin (h, size, alignment, chunkfun, freefun)
+ struct obstack *h;
+ int size;
+ int alignment;
+ POINTER (*chunkfun) ();
+ void (*freefun) ();
+{
+ register struct _obstack_chunk* chunk; /* points to new chunk */
+
+ if (alignment == 0)
+ alignment = DEFAULT_ALIGNMENT;
+ if (size == 0)
+ /* Default size is what GNU malloc can fit in a 4096-byte block. */
+ {
+ /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+ Use the values for range checking, because if range checking is off,
+ the extra bytes won't be missed terribly, but if range checking is on
+ and we used a larger request, a whole extra 4096 bytes would be
+ allocated.
+
+ These number are irrelevant to the new GNU malloc. I suspect it is
+ less sensitive to the size of the request. */
+ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ + 4 + DEFAULT_ROUNDING - 1)
+ & ~(DEFAULT_ROUNDING - 1));
+ size = 4096 - extra;
+ }
+
+ h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
+ h->freefun = freefun;
+ h->chunk_size = size;
+ h->alignment_mask = alignment - 1;
+ h->use_extra_arg = 0;
+
+ chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ {
+ h->alloc_failed = 1;
+ return 0;
+ }
+ h->alloc_failed = 0;
+ h->next_free = h->object_base = chunk->contents;
+ h->chunk_limit = chunk->limit
+ = (char *) chunk + h->chunk_size;
+ chunk->prev = 0;
+ /* The initial chunk now contains no empty object. */
+ h->maybe_empty_object = 0;
+ return 1;
+}
+
+int
+_obstack_begin_1 (h, size, alignment, chunkfun, freefun, arg)
+ struct obstack *h;
+ int size;
+ int alignment;
+ POINTER (*chunkfun) ();
+ void (*freefun) ();
+ POINTER arg;
+{
+ register struct _obstack_chunk* chunk; /* points to new chunk */
+
+ if (alignment == 0)
+ alignment = DEFAULT_ALIGNMENT;
+ if (size == 0)
+ /* Default size is what GNU malloc can fit in a 4096-byte block. */
+ {
+ /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
+ Use the values for range checking, because if range checking is off,
+ the extra bytes won't be missed terribly, but if range checking is on
+ and we used a larger request, a whole extra 4096 bytes would be
+ allocated.
+
+ These number are irrelevant to the new GNU malloc. I suspect it is
+ less sensitive to the size of the request. */
+ int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
+ + 4 + DEFAULT_ROUNDING - 1)
+ & ~(DEFAULT_ROUNDING - 1));
+ size = 4096 - extra;
+ }
+
+ h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun;
+ h->freefun = freefun;
+ h->chunk_size = size;
+ h->alignment_mask = alignment - 1;
+ h->extra_arg = arg;
+ h->use_extra_arg = 1;
+
+ chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
+ if (!chunk)
+ {
+ h->alloc_failed = 1;
+ return 0;
+ }
+ h->alloc_failed = 0;
+ h->next_free = h->object_base = chunk->contents;
+ h->chunk_limit = chunk->limit
+ = (char *) chunk + h->chunk_size;
+ chunk->prev = 0;
+ /* The initial chunk now contains no empty object. */
+ h->maybe_empty_object = 0;
+ return 1;
+}
+
+/* Allocate a new current chunk for the obstack *H
+ on the assumption that LENGTH bytes need to be added
+ to the current object, or a new object of length LENGTH allocated.
+ Copies any partial object from the end of the old chunk
+ to the beginning of the new one. */
+
+void
+_obstack_newchunk (h, length)
+ struct obstack *h;
+ int length;
+{
+ register struct _obstack_chunk* old_chunk = h->chunk;
+ register struct _obstack_chunk* new_chunk;
+ register long new_size;
+ register int obj_size = h->next_free - h->object_base;
+ register int i;
+ int already;
+
+ /* Compute size for new chunk. */
+ new_size = (obj_size + length) + (obj_size >> 3) + 100;
+ if (new_size < h->chunk_size)
+ new_size = h->chunk_size;
+
+ /* Allocate and initialize the new chunk. */
+ new_chunk = CALL_CHUNKFUN (h, new_size);
+ if (!new_chunk)
+ {
+ h->alloc_failed = 1;
+ return;
+ }
+ h->alloc_failed = 0;
+ h->chunk = new_chunk;
+ new_chunk->prev = old_chunk;
+ new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
+
+ /* Move the existing object to the new chunk.
+ Word at a time is fast and is safe if the object
+ is sufficiently aligned. */
+ if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
+ {
+ for (i = obj_size / sizeof (COPYING_UNIT) - 1;
+ i >= 0; i--)
+ ((COPYING_UNIT *)new_chunk->contents)[i]
+ = ((COPYING_UNIT *)h->object_base)[i];
+ /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
+ but that can cross a page boundary on a machine
+ which does not do strict alignment for COPYING_UNITS. */
+ already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
+ }
+ else
+ already = 0;
+ /* Copy remaining bytes one by one. */
+ for (i = already; i < obj_size; i++)
+ new_chunk->contents[i] = h->object_base[i];
+
+ /* If the object just copied was the only data in OLD_CHUNK,
+ free that chunk and remove it from the chain.
+ But not if that chunk might contain an empty object. */
+ if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
+ {
+ new_chunk->prev = old_chunk->prev;
+ CALL_FREEFUN (h, old_chunk);
+ }
+
+ h->object_base = new_chunk->contents;
+ h->next_free = h->object_base + obj_size;
+ /* The new chunk certainly contains no empty object yet. */
+ h->maybe_empty_object = 0;
+}
+
+/* Return nonzero if object OBJ has been allocated from obstack H.
+ This is here for debugging.
+ If you use it in a program, you are probably losing. */
+
+#if defined (__STDC__) && __STDC__
+/* Suppress -Wmissing-prototypes warning. We don't want to declare this in
+ obstack.h because it is just for debugging. */
+int _obstack_allocated_p (struct obstack *h, POINTER obj);
+#endif
+
+int
+_obstack_allocated_p (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk* plp; /* point to previous chunk if any */
+
+ lp = (h)->chunk;
+ /* We use >= rather than > since the object cannot be exactly at
+ the beginning of the chunk but might be an empty object exactly
+ at the end of an adjacent chunk. */
+ while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
+ {
+ plp = lp->prev;
+ lp = plp;
+ }
+ return lp != 0;
+}
+
+/* Free objects in obstack H, including OBJ and everything allocate
+ more recently than OBJ. If OBJ is zero, free everything in H. */
+
+#undef obstack_free
+
+/* This function has two names with identical definitions.
+ This is the first one, called from non-ANSI code. */
+
+void
+_obstack_free (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk* plp; /* point to previous chunk if any */
+
+ lp = h->chunk;
+ /* We use >= because there cannot be an object at the beginning of a chunk.
+ But there can be an empty object at that address
+ at the end of another chunk. */
+ while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
+ {
+ plp = lp->prev;
+ CALL_FREEFUN (h, lp);
+ lp = plp;
+ /* If we switch chunks, we can't tell whether the new current
+ chunk contains an empty object, so assume that it may. */
+ h->maybe_empty_object = 1;
+ }
+ if (lp)
+ {
+ h->object_base = h->next_free = (char *)(obj);
+ h->chunk_limit = lp->limit;
+ h->chunk = lp;
+ }
+ else if (obj != 0)
+ /* obj is not in any of the chunks! */
+ abort ();
+}
+
+/* This function is used from ANSI code. */
+
+void
+obstack_free (h, obj)
+ struct obstack *h;
+ POINTER obj;
+{
+ register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */
+ register struct _obstack_chunk* plp; /* point to previous chunk if any */
+
+ lp = h->chunk;
+ /* We use >= because there cannot be an object at the beginning of a chunk.
+ But there can be an empty object at that address
+ at the end of another chunk. */
+ while (lp != 0 && ((POINTER)lp >= obj || (POINTER)(lp)->limit < obj))
+ {
+ plp = lp->prev;
+ CALL_FREEFUN (h, lp);
+ lp = plp;
+ /* If we switch chunks, we can't tell whether the new current
+ chunk contains an empty object, so assume that it may. */
+ h->maybe_empty_object = 1;
+ }
+ if (lp)
+ {
+ h->object_base = h->next_free = (char *)(obj);
+ h->chunk_limit = lp->limit;
+ h->chunk = lp;
+ }
+ else if (obj != 0)
+ /* obj is not in any of the chunks! */
+ abort ();
+}
+
+#if 0
+/* These are now turned off because the applications do not use it
+ and it uses bcopy via obstack_grow, which causes trouble on sysV. */
+
+/* Now define the functional versions of the obstack macros.
+ Define them to simply use the corresponding macros to do the job. */
+
+#if defined (__STDC__) && __STDC__
+/* These function definitions do not work with non-ANSI preprocessors;
+ they won't pass through the macro names in parentheses. */
+
+/* The function names appear in parentheses in order to prevent
+ the macro-definitions of the names from being expanded there. */
+
+POINTER (obstack_base) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_base (obstack);
+}
+
+POINTER (obstack_next_free) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_next_free (obstack);
+}
+
+int (obstack_object_size) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_object_size (obstack);
+}
+
+int (obstack_room) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_room (obstack);
+}
+
+void (obstack_grow) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ obstack_grow (obstack, pointer, length);
+}
+
+void (obstack_grow0) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ obstack_grow0 (obstack, pointer, length);
+}
+
+void (obstack_1grow) (obstack, character)
+ struct obstack *obstack;
+ int character;
+{
+ obstack_1grow (obstack, character);
+}
+
+void (obstack_blank) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ obstack_blank (obstack, length);
+}
+
+void (obstack_1grow_fast) (obstack, character)
+ struct obstack *obstack;
+ int character;
+{
+ obstack_1grow_fast (obstack, character);
+}
+
+void (obstack_blank_fast) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ obstack_blank_fast (obstack, length);
+}
+
+POINTER (obstack_finish) (obstack)
+ struct obstack *obstack;
+{
+ return obstack_finish (obstack);
+}
+
+POINTER (obstack_alloc) (obstack, length)
+ struct obstack *obstack;
+ int length;
+{
+ return obstack_alloc (obstack, length);
+}
+
+POINTER (obstack_copy) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ return obstack_copy (obstack, pointer, length);
+}
+
+POINTER (obstack_copy0) (obstack, pointer, length)
+ struct obstack *obstack;
+ POINTER pointer;
+ int length;
+{
+ return obstack_copy0 (obstack, pointer, length);
+}
+
+#endif /* __STDC__ */
+
+#endif /* 0 */
+
+#endif /* _LIBC or not __GNU_LIBRARY__. */
diff --git a/lib/obstack.h b/lib/obstack.h
new file mode 100644
index 00000000..2f5ec61a
--- /dev/null
+++ b/lib/obstack.h
@@ -0,0 +1,516 @@
+/* obstack.h - object stack macros
+ Copyright (C) 1988, 89, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Summary:
+
+All the apparent functions defined here are macros. The idea
+is that you would use these pre-tested macros to solve a
+very specific set of problems, and they would run fast.
+Caution: no side-effects in arguments please!! They may be
+evaluated MANY times!!
+
+These macros operate a stack of objects. Each object starts life
+small, and may grow to maturity. (Consider building a word syllable
+by syllable.) An object can move while it is growing. Once it has
+been "finished" it never changes address again. So the "top of the
+stack" is typically an immature growing object, while the rest of the
+stack is of mature, fixed size and fixed address objects.
+
+These routines grab large chunks of memory, using a function you
+supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
+by calling `obstack_chunk_free'. You must define them and declare
+them before using any obstack macros.
+
+Each independent stack is represented by a `struct obstack'.
+Each of the obstack macros expects a pointer to such a structure
+as the first argument.
+
+One motivation for this package is the problem of growing char strings
+in symbol tables. Unless you are "fascist pig with a read-only mind"
+--Gosper's immortal quote from HAKMEM item 154, out of context--you
+would not like to put any arbitrary upper limit on the length of your
+symbols.
+
+In practice this often means you will build many short symbols and a
+few long symbols. At the time you are reading a symbol you don't know
+how long it is. One traditional method is to read a symbol into a
+buffer, realloc()ating the buffer every time you try to read a symbol
+that is longer than the buffer. This is beaut, but you still will
+want to copy the symbol from the buffer to a more permanent
+symbol-table entry say about half the time.
+
+With obstacks, you can work differently. Use one obstack for all symbol
+names. As you read a symbol, grow the name in the obstack gradually.
+When the name is complete, finalize it. Then, if the symbol exists already,
+free the newly read name.
+
+The way we do this is to take a large chunk, allocating memory from
+low addresses. When you want to build a symbol in the chunk you just
+add chars above the current "high water mark" in the chunk. When you
+have finished adding chars, because you got to the end of the symbol,
+you know how long the chars are, and you can create a new object.
+Mostly the chars will not burst over the highest address of the chunk,
+because you would typically expect a chunk to be (say) 100 times as
+long as an average object.
+
+In case that isn't clear, when we have enough chars to make up
+the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
+so we just point to it where it lies. No moving of chars is
+needed and this is the second win: potentially long strings need
+never be explicitly shuffled. Once an object is formed, it does not
+change its address during its lifetime.
+
+When the chars burst over a chunk boundary, we allocate a larger
+chunk, and then copy the partly formed object from the end of the old
+chunk to the beginning of the new larger chunk. We then carry on
+accreting characters to the end of the object as we normally would.
+
+A special macro is provided to add a single char at a time to a
+growing object. This allows the use of register variables, which
+break the ordinary 'growth' macro.
+
+Summary:
+ We allocate large chunks.
+ We carve out one object at a time from the current chunk.
+ Once carved, an object never moves.
+ We are free to append data of any size to the currently
+ growing object.
+ Exactly one object is growing in an obstack at any one time.
+ You can run one obstack per control block.
+ You may have as many control blocks as you dare.
+ Because of the way we do it, you can `unwind' an obstack
+ back to a previous state. (You may remove objects much
+ as you would with a stack.)
+*/
+
+
+/* Don't do the contents of this file more than once. */
+
+#ifndef __OBSTACK_H__
+#define __OBSTACK_H__
+
+/* We use subtraction of (char *)0 instead of casting to int
+ because on word-addressable machines a simple cast to int
+ may ignore the byte-within-word field of the pointer. */
+
+#ifndef __PTR_TO_INT
+#define __PTR_TO_INT(P) ((P) - (char *)0)
+#endif
+
+#ifndef __INT_TO_PTR
+#define __INT_TO_PTR(P) ((P) + (char *)0)
+#endif
+
+/* We need the type of the resulting object. In ANSI C it is ptrdiff_t
+ but in traditional C it is usually long. If we are in ANSI C and
+ don't already have ptrdiff_t get it. */
+
+#if defined (__STDC__) && __STDC__ && ! defined (offsetof)
+#if defined (__GNUC__) && defined (IN_GCC)
+/* On Next machine, the system's stddef.h screws up if included
+ after we have defined just ptrdiff_t, so include all of stddef.h.
+ Otherwise, define just ptrdiff_t, which is all we need. */
+#ifndef __NeXT__
+#define __need_ptrdiff_t
+#endif
+#endif
+
+#include <stddef.h>
+#endif
+
+#if defined (__STDC__) && __STDC__
+#define PTR_INT_TYPE ptrdiff_t
+#else
+#define PTR_INT_TYPE long
+#endif
+
+struct _obstack_chunk /* Lives at front of each chunk. */
+{
+ char *limit; /* 1 past end of this chunk */
+ struct _obstack_chunk *prev; /* address of prior chunk or NULL */
+ char contents[4]; /* objects begin here */
+};
+
+struct obstack /* control current object in current chunk */
+{
+ long chunk_size; /* preferred size to allocate chunks in */
+ struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */
+ char *object_base; /* address of object we are building */
+ char *next_free; /* where to add next char to current object */
+ char *chunk_limit; /* address of char after current chunk */
+ PTR_INT_TYPE temp; /* Temporary for some macros. */
+ int alignment_mask; /* Mask of alignment for each object. */
+ struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */
+ void (*freefun) (); /* User's function to free a chunk. */
+ char *extra_arg; /* first arg for chunk alloc/dealloc funcs */
+ unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
+ unsigned maybe_empty_object:1;/* There is a possibility that the current
+ chunk contains a zero-length object. This
+ prevents freeing the chunk if we allocate
+ a bigger chunk to replace it. */
+ unsigned alloc_failed:1; /* chunk alloc func returned 0 */
+};
+
+/* Declare the external functions we use; they are in obstack.c. */
+
+#if defined (__STDC__) && __STDC__
+extern void _obstack_newchunk (struct obstack *, int);
+extern void _obstack_free (struct obstack *, void *);
+extern int _obstack_begin (struct obstack *, int, int,
+ void *(*) (), void (*) ());
+extern int _obstack_begin_1 (struct obstack *, int, int,
+ void *(*) (), void (*) (), void *);
+#else
+extern void _obstack_newchunk ();
+extern void _obstack_free ();
+extern int _obstack_begin ();
+extern int _obstack_begin_1 ();
+#endif
+
+#if defined (__STDC__) && __STDC__
+
+/* Do the function-declarations after the structs
+ but before defining the macros. */
+
+void obstack_init (struct obstack *obstack);
+
+void * obstack_alloc (struct obstack *obstack, int size);
+
+void * obstack_copy (struct obstack *obstack, void *address, int size);
+void * obstack_copy0 (struct obstack *obstack, void *address, int size);
+
+void obstack_free (struct obstack *obstack, void *block);
+
+void obstack_blank (struct obstack *obstack, int size);
+
+void obstack_grow (struct obstack *obstack, void *data, int size);
+void obstack_grow0 (struct obstack *obstack, void *data, int size);
+
+void obstack_1grow (struct obstack *obstack, int data_char);
+void obstack_ptr_grow (struct obstack *obstack, void *data);
+void obstack_int_grow (struct obstack *obstack, int data);
+
+void * obstack_finish (struct obstack *obstack);
+
+int obstack_object_size (struct obstack *obstack);
+
+int obstack_room (struct obstack *obstack);
+void obstack_1grow_fast (struct obstack *obstack, int data_char);
+void obstack_ptr_grow_fast (struct obstack *obstack, void *data);
+void obstack_int_grow_fast (struct obstack *obstack, int data);
+void obstack_blank_fast (struct obstack *obstack, int size);
+
+void * obstack_base (struct obstack *obstack);
+void * obstack_next_free (struct obstack *obstack);
+int obstack_alignment_mask (struct obstack *obstack);
+int obstack_chunk_size (struct obstack *obstack);
+
+#endif /* __STDC__ */
+
+/* Non-ANSI C cannot really support alternative functions for these macros,
+ so we do not declare them. */
+
+/* Pointer to beginning of object being allocated or to be allocated next.
+ Note that this might not be the final address of the object
+ because a new chunk might be needed to hold the final size. */
+
+#define obstack_base(h) ((h)->alloc_failed ? 0 : (h)->object_base)
+
+/* Size for allocating ordinary chunks. */
+
+#define obstack_chunk_size(h) ((h)->chunk_size)
+
+/* Pointer to next byte not yet allocated in current chunk. */
+
+#define obstack_next_free(h) ((h)->alloc_failed ? 0 : (h)->next_free)
+
+/* Mask specifying low bits that should be clear in address of an object. */
+
+#define obstack_alignment_mask(h) ((h)->alignment_mask)
+
+#define obstack_init(h) \
+ _obstack_begin ((h), 0, 0, \
+ (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
+
+#define obstack_begin(h, size) \
+ _obstack_begin ((h), (size), 0, \
+ (void *(*) ()) obstack_chunk_alloc, (void (*) ()) obstack_chunk_free)
+
+#define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
+ _obstack_begin ((h), (size), (alignment), \
+ (void *(*) ()) (chunkfun), (void (*) ()) (freefun))
+
+#define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
+ _obstack_begin_1 ((h), (size), (alignment), \
+ (void *(*) ()) (chunkfun), (void (*) ()) (freefun), (arg))
+
+#define obstack_chunkfun(h, newchunkfun) \
+ ((h) -> chunkfun = (struct _obstack_chunk *(*)()) (newchunkfun))
+
+#define obstack_freefun(h, newfreefun) \
+ ((h) -> freefun = (void (*)()) (newfreefun))
+
+#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar)
+
+#define obstack_blank_fast(h,n) ((h)->next_free += (n))
+
+#if defined (__GNUC__) && defined (__STDC__)
+/* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
+ does not implement __extension__. But that compiler doesn't define
+ __GNUC_MINOR__. */
+#if __GNUC__ < 2 || (NeXt && !__GNUC_MINOR__)
+#define __extension__
+#endif
+
+/* For GNU C, if not -traditional,
+ we can define these macros to compute all args only once
+ without using a global variable.
+ Also, we can avoid using the `temp' slot, to make faster code. */
+
+#define obstack_object_size(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ __o->alloc_failed ? 0 : \
+ (unsigned) (__o->next_free - __o->object_base); })
+
+#define obstack_room(OBSTACK) \
+ __extension__ \
+ ({ struct obstack *__o = (OBSTACK); \
+ (unsigned) (__o->chunk_limit - __o->next_free); })
+
+#define obstack_grow(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->next_free + __len > __o->chunk_limit) \
+ _obstack_newchunk (__o, __len); \
+ if (!__o->alloc_failed) \
+ { \
+ bcopy ((char *) (where), __o->next_free, __len); \
+ __o->next_free += __len; \
+ } \
+ (void) 0; })
+
+#define obstack_grow0(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->next_free + __len + 1 > __o->chunk_limit) \
+ _obstack_newchunk (__o, __len + 1); \
+ if (!__o->alloc_failed) \
+ { \
+ bcopy ((char *) (where), __o->next_free, __len); \
+ __o->next_free += __len; \
+ *(__o->next_free)++ = 0; \
+ } \
+ (void) 0; })
+
+#define obstack_1grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + 1 > __o->chunk_limit) \
+ _obstack_newchunk (__o, 1); \
+ if (!__o->alloc_failed) \
+ *(__o->next_free)++ = (datum); \
+ (void) 0; })
+
+/* These assume that the obstack alignment is good enough for pointers or ints,
+ and that the data added so far to the current object
+ shares that much alignment. */
+
+#define obstack_ptr_grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
+ _obstack_newchunk (__o, sizeof (void *)); \
+ if (!__o->alloc_failed) \
+ *((void **)__o->next_free)++ = ((void *)datum); \
+ (void) 0; })
+
+#define obstack_int_grow(OBSTACK,datum) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ if (__o->next_free + sizeof (int) > __o->chunk_limit) \
+ _obstack_newchunk (__o, sizeof (int)); \
+ if (!__o->alloc_failed) \
+ *((int *)__o->next_free)++ = ((int)datum); \
+ (void) 0; })
+
+#define obstack_ptr_grow_fast(h,aptr) (*((void **)(h)->next_free)++ = (void *)aptr)
+#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
+
+#define obstack_blank(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ int __len = (length); \
+ if (__o->chunk_limit - __o->next_free < __len) \
+ _obstack_newchunk (__o, __len); \
+ if (!__o->alloc_failed) \
+ __o->next_free += __len; \
+ (void) 0; })
+
+#define obstack_alloc(OBSTACK,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_blank (__h, (length)); \
+ obstack_finish (__h); })
+
+#define obstack_copy(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_grow (__h, (where), (length)); \
+ obstack_finish (__h); })
+
+#define obstack_copy0(OBSTACK,where,length) \
+__extension__ \
+({ struct obstack *__h = (OBSTACK); \
+ obstack_grow0 (__h, (where), (length)); \
+ obstack_finish (__h); })
+
+/* The local variable is named __o1 to avoid a name conflict
+ when obstack_blank is called. */
+#define obstack_finish(OBSTACK) \
+__extension__ \
+({ struct obstack *__o1 = (OBSTACK); \
+ void *value; \
+ if (__o1->alloc_failed) \
+ value = 0; \
+ else \
+ { \
+ value = (void *) __o1->object_base; \
+ if (__o1->next_free == value) \
+ __o1->maybe_empty_object = 1; \
+ __o1->next_free \
+ = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
+ & ~ (__o1->alignment_mask)); \
+ if (__o1->next_free - (char *)__o1->chunk \
+ > __o1->chunk_limit - (char *)__o1->chunk) \
+ __o1->next_free = __o1->chunk_limit; \
+ __o1->object_base = __o1->next_free; \
+ } \
+ value; })
+
+#define obstack_free(OBSTACK, OBJ) \
+__extension__ \
+({ struct obstack *__o = (OBSTACK); \
+ void *__obj = (OBJ); \
+ if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
+ __o->next_free = __o->object_base = __obj; \
+ else (obstack_free) (__o, __obj); })
+
+#else /* not __GNUC__ or not __STDC__ */
+
+#define obstack_object_size(h) \
+ (unsigned) ((h)->alloc_failed ? 0 : (h)->next_free - (h)->object_base)
+
+#define obstack_room(h) \
+ (unsigned) ((h)->chunk_limit - (h)->next_free)
+
+/* Note that the call to _obstack_newchunk is enclosed in (..., 0)
+ so that we can avoid having void expressions
+ in the arms of the conditional expression.
+ Casting the third operand to void was tried before,
+ but some compilers won't accept it. */
+
+#define obstack_grow(h,where,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
+ ((h)->alloc_failed ? 0 : \
+ (bcopy ((char *) (where), (h)->next_free, (h)->temp), \
+ (h)->next_free += (h)->temp)))
+
+#define obstack_grow0(h,where,length) \
+( (h)->temp = (length), \
+ (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0), \
+ ((h)->alloc_failed ? 0 : \
+ (bcopy ((char *) (where), (h)->next_free, (h)->temp), \
+ (h)->next_free += (h)->temp, \
+ *((h)->next_free)++ = 0)))
+
+#define obstack_1grow(h,datum) \
+( (((h)->next_free + 1 > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), 1), 0) : 0), \
+ ((h)->alloc_failed ? 0 : \
+ (*((h)->next_free)++ = (datum))))
+
+#define obstack_ptr_grow(h,datum) \
+( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
+ ((h)->alloc_failed ? 0 : \
+ (*((char **)(((h)->next_free+=sizeof(char *))-sizeof(char *))) = ((char *)datum))))
+
+#define obstack_int_grow(h,datum) \
+( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
+ ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
+ ((h)->alloc_failed ? 0 : \
+ (*((int *)(((h)->next_free+=sizeof(int))-sizeof(int))) = ((int)datum))))
+
+#define obstack_ptr_grow_fast(h,aptr) (*((char **)(h)->next_free)++ = (char *)aptr)
+#define obstack_int_grow_fast(h,aint) (*((int *)(h)->next_free)++ = (int)aint)
+
+#define obstack_blank(h,length) \
+( (h)->temp = (length), \
+ (((h)->chunk_limit - (h)->next_free < (h)->temp) \
+ ? (_obstack_newchunk ((h), (h)->temp), 0) : 0), \
+ ((h)->alloc_failed ? 0 : \
+ ((h)->next_free += (h)->temp)))
+
+#define obstack_alloc(h,length) \
+ (obstack_blank ((h), (length)), obstack_finish ((h)))
+
+#define obstack_copy(h,where,length) \
+ (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
+
+#define obstack_copy0(h,where,length) \
+ (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
+
+#define obstack_finish(h) \
+( (h)->alloc_failed ? 0 : \
+ (((h)->next_free == (h)->object_base \
+ ? (((h)->maybe_empty_object = 1), 0) \
+ : 0), \
+ (h)->temp = __PTR_TO_INT ((h)->object_base), \
+ (h)->next_free \
+ = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask) \
+ & ~ ((h)->alignment_mask)), \
+ (((h)->next_free - (char *)(h)->chunk \
+ > (h)->chunk_limit - (char *)(h)->chunk) \
+ ? ((h)->next_free = (h)->chunk_limit) : 0), \
+ (h)->object_base = (h)->next_free, \
+ __INT_TO_PTR ((h)->temp)))
+
+#if defined (__STDC__) && __STDC__
+#define obstack_free(h,obj) \
+( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \
+ (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+ ? (int) ((h)->next_free = (h)->object_base \
+ = (h)->temp + (char *) (h)->chunk) \
+ : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
+#else
+#define obstack_free(h,obj) \
+( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \
+ (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
+ ? (int) ((h)->next_free = (h)->object_base \
+ = (h)->temp + (char *) (h)->chunk) \
+ : (_obstack_free ((h), (h)->temp + (char *) (h)->chunk), 0)))
+#endif
+
+#endif /* not __GNUC__ or not __STDC__ */
+
+#endif /* not __OBSTACK_H__ */
diff --git a/lib/regex.c b/lib/regex.c
new file mode 100644
index 00000000..33c7ea24
--- /dev/null
+++ b/lib/regex.c
@@ -0,0 +1,5244 @@
+/* Extended regular expression matching and search library,
+ version 0.12.
+ (Implements POSIX draft P10003.2/D11.2, except for
+ internationalization features.)
+
+ Copyright (C) 1993, 1994 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* AIX requires this to be the first thing in the file. */
+#if defined (_AIX) && !defined (REGEX_MALLOC)
+ #pragma alloca
+#endif
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* We need this for `regex.h', and perhaps for the Emacs include files. */
+#include <sys/types.h>
+
+/* The `emacs' switch turns on certain matching commands
+ that make sense only in Emacs. */
+#ifdef emacs
+
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+
+/* Emacs uses `NULL' as a predicate. */
+#undef NULL
+
+#else /* not emacs */
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+char *malloc ();
+char *realloc ();
+#endif
+
+
+/* We used to test for `BSTRING' here, but only GCC and Emacs define
+ `BSTRING', as far as I know, and neither of them use this code. */
+#ifndef INHIBIT_STRING_HEADER
+#if HAVE_STRING_H || STDC_HEADERS
+#include <string.h>
+#ifndef bcmp
+#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
+#endif
+#ifndef bcopy
+#define bcopy(s, d, n) memcpy ((d), (s), (n))
+#endif
+#ifndef bzero
+#define bzero(s, n) memset ((s), 0, (n))
+#endif
+#else
+#include <strings.h>
+#endif
+#endif
+
+/* Define the syntax stuff for \<, \>, etc. */
+
+/* This must be nonzero for the wordchar and notwordchar pattern
+ commands in re_match_2. */
+#ifndef Sword
+#define Sword 1
+#endif
+
+#ifdef SYNTAX_TABLE
+
+extern char *re_syntax_table;
+
+#else /* not SYNTAX_TABLE */
+
+/* How many characters in the character set. */
+#define CHAR_SET_SIZE 256
+
+static char re_syntax_table[CHAR_SET_SIZE];
+
+static void
+init_syntax_once ()
+{
+ register int c;
+ static int done = 0;
+
+ if (done)
+ return;
+
+ bzero (re_syntax_table, sizeof re_syntax_table);
+
+ for (c = 'a'; c <= 'z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = 'A'; c <= 'Z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = '0'; c <= '9'; c++)
+ re_syntax_table[c] = Sword;
+
+ re_syntax_table['_'] = Sword;
+
+ done = 1;
+}
+
+#endif /* not SYNTAX_TABLE */
+
+#define SYNTAX(c) re_syntax_table[c]
+
+#endif /* not emacs */
+
+/* Get the interface, including the syntax bits. */
+#include "regex.h"
+
+/* isalpha etc. are used for the character classes. */
+#include <ctype.h>
+
+/* Jim Meyering writes:
+
+ "... Some ctype macros are valid only for character codes that
+ isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
+ using /bin/cc or gcc but without giving an ansi option). So, all
+ ctype uses should be through macros like ISPRINT... If
+ STDC_HEADERS is defined, then autoconf has verified that the ctype
+ macros don't need to be guarded with references to isascii. ...
+ Defining isascii to 1 should let any compiler worth its salt
+ eliminate the && through constant folding." */
+
+#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
+#define ISASCII(c) 1
+#else
+#define ISASCII(c) isascii(c)
+#endif
+
+#ifdef isblank
+#define ISBLANK(c) (ISASCII (c) && isblank (c))
+#else
+#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+#ifdef isgraph
+#define ISGRAPH(c) (ISASCII (c) && isgraph (c))
+#else
+#define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
+#endif
+
+#define ISPRINT(c) (ISASCII (c) && isprint (c))
+#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
+#define ISALNUM(c) (ISASCII (c) && isalnum (c))
+#define ISALPHA(c) (ISASCII (c) && isalpha (c))
+#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
+#define ISLOWER(c) (ISASCII (c) && islower (c))
+#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
+#define ISSPACE(c) (ISASCII (c) && isspace (c))
+#define ISUPPER(c) (ISASCII (c) && isupper (c))
+#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* We remove any previous definition of `SIGN_EXTEND_CHAR',
+ since ours (we hope) works properly with all combinations of
+ machines, compilers, `char' and `unsigned char' argument types.
+ (Per Bothner suggested the basic approach.) */
+#undef SIGN_EXTEND_CHAR
+#if __STDC__
+#define SIGN_EXTEND_CHAR(c) ((signed char) (c))
+#else /* not __STDC__ */
+/* As in Harbison and Steele. */
+#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
+#endif
+
+/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
+ use `alloca' instead of `malloc'. This is because using malloc in
+ re_search* or re_match* could cause memory leaks when C-g is used in
+ Emacs; also, malloc is slower and causes storage fragmentation. On
+ the other hand, malloc is more portable, and easier to debug.
+
+ Because we sometimes use alloca, some routines have to be macros,
+ not functions -- `alloca'-allocated space disappears at the end of the
+ function it is called in. */
+
+#ifdef REGEX_MALLOC
+
+#define REGEX_ALLOCATE malloc
+#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
+
+#else /* not REGEX_MALLOC */
+
+/* Emacs already defines alloca, sometimes. */
+#ifndef alloca
+
+/* Make alloca work the best possible way. */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* not __GNUC__ or HAVE_ALLOCA_H */
+#ifndef _AIX /* Already did AIX, up at the top. */
+char *alloca ();
+#endif /* not _AIX */
+#endif /* not HAVE_ALLOCA_H */
+#endif /* not __GNUC__ */
+
+#endif /* not alloca */
+
+#define REGEX_ALLOCATE alloca
+
+/* Assumes a `char *destination' variable. */
+#define REGEX_REALLOCATE(source, osize, nsize) \
+ (destination = (char *) alloca (nsize), \
+ bcopy (source, destination, osize), \
+ destination)
+
+#endif /* not REGEX_MALLOC */
+
+
+/* True if `size1' is non-NULL and PTR is pointing anywhere inside
+ `string1' or just past its end. This works if PTR is NULL, which is
+ a good thing. */
+#define FIRST_STRING_P(ptr) \
+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
+
+/* (Re)Allocate N items of type T using malloc, or fail. */
+#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
+#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
+#define RETALLOC_IF(addr, n, t) \
+ if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
+#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
+
+#define BYTEWIDTH 8 /* In bits. */
+
+#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
+
+#undef MAX
+#undef MIN
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+typedef char boolean;
+#define false 0
+#define true 1
+
+static int re_match_2_internal ();
+
+/* These are the command codes that appear in compiled regular
+ expressions. Some opcodes are followed by argument bytes. A
+ command code can specify any interpretation whatsoever for its
+ arguments. Zero bytes may appear in the compiled regular expression. */
+
+typedef enum
+{
+ no_op = 0,
+
+ /* Followed by one byte giving n, then by n literal bytes. */
+ exactn,
+
+ /* Matches any (more or less) character. */
+ anychar,
+
+ /* Matches any one char belonging to specified set. First
+ following byte is number of bitmap bytes. Then come bytes
+ for a bitmap saying which chars are in. Bits in each byte
+ are ordered low-bit-first. A character is in the set if its
+ bit is 1. A character too large to have a bit in the map is
+ automatically not in the set. */
+ charset,
+
+ /* Same parameters as charset, but match any character that is
+ not one of those specified. */
+ charset_not,
+
+ /* Start remembering the text that is matched, for storing in a
+ register. Followed by one byte with the register number, in
+ the range 0 to one less than the pattern buffer's re_nsub
+ field. Then followed by one byte with the number of groups
+ inner to this one. (This last has to be part of the
+ start_memory only because we need it in the on_failure_jump
+ of re_match_2.) */
+ start_memory,
+
+ /* Stop remembering the text that is matched and store it in a
+ memory register. Followed by one byte with the register
+ number, in the range 0 to one less than `re_nsub' in the
+ pattern buffer, and one byte with the number of inner groups,
+ just like `start_memory'. (We need the number of inner
+ groups here because we don't have any easy way of finding the
+ corresponding start_memory when we're at a stop_memory.) */
+ stop_memory,
+
+ /* Match a duplicate of something remembered. Followed by one
+ byte containing the register number. */
+ duplicate,
+
+ /* Fail unless at beginning of line. */
+ begline,
+
+ /* Fail unless at end of line. */
+ endline,
+
+ /* Succeeds if at beginning of buffer (if emacs) or at beginning
+ of string to be matched (if not). */
+ begbuf,
+
+ /* Analogously, for end of buffer/string. */
+ endbuf,
+
+ /* Followed by two byte relative address to which to jump. */
+ jump,
+
+ /* Same as jump, but marks the end of an alternative. */
+ jump_past_alt,
+
+ /* Followed by two-byte relative address of place to resume at
+ in case of failure. */
+ on_failure_jump,
+
+ /* Like on_failure_jump, but pushes a placeholder instead of the
+ current string position when executed. */
+ on_failure_keep_string_jump,
+
+ /* Throw away latest failure point and then jump to following
+ two-byte relative address. */
+ pop_failure_jump,
+
+ /* Change to pop_failure_jump if know won't have to backtrack to
+ match; otherwise change to jump. This is used to jump
+ back to the beginning of a repeat. If what follows this jump
+ clearly won't match what the repeat does, such that we can be
+ sure that there is no use backtracking out of repetitions
+ already matched, then we change it to a pop_failure_jump.
+ Followed by two-byte address. */
+ maybe_pop_jump,
+
+ /* Jump to following two-byte address, and push a dummy failure
+ point. This failure point will be thrown away if an attempt
+ is made to use it for a failure. A `+' construct makes this
+ before the first repeat. Also used as an intermediary kind
+ of jump when compiling an alternative. */
+ dummy_failure_jump,
+
+ /* Push a dummy failure point and continue. Used at the end of
+ alternatives. */
+ push_dummy_failure,
+
+ /* Followed by two-byte relative address and two-byte number n.
+ After matching N times, jump to the address upon failure. */
+ succeed_n,
+
+ /* Followed by two-byte relative address, and two-byte number n.
+ Jump to the address N times, then fail. */
+ jump_n,
+
+ /* Set the following two-byte relative address to the
+ subsequent two-byte number. The address *includes* the two
+ bytes of number. */
+ set_number_at,
+
+ wordchar, /* Matches any word-constituent character. */
+ notwordchar, /* Matches any char that is not a word-constituent. */
+
+ wordbeg, /* Succeeds if at word beginning. */
+ wordend, /* Succeeds if at word end. */
+
+ wordbound, /* Succeeds if at a word boundary. */
+ notwordbound /* Succeeds if not at a word boundary. */
+
+#ifdef emacs
+ ,before_dot, /* Succeeds if before point. */
+ at_dot, /* Succeeds if at point. */
+ after_dot, /* Succeeds if after point. */
+
+ /* Matches any character whose syntax is specified. Followed by
+ a byte which contains a syntax code, e.g., Sword. */
+ syntaxspec,
+
+ /* Matches any character whose syntax is not that specified. */
+ notsyntaxspec
+#endif /* emacs */
+} re_opcode_t;
+
+/* Common operations on the compiled pattern. */
+
+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
+
+#define STORE_NUMBER(destination, number) \
+ do { \
+ (destination)[0] = (number) & 0377; \
+ (destination)[1] = (number) >> 8; \
+ } while (0)
+
+/* Same as STORE_NUMBER, except increment DESTINATION to
+ the byte after where the number is stored. Therefore, DESTINATION
+ must be an lvalue. */
+
+#define STORE_NUMBER_AND_INCR(destination, number) \
+ do { \
+ STORE_NUMBER (destination, number); \
+ (destination) += 2; \
+ } while (0)
+
+/* Put into DESTINATION a number stored in two contiguous bytes starting
+ at SOURCE. */
+
+#define EXTRACT_NUMBER(destination, source) \
+ do { \
+ (destination) = *(source) & 0377; \
+ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
+ } while (0)
+
+#ifdef DEBUG
+static void
+extract_number (dest, source)
+ int *dest;
+ unsigned char *source;
+{
+ int temp = SIGN_EXTEND_CHAR (*(source + 1));
+ *dest = *source & 0377;
+ *dest += temp << 8;
+}
+
+#ifndef EXTRACT_MACROS /* To debug the macros. */
+#undef EXTRACT_NUMBER
+#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
+#endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
+ SOURCE must be an lvalue. */
+
+#define EXTRACT_NUMBER_AND_INCR(destination, source) \
+ do { \
+ EXTRACT_NUMBER (destination, source); \
+ (source) += 2; \
+ } while (0)
+
+#ifdef DEBUG
+static void
+extract_number_and_incr (destination, source)
+ int *destination;
+ unsigned char **source;
+{
+ extract_number (destination, *source);
+ *source += 2;
+}
+
+#ifndef EXTRACT_MACROS
+#undef EXTRACT_NUMBER_AND_INCR
+#define EXTRACT_NUMBER_AND_INCR(dest, src) \
+ extract_number_and_incr (&dest, &src)
+#endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* If DEBUG is defined, Regex prints many voluminous messages about what
+ it is doing (if the variable `debug' is nonzero). If linked with the
+ main program in `iregex.c', you can enter patterns and strings
+ interactively. And if linked with the main program in `main.c' and
+ the other test files, you can run the already-written tests. */
+
+#ifdef DEBUG
+
+/* We use standard I/O for debugging. */
+#include <stdio.h>
+
+/* It is useful to test things that ``must'' be true when debugging. */
+#include <assert.h>
+
+static int debug = 0;
+
+#define DEBUG_STATEMENT(e) e
+#define DEBUG_PRINT1(x) if (debug) printf (x)
+#define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
+#define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
+#define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
+ if (debug) print_partial_compiled_pattern (s, e)
+#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
+ if (debug) print_double_string (w, s1, sz1, s2, sz2)
+
+
+extern void printchar ();
+
+/* Print the fastmap in human-readable form. */
+
+void
+print_fastmap (fastmap)
+ char *fastmap;
+{
+ unsigned was_a_range = 0;
+ unsigned i = 0;
+
+ while (i < (1 << BYTEWIDTH))
+ {
+ if (fastmap[i++])
+ {
+ was_a_range = 0;
+ printchar (i - 1);
+ while (i < (1 << BYTEWIDTH) && fastmap[i])
+ {
+ was_a_range = 1;
+ i++;
+ }
+ if (was_a_range)
+ {
+ printf ("-");
+ printchar (i - 1);
+ }
+ }
+ }
+ putchar ('\n');
+}
+
+
+/* Print a compiled pattern string in human-readable form, starting at
+ the START pointer into it and ending just before the pointer END. */
+
+void
+print_partial_compiled_pattern (start, end)
+ unsigned char *start;
+ unsigned char *end;
+{
+ int mcnt, mcnt2;
+ unsigned char *p = start;
+ unsigned char *pend = end;
+
+ if (start == NULL)
+ {
+ printf ("(null)\n");
+ return;
+ }
+
+ /* Loop over pattern commands. */
+ while (p < pend)
+ {
+ printf ("%d:\t", p - start);
+
+ switch ((re_opcode_t) *p++)
+ {
+ case no_op:
+ printf ("/no_op");
+ break;
+
+ case exactn:
+ mcnt = *p++;
+ printf ("/exactn/%d", mcnt);
+ do
+ {
+ putchar ('/');
+ printchar (*p++);
+ }
+ while (--mcnt);
+ break;
+
+ case start_memory:
+ mcnt = *p++;
+ printf ("/start_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case stop_memory:
+ mcnt = *p++;
+ printf ("/stop_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case duplicate:
+ printf ("/duplicate/%d", *p++);
+ break;
+
+ case anychar:
+ printf ("/anychar");
+ break;
+
+ case charset:
+ case charset_not:
+ {
+ register int c, last = -100;
+ register int in_range = 0;
+
+ printf ("/charset [%s",
+ (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
+
+ assert (p + *p < pend);
+
+ for (c = 0; c < 256; c++)
+ if (c / 8 < *p
+ && (p[1 + (c/8)] & (1 << (c % 8))))
+ {
+ /* Are we starting a range? */
+ if (last + 1 == c && ! in_range)
+ {
+ putchar ('-');
+ in_range = 1;
+ }
+ /* Have we broken a range? */
+ else if (last + 1 != c && in_range)
+ {
+ printchar (last);
+ in_range = 0;
+ }
+
+ if (! in_range)
+ printchar (c);
+
+ last = c;
+ }
+
+ if (in_range)
+ printchar (last);
+
+ putchar (']');
+
+ p += 1 + *p;
+ }
+ break;
+
+ case begline:
+ printf ("/begline");
+ break;
+
+ case endline:
+ printf ("/endline");
+ break;
+
+ case on_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case on_failure_keep_string_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_keep_string_jump to %d", p + mcnt - start);
+ break;
+
+ case dummy_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/dummy_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case push_dummy_failure:
+ printf ("/push_dummy_failure");
+ break;
+
+ case maybe_pop_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/maybe_pop_jump to %d", p + mcnt - start);
+ break;
+
+ case pop_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/pop_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case jump_past_alt:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump_past_alt to %d", p + mcnt - start);
+ break;
+
+ case jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump to %d", p + mcnt - start);
+ break;
+
+ case succeed_n:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/succeed_n to %d, %d times", p + mcnt - start, mcnt2);
+ break;
+
+ case jump_n:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/jump_n to %d, %d times", p + mcnt - start, mcnt2);
+ break;
+
+ case set_number_at:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/set_number_at location %d to %d", p + mcnt - start, mcnt2);
+ break;
+
+ case wordbound:
+ printf ("/wordbound");
+ break;
+
+ case notwordbound:
+ printf ("/notwordbound");
+ break;
+
+ case wordbeg:
+ printf ("/wordbeg");
+ break;
+
+ case wordend:
+ printf ("/wordend");
+
+#ifdef emacs
+ case before_dot:
+ printf ("/before_dot");
+ break;
+
+ case at_dot:
+ printf ("/at_dot");
+ break;
+
+ case after_dot:
+ printf ("/after_dot");
+ break;
+
+ case syntaxspec:
+ printf ("/syntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+
+ case notsyntaxspec:
+ printf ("/notsyntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+#endif /* emacs */
+
+ case wordchar:
+ printf ("/wordchar");
+ break;
+
+ case notwordchar:
+ printf ("/notwordchar");
+ break;
+
+ case begbuf:
+ printf ("/begbuf");
+ break;
+
+ case endbuf:
+ printf ("/endbuf");
+ break;
+
+ default:
+ printf ("?%d", *(p-1));
+ }
+
+ putchar ('\n');
+ }
+
+ printf ("%d:\tend of pattern.\n", p - start);
+}
+
+
+void
+print_compiled_pattern (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ unsigned char *buffer = bufp->buffer;
+
+ print_partial_compiled_pattern (buffer, buffer + bufp->used);
+ printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated);
+
+ if (bufp->fastmap_accurate && bufp->fastmap)
+ {
+ printf ("fastmap: ");
+ print_fastmap (bufp->fastmap);
+ }
+
+ printf ("re_nsub: %d\t", bufp->re_nsub);
+ printf ("regs_alloc: %d\t", bufp->regs_allocated);
+ printf ("can_be_null: %d\t", bufp->can_be_null);
+ printf ("newline_anchor: %d\n", bufp->newline_anchor);
+ printf ("no_sub: %d\t", bufp->no_sub);
+ printf ("not_bol: %d\t", bufp->not_bol);
+ printf ("not_eol: %d\t", bufp->not_eol);
+ printf ("syntax: %d\n", bufp->syntax);
+ /* Perhaps we should print the translate table? */
+}
+
+
+void
+print_double_string (where, string1, size1, string2, size2)
+ const char *where;
+ const char *string1;
+ const char *string2;
+ int size1;
+ int size2;
+{
+ unsigned this_char;
+
+ if (where == NULL)
+ printf ("(null)");
+ else
+ {
+ if (FIRST_STRING_P (where))
+ {
+ for (this_char = where - string1; this_char < size1; this_char++)
+ printchar (string1[this_char]);
+
+ where = string2;
+ }
+
+ for (this_char = where - string2; this_char < size2; this_char++)
+ printchar (string2[this_char]);
+ }
+}
+
+#else /* not DEBUG */
+
+#undef assert
+#define assert(e)
+
+#define DEBUG_STATEMENT(e)
+#define DEBUG_PRINT1(x)
+#define DEBUG_PRINT2(x1, x2)
+#define DEBUG_PRINT3(x1, x2, x3)
+#define DEBUG_PRINT4(x1, x2, x3, x4)
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
+#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
+
+#endif /* not DEBUG */
+
+/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
+ also be assigned to arbitrarily: each pattern buffer stores its own
+ syntax, so it can be changed between regex compilations. */
+reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS;
+
+
+/* Specify the precise syntax of regexps for compilation. This provides
+ for compatibility for various utilities which historically have
+ different, incompatible syntaxes.
+
+ The argument SYNTAX is a bit mask comprised of the various bits
+ defined in regex.h. We return the old syntax. */
+
+reg_syntax_t
+re_set_syntax (syntax)
+ reg_syntax_t syntax;
+{
+ reg_syntax_t ret = re_syntax_options;
+
+ re_syntax_options = syntax;
+ return ret;
+}
+
+/* This table gives an error message for each of the error codes listed
+ in regex.h. Obviously the order here has to be same as there. */
+
+static const char *re_error_msg[] =
+ { NULL, /* REG_NOERROR */
+ "No match", /* REG_NOMATCH */
+ "Invalid regular expression", /* REG_BADPAT */
+ "Invalid collation character", /* REG_ECOLLATE */
+ "Invalid character class name", /* REG_ECTYPE */
+ "Trailing backslash", /* REG_EESCAPE */
+ "Invalid back reference", /* REG_ESUBREG */
+ "Unmatched [ or [^", /* REG_EBRACK */
+ "Unmatched ( or \\(", /* REG_EPAREN */
+ "Unmatched \\{", /* REG_EBRACE */
+ "Invalid content of \\{\\}", /* REG_BADBR */
+ "Invalid range end", /* REG_ERANGE */
+ "Memory exhausted", /* REG_ESPACE */
+ "Invalid preceding regular expression", /* REG_BADRPT */
+ "Premature end of regular expression", /* REG_EEND */
+ "Regular expression too big", /* REG_ESIZE */
+ "Unmatched ) or \\)", /* REG_ERPAREN */
+ };
+
+/* Avoiding alloca during matching, to placate r_alloc. */
+
+/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
+ searching and matching functions should not call alloca. On some
+ systems, alloca is implemented in terms of malloc, and if we're
+ using the relocating allocator routines, then malloc could cause a
+ relocation, which might (if the strings being searched are in the
+ ralloc heap) shift the data out from underneath the regexp
+ routines.
+
+ Here's another reason to avoid allocation: Emacs
+ processes input from X in a signal handler; processing X input may
+ call malloc; if input arrives while a matching routine is calling
+ malloc, then we're scrod. But Emacs can't just block input while
+ calling matching routines; then we don't notice interrupts when
+ they come in. So, Emacs blocks input around all regexp calls
+ except the matching calls, which it leaves unprotected, in the
+ faith that they will not malloc. */
+
+/* Normally, this is fine. */
+#define MATCH_MAY_ALLOCATE
+
+/* The match routines may not allocate if (1) they would do it with malloc
+ and (2) it's not safe for them to use malloc. */
+#if (defined (C_ALLOCA) || defined (REGEX_MALLOC)) && (defined (emacs) || defined (REL_ALLOC))
+#undef MATCH_MAY_ALLOCATE
+#endif
+
+
+/* Failure stack declarations and macros; both re_compile_fastmap and
+ re_match_2 use a failure stack. These have to be macros because of
+ REGEX_ALLOCATE. */
+
+
+/* Number of failure points for which to initially allocate space
+ when matching. If this number is exceeded, we allocate more
+ space, so it is not a hard limit. */
+#ifndef INIT_FAILURE_ALLOC
+#define INIT_FAILURE_ALLOC 5
+#endif
+
+/* Roughly the maximum number of failure points on the stack. Would be
+ exactly that if always used MAX_FAILURE_SPACE each time we failed.
+ This is a variable only so users of regex can assign to it; we never
+ change it ourselves. */
+int re_max_failures = 2000;
+
+typedef unsigned char *fail_stack_elt_t;
+
+typedef struct
+{
+ fail_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} fail_stack_type;
+
+#define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
+#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
+#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
+#define FAIL_STACK_TOP() (fail_stack.stack[fail_stack.avail])
+
+
+/* Initialize `fail_stack'. Do `return -2' if the alloc fails. */
+
+#ifdef MATCH_MAY_ALLOCATE
+#define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.stack = (fail_stack_elt_t *) \
+ REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \
+ \
+ if (fail_stack.stack == NULL) \
+ return -2; \
+ \
+ fail_stack.size = INIT_FAILURE_ALLOC; \
+ fail_stack.avail = 0; \
+ } while (0)
+#else
+#define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.avail = 0; \
+ } while (0)
+#endif
+
+
+/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
+
+ Return 1 if succeeds, and 0 if either ran out of memory
+ allocating space for it or it was already too large.
+
+ REGEX_REALLOCATE requires `destination' be declared. */
+
+#define DOUBLE_FAIL_STACK(fail_stack) \
+ ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \
+ ? 0 \
+ : ((fail_stack).stack = (fail_stack_elt_t *) \
+ REGEX_REALLOCATE ((fail_stack).stack, \
+ (fail_stack).size * sizeof (fail_stack_elt_t), \
+ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
+ \
+ (fail_stack).stack == NULL \
+ ? 0 \
+ : ((fail_stack).size <<= 1, \
+ 1)))
+
+
+/* Push PATTERN_OP on FAIL_STACK.
+
+ Return 1 if was able to do so and 0 if ran out of memory allocating
+ space to do so. */
+#define PUSH_PATTERN_OP(pattern_op, fail_stack) \
+ ((FAIL_STACK_FULL () \
+ && !DOUBLE_FAIL_STACK (fail_stack)) \
+ ? 0 \
+ : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \
+ 1))
+
+/* This pushes an item onto the failure stack. Must be a four-byte
+ value. Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_ITEM(item) \
+ fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item
+
+/* The complement operation. Assumes `fail_stack' is nonempty. */
+#define POP_FAILURE_ITEM() fail_stack.stack[--fail_stack.avail]
+
+/* Used to omit pushing failure point id's when we're not debugging. */
+#ifdef DEBUG
+#define DEBUG_PUSH PUSH_FAILURE_ITEM
+#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_ITEM ()
+#else
+#define DEBUG_PUSH(item)
+#define DEBUG_POP(item_addr)
+#endif
+
+
+/* Push the information about the state we will need
+ if we ever fail back to it.
+
+ Requires variables fail_stack, regstart, regend, reg_info, and
+ num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be
+ declared.
+
+ Does `return FAILURE_CODE' if runs out of memory. */
+
+#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
+ do { \
+ char *destination; \
+ /* Must be int, so when we don't save any registers, the arithmetic \
+ of 0 + -1 isn't done as unsigned. */ \
+ int this_reg; \
+ \
+ DEBUG_STATEMENT (failure_id++); \
+ DEBUG_STATEMENT (nfailure_points_pushed++); \
+ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
+ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
+ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
+ \
+ DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \
+ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
+ \
+ /* Ensure we have enough space allocated for what we will push. */ \
+ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
+ { \
+ if (!DOUBLE_FAIL_STACK (fail_stack)) \
+ return failure_code; \
+ \
+ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
+ (fail_stack).size); \
+ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
+ } \
+ \
+ /* Push the info, starting with the registers. */ \
+ DEBUG_PRINT1 ("\n"); \
+ \
+ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
+ this_reg++) \
+ { \
+ DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \
+ DEBUG_STATEMENT (num_regs_pushed++); \
+ \
+ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
+ PUSH_FAILURE_ITEM (regstart[this_reg]); \
+ \
+ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
+ PUSH_FAILURE_ITEM (regend[this_reg]); \
+ \
+ DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \
+ DEBUG_PRINT2 (" match_null=%d", \
+ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" matched_something=%d", \
+ MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" ever_matched=%d", \
+ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT1 ("\n"); \
+ PUSH_FAILURE_ITEM (reg_info[this_reg].word); \
+ } \
+ \
+ DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\
+ PUSH_FAILURE_ITEM (lowest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\
+ PUSH_FAILURE_ITEM (highest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
+ PUSH_FAILURE_ITEM (pattern_place); \
+ \
+ DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \
+ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
+ size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ PUSH_FAILURE_ITEM (string_place); \
+ \
+ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
+ DEBUG_PUSH (failure_id); \
+ } while (0)
+
+/* This is the number of items that are pushed and popped on the stack
+ for each register. */
+#define NUM_REG_ITEMS 3
+
+/* Individual items aside from the registers. */
+#ifdef DEBUG
+#define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
+#else
+#define NUM_NONREG_ITEMS 4
+#endif
+
+/* We push at most this many items on the stack. */
+#define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
+
+/* We actually push this many items. */
+#define NUM_FAILURE_ITEMS \
+ ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \
+ + NUM_NONREG_ITEMS)
+
+/* How many items can still be added to the stack without overflowing it. */
+#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
+
+
+/* Pops what PUSH_FAIL_STACK pushes.
+
+ We restore into the parameters, all of which should be lvalues:
+ STR -- the saved data position.
+ PAT -- the saved pattern position.
+ LOW_REG, HIGH_REG -- the highest and lowest active registers.
+ REGSTART, REGEND -- arrays of string positions.
+ REG_INFO -- array of information about each subexpression.
+
+ Also assumes the variables `fail_stack' and (if debugging), `bufp',
+ `pend', `string1', `size1', `string2', and `size2'. */
+
+#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
+{ \
+ DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \
+ int this_reg; \
+ const unsigned char *string_temp; \
+ \
+ assert (!FAIL_STACK_EMPTY ()); \
+ \
+ /* Remove failure points and point to how many regs pushed. */ \
+ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
+ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
+ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
+ \
+ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
+ \
+ DEBUG_POP (&failure_id); \
+ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
+ \
+ /* If the saved string location is NULL, it came from an \
+ on_failure_keep_string_jump opcode, and we want to throw away the \
+ saved NULL, thus retaining our current position in the string. */ \
+ string_temp = POP_FAILURE_ITEM (); \
+ if (string_temp != NULL) \
+ str = (const char *) string_temp; \
+ \
+ DEBUG_PRINT2 (" Popping string 0x%x: `", str); \
+ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ \
+ pat = (unsigned char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
+ \
+ /* Restore register info. */ \
+ high_reg = (unsigned) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \
+ \
+ low_reg = (unsigned) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \
+ \
+ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
+ { \
+ DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \
+ \
+ reg_info[this_reg].word = POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \
+ \
+ regend[this_reg] = (const char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
+ \
+ regstart[this_reg] = (const char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
+ } \
+ \
+ DEBUG_STATEMENT (nfailure_points_popped++); \
+} /* POP_FAILURE_POINT */
+
+
+
+/* Structure for per-register (a.k.a. per-group) information.
+ This must not be longer than one word, because we push this value
+ onto the failure stack. Other register information, such as the
+ starting and ending positions (which are addresses), and the list of
+ inner groups (which is a bits list) are maintained in separate
+ variables.
+
+ We are making a (strictly speaking) nonportable assumption here: that
+ the compiler will pack our bit fields into something that fits into
+ the type of `word', i.e., is something that fits into one item on the
+ failure stack. */
+typedef union
+{
+ fail_stack_elt_t word;
+ struct
+ {
+ /* This field is one if this group can match the empty string,
+ zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
+#define MATCH_NULL_UNSET_VALUE 3
+ unsigned match_null_string_p : 2;
+ unsigned is_active : 1;
+ unsigned matched_something : 1;
+ unsigned ever_matched_something : 1;
+ } bits;
+} register_info_type;
+
+#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
+#define IS_ACTIVE(R) ((R).bits.is_active)
+#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
+#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
+
+
+/* Call this when have matched a real character; it sets `matched' flags
+ for the subexpressions which we are currently inside. Also records
+ that those subexprs have matched. */
+#define SET_REGS_MATCHED() \
+ do \
+ { \
+ unsigned r; \
+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
+ { \
+ MATCHED_SOMETHING (reg_info[r]) \
+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
+ = 1; \
+ } \
+ } \
+ while (0)
+
+
+/* Registers are set to a sentinel when they haven't yet matched. */
+#define REG_UNSET_VALUE ((char *) -1)
+#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
+
+
+
+/* How do we implement a missing MATCH_MAY_ALLOCATE?
+ We make the fail stack a global thing, and then grow it to
+ re_max_failures when we compile. */
+#ifndef MATCH_MAY_ALLOCATE
+static fail_stack_type fail_stack;
+
+static const char ** regstart, ** regend;
+static const char ** old_regstart, ** old_regend;
+static const char **best_regstart, **best_regend;
+static register_info_type *reg_info;
+static const char **reg_dummy;
+static register_info_type *reg_info_dummy;
+#endif
+
+
+/* Subroutine declarations and macros for regex_compile. */
+
+static void store_op1 (), store_op2 ();
+static void insert_op1 (), insert_op2 ();
+static boolean at_begline_loc_p (), at_endline_loc_p ();
+static boolean group_in_compile_stack ();
+static reg_errcode_t compile_range ();
+
+/* Fetch the next character in the uncompiled pattern---translating it
+ if necessary. Also cast from a signed character in the constant
+ string passed to us by the user to an unsigned char that we can use
+ as an array index (in, e.g., `translate'). */
+#define PATFETCH(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ if (translate) c = translate[c]; \
+ } while (0)
+
+/* Fetch the next character in the uncompiled pattern, with no
+ translation. */
+#define PATFETCH_RAW(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ } while (0)
+
+/* Go backwards one character in the pattern. */
+#define PATUNFETCH p--
+
+
+/* If `translate' is non-null, return translate[D], else just D. We
+ cast the subscript to translate because some data is declared as
+ `char *', to avoid warnings when a string constant is passed. But
+ when we use a character as a subscript we must make it unsigned. */
+#define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d))
+
+
+/* Macros for outputting the compiled pattern into `buffer'. */
+
+/* If the buffer isn't allocated when it comes in, use this. */
+#define INIT_BUF_SIZE 32
+
+/* Make sure we have at least N more bytes of space in buffer. */
+#define GET_BUFFER_SPACE(n) \
+ while (b - bufp->buffer + (n) > bufp->allocated) \
+ EXTEND_BUFFER ()
+
+/* Make sure we have one more byte of buffer space and then add C to it. */
+#define BUF_PUSH(c) \
+ do { \
+ GET_BUFFER_SPACE (1); \
+ *b++ = (unsigned char) (c); \
+ } while (0)
+
+
+/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
+#define BUF_PUSH_2(c1, c2) \
+ do { \
+ GET_BUFFER_SPACE (2); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ } while (0)
+
+
+/* As with BUF_PUSH_2, except for three bytes. */
+#define BUF_PUSH_3(c1, c2, c3) \
+ do { \
+ GET_BUFFER_SPACE (3); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ *b++ = (unsigned char) (c3); \
+ } while (0)
+
+
+/* Store a jump with opcode OP at LOC to location TO. We store a
+ relative address offset by the three bytes the jump itself occupies. */
+#define STORE_JUMP(op, loc, to) \
+ store_op1 (op, loc, (to) - (loc) - 3)
+
+/* Likewise, for a two-argument jump. */
+#define STORE_JUMP2(op, loc, to, arg) \
+ store_op2 (op, loc, (to) - (loc) - 3, arg)
+
+/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP(op, loc, to) \
+ insert_op1 (op, loc, (to) - (loc) - 3, b)
+
+/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP2(op, loc, to, arg) \
+ insert_op2 (op, loc, (to) - (loc) - 3, arg, b)
+
+
+/* This is not an arbitrary limit: the arguments which represent offsets
+ into the pattern are two bytes long. So if 2^16 bytes turns out to
+ be too small, many things would have to change. */
+#define MAX_BUF_SIZE (1L << 16)
+
+
+/* Extend the buffer by twice its current size via realloc and
+ reset the pointers that pointed into the old block to point to the
+ correct places in the new one. If extending the buffer results in it
+ being larger than MAX_BUF_SIZE, then flag memory exhausted. */
+#define EXTEND_BUFFER() \
+ do { \
+ unsigned char *old_buffer = bufp->buffer; \
+ if (bufp->allocated == MAX_BUF_SIZE) \
+ return REG_ESIZE; \
+ bufp->allocated <<= 1; \
+ if (bufp->allocated > MAX_BUF_SIZE) \
+ bufp->allocated = MAX_BUF_SIZE; \
+ bufp->buffer = (unsigned char *) realloc (bufp->buffer, bufp->allocated);\
+ if (bufp->buffer == NULL) \
+ return REG_ESPACE; \
+ /* If the buffer moved, move all the pointers into it. */ \
+ if (old_buffer != bufp->buffer) \
+ { \
+ b = (b - old_buffer) + bufp->buffer; \
+ begalt = (begalt - old_buffer) + bufp->buffer; \
+ if (fixup_alt_jump) \
+ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
+ if (laststart) \
+ laststart = (laststart - old_buffer) + bufp->buffer; \
+ if (pending_exact) \
+ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
+ } \
+ } while (0)
+
+
+/* Since we have one byte reserved for the register number argument to
+ {start,stop}_memory, the maximum number of groups we can report
+ things about is what fits in that byte. */
+#define MAX_REGNUM 255
+
+/* But patterns can have more than `MAX_REGNUM' registers. We just
+ ignore the excess. */
+typedef unsigned regnum_t;
+
+
+/* Macros for the compile stack. */
+
+/* Since offsets can go either forwards or backwards, this type needs to
+ be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
+typedef int pattern_offset_t;
+
+typedef struct
+{
+ pattern_offset_t begalt_offset;
+ pattern_offset_t fixup_alt_jump;
+ pattern_offset_t inner_group_offset;
+ pattern_offset_t laststart_offset;
+ regnum_t regnum;
+} compile_stack_elt_t;
+
+
+typedef struct
+{
+ compile_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} compile_stack_type;
+
+
+#define INIT_COMPILE_STACK_SIZE 32
+
+#define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
+#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
+
+/* The next available element. */
+#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
+
+
+/* Set the bit for character C in a list. */
+#define SET_LIST_BIT(c) \
+ (b[((unsigned char) (c)) / BYTEWIDTH] \
+ |= 1 << (((unsigned char) c) % BYTEWIDTH))
+
+
+/* Get the next unsigned number in the uncompiled pattern. */
+#define GET_UNSIGNED_NUMBER(num) \
+ { if (p != pend) \
+ { \
+ PATFETCH (c); \
+ while (ISDIGIT (c)) \
+ { \
+ if (num < 0) \
+ num = 0; \
+ num = num * 10 + c - '0'; \
+ if (p == pend) \
+ break; \
+ PATFETCH (c); \
+ } \
+ } \
+ }
+
+#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
+
+#define IS_CHAR_CLASS(string) \
+ (STREQ (string, "alpha") || STREQ (string, "upper") \
+ || STREQ (string, "lower") || STREQ (string, "digit") \
+ || STREQ (string, "alnum") || STREQ (string, "xdigit") \
+ || STREQ (string, "space") || STREQ (string, "print") \
+ || STREQ (string, "punct") || STREQ (string, "graph") \
+ || STREQ (string, "cntrl") || STREQ (string, "blank"))
+
+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
+ Returns one of error codes defined in `regex.h', or zero for success.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate'
+ fields are set in BUFP on entry.
+
+ If it succeeds, results are put in BUFP (if it returns an error, the
+ contents of BUFP are undefined):
+ `buffer' is the compiled pattern;
+ `syntax' is set to SYNTAX;
+ `used' is set to the length of the compiled pattern;
+ `fastmap_accurate' is zero;
+ `re_nsub' is the number of subexpressions in PATTERN;
+ `not_bol' and `not_eol' are zero;
+
+ The `fastmap' and `newline_anchor' fields are neither
+ examined nor set. */
+
+/* Return, freeing storage we allocated. */
+#define FREE_STACK_RETURN(value) \
+ return (free (compile_stack.stack), value)
+
+static reg_errcode_t
+regex_compile (pattern, size, syntax, bufp)
+ const char *pattern;
+ int size;
+ reg_syntax_t syntax;
+ struct re_pattern_buffer *bufp;
+{
+ /* We fetch characters from PATTERN here. Even though PATTERN is
+ `char *' (i.e., signed), we declare these variables as unsigned, so
+ they can be reliably used as array indices. */
+ register unsigned char c, c1;
+
+ /* A random temporary spot in PATTERN. */
+ const char *p1;
+
+ /* Points to the end of the buffer, where we should append. */
+ register unsigned char *b;
+
+ /* Keeps track of unclosed groups. */
+ compile_stack_type compile_stack;
+
+ /* Points to the current (ending) position in the pattern. */
+ const char *p = pattern;
+ const char *pend = pattern + size;
+
+ /* How to translate the characters in the pattern. */
+ char *translate = bufp->translate;
+
+ /* Address of the count-byte of the most recently inserted `exactn'
+ command. This makes it possible to tell if a new exact-match
+ character can be added to that command or if the character requires
+ a new `exactn' command. */
+ unsigned char *pending_exact = 0;
+
+ /* Address of start of the most recently finished expression.
+ This tells, e.g., postfix * where to find the start of its
+ operand. Reset at the beginning of groups and alternatives. */
+ unsigned char *laststart = 0;
+
+ /* Address of beginning of regexp, or inside of last group. */
+ unsigned char *begalt;
+
+ /* Place in the uncompiled pattern (i.e., the {) to
+ which to go back if the interval is invalid. */
+ const char *beg_interval;
+
+ /* Address of the place where a forward jump should go to the end of
+ the containing expression. Each alternative of an `or' -- except the
+ last -- ends with a forward jump of this sort. */
+ unsigned char *fixup_alt_jump = 0;
+
+ /* Counts open-groups as they are encountered. Remembered for the
+ matching close-group on the compile stack, so the same register
+ number is put in the stop_memory as the start_memory. */
+ regnum_t regnum = 0;
+
+#ifdef DEBUG
+ DEBUG_PRINT1 ("\nCompiling pattern: ");
+ if (debug)
+ {
+ unsigned debug_count;
+
+ for (debug_count = 0; debug_count < size; debug_count++)
+ printchar (pattern[debug_count]);
+ putchar ('\n');
+ }
+#endif /* DEBUG */
+
+ /* Initialize the compile stack. */
+ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
+ if (compile_stack.stack == NULL)
+ return REG_ESPACE;
+
+ compile_stack.size = INIT_COMPILE_STACK_SIZE;
+ compile_stack.avail = 0;
+
+ /* Initialize the pattern buffer. */
+ bufp->syntax = syntax;
+ bufp->fastmap_accurate = 0;
+ bufp->not_bol = bufp->not_eol = 0;
+
+ /* Set `used' to zero, so that if we return an error, the pattern
+ printer (for debugging) will think there's no pattern. We reset it
+ at the end. */
+ bufp->used = 0;
+
+ /* Always count groups, whether or not bufp->no_sub is set. */
+ bufp->re_nsub = 0;
+
+#if !defined (emacs) && !defined (SYNTAX_TABLE)
+ /* Initialize the syntax table. */
+ init_syntax_once ();
+#endif
+
+ if (bufp->allocated == 0)
+ {
+ if (bufp->buffer)
+ { /* If zero allocated, but buffer is non-null, try to realloc
+ enough space. This loses if buffer's address is bogus, but
+ that is the user's responsibility. */
+ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
+ }
+ else
+ { /* Caller did not allocate a buffer. Do it for them. */
+ bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
+ }
+ if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE);
+
+ bufp->allocated = INIT_BUF_SIZE;
+ }
+
+ begalt = b = bufp->buffer;
+
+ /* Loop through the uncompiled pattern until we're at the end. */
+ while (p != pend)
+ {
+ PATFETCH (c);
+
+ switch (c)
+ {
+ case '^':
+ {
+ if ( /* If at start of pattern, it's an operator. */
+ p == pattern + 1
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's come before. */
+ || at_begline_loc_p (pattern, p, syntax))
+ BUF_PUSH (begline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '$':
+ {
+ if ( /* If at end of pattern, it's an operator. */
+ p == pend
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's next. */
+ || at_endline_loc_p (p, pend, syntax))
+ BUF_PUSH (endline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '+':
+ case '?':
+ if ((syntax & RE_BK_PLUS_QM)
+ || (syntax & RE_LIMITED_OPS))
+ goto normal_char;
+ handle_plus:
+ case '*':
+ /* If there is no previous pattern... */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ FREE_STACK_RETURN (REG_BADRPT);
+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ }
+
+ {
+ /* Are we optimizing this jump? */
+ boolean keep_string_p = false;
+
+ /* 1 means zero (many) matches is allowed. */
+ char zero_times_ok = 0, many_times_ok = 0;
+
+ /* If there is a sequence of repetition chars, collapse it
+ down to just one (the right one). We can't combine
+ interval operators with these because of, e.g., `a{2}*',
+ which should only match an even number of `a's. */
+
+ for (;;)
+ {
+ zero_times_ok |= c != '+';
+ many_times_ok |= c != '?';
+
+ if (p == pend)
+ break;
+
+ PATFETCH (c);
+
+ if (c == '*'
+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
+ ;
+
+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ PATFETCH (c1);
+ if (!(c1 == '+' || c1 == '?'))
+ {
+ PATUNFETCH;
+ PATUNFETCH;
+ break;
+ }
+
+ c = c1;
+ }
+ else
+ {
+ PATUNFETCH;
+ break;
+ }
+
+ /* If we get here, we found another repeat character. */
+ }
+
+ /* Star, etc. applied to an empty pattern is equivalent
+ to an empty pattern. */
+ if (!laststart)
+ break;
+
+ /* Now we know whether or not zero matches is allowed
+ and also whether or not two or more matches is allowed. */
+ if (many_times_ok)
+ { /* More than one repetition is allowed, so put in at the
+ end a backward relative jump from `b' to before the next
+ jump we're going to put in below (which jumps from
+ laststart to after this jump).
+
+ But if we are at the `*' in the exact sequence `.*\n',
+ insert an unconditional jump backwards to the .,
+ instead of the beginning of the loop. This way we only
+ push a failure point once, instead of every time
+ through the loop. */
+ assert (p - 1 > pattern);
+
+ /* Allocate the space for the jump. */
+ GET_BUFFER_SPACE (3);
+
+ /* We know we are not at the first character of the pattern,
+ because laststart was nonzero. And we've already
+ incremented `p', by the way, to be the character after
+ the `*'. Do we have to do something analogous here
+ for null bytes, because of RE_DOT_NOT_NULL? */
+ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
+ && zero_times_ok
+ && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
+ && !(syntax & RE_DOT_NEWLINE))
+ { /* We have .*\n. */
+ STORE_JUMP (jump, b, laststart);
+ keep_string_p = true;
+ }
+ else
+ /* Anything else. */
+ STORE_JUMP (maybe_pop_jump, b, laststart - 3);
+
+ /* We've added more stuff to the buffer. */
+ b += 3;
+ }
+
+ /* On failure, jump from laststart to b + 3, which will be the
+ end of the buffer after this jump is inserted. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
+ : on_failure_jump,
+ laststart, b + 3);
+ pending_exact = 0;
+ b += 3;
+
+ if (!zero_times_ok)
+ {
+ /* At least one repetition is required, so insert a
+ `dummy_failure_jump' before the initial
+ `on_failure_jump' instruction of the loop. This
+ effects a skip over that instruction the first time
+ we hit that loop. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
+ b += 3;
+ }
+ }
+ break;
+
+
+ case '.':
+ laststart = b;
+ BUF_PUSH (anychar);
+ break;
+
+
+ case '[':
+ {
+ boolean had_char_class = false;
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ /* Ensure that we have enough space to push a charset: the
+ opcode, the length count, and the bitset; 34 bytes in all. */
+ GET_BUFFER_SPACE (34);
+
+ laststart = b;
+
+ /* We test `*p == '^' twice, instead of using an if
+ statement, so we only need one BUF_PUSH. */
+ BUF_PUSH (*p == '^' ? charset_not : charset);
+ if (*p == '^')
+ p++;
+
+ /* Remember the first position in the bracket expression. */
+ p1 = p;
+
+ /* Push the number of bytes in the bitmap. */
+ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* Clear the whole map. */
+ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* charset_not matches newline according to a syntax bit. */
+ if ((re_opcode_t) b[-2] == charset_not
+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
+ SET_LIST_BIT ('\n');
+
+ /* Read in characters and ranges, setting map bits. */
+ for (;;)
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ PATFETCH (c);
+
+ /* \ might escape characters inside [...] and [^...]. */
+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ PATFETCH (c1);
+ SET_LIST_BIT (c1);
+ continue;
+ }
+
+ /* Could be the end of the bracket expression. If it's
+ not (i.e., when the bracket expression is `[]' so
+ far), the ']' character bit gets set way below. */
+ if (c == ']' && p != p1 + 1)
+ break;
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character class. */
+ if (had_char_class && c == '-' && *p != ']')
+ FREE_STACK_RETURN (REG_ERANGE);
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character: if this is a hyphen not at the
+ beginning or the end of a list, then it's the range
+ operator. */
+ if (c == '-'
+ && !(p - 2 >= pattern && p[-2] == '[')
+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
+ && *p != ']')
+ {
+ reg_errcode_t ret
+ = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
+ }
+
+ else if (p[0] == '-' && p[1] != ']')
+ { /* This handles ranges made up of characters only. */
+ reg_errcode_t ret;
+
+ /* Move past the `-'. */
+ PATFETCH (c1);
+
+ ret = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
+ }
+
+ /* See if we're at the beginning of a possible character
+ class. */
+
+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
+ { /* Leave room for the null. */
+ char str[CHAR_CLASS_MAX_LENGTH + 1];
+
+ PATFETCH (c);
+ c1 = 0;
+
+ /* If pattern is `[[:'. */
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (;;)
+ {
+ PATFETCH (c);
+ if (c == ':' || c == ']' || p == pend
+ || c1 == CHAR_CLASS_MAX_LENGTH)
+ break;
+ str[c1++] = c;
+ }
+ str[c1] = '\0';
+
+ /* If isn't a word bracketed by `[:' and:`]':
+ undo the ending character, the letters, and leave
+ the leading `:' and `[' (but set bits for them). */
+ if (c == ':' && *p == ']')
+ {
+ int ch;
+ boolean is_alnum = STREQ (str, "alnum");
+ boolean is_alpha = STREQ (str, "alpha");
+ boolean is_blank = STREQ (str, "blank");
+ boolean is_cntrl = STREQ (str, "cntrl");
+ boolean is_digit = STREQ (str, "digit");
+ boolean is_graph = STREQ (str, "graph");
+ boolean is_lower = STREQ (str, "lower");
+ boolean is_print = STREQ (str, "print");
+ boolean is_punct = STREQ (str, "punct");
+ boolean is_space = STREQ (str, "space");
+ boolean is_upper = STREQ (str, "upper");
+ boolean is_xdigit = STREQ (str, "xdigit");
+
+ if (!IS_CHAR_CLASS (str))
+ FREE_STACK_RETURN (REG_ECTYPE);
+
+ /* Throw away the ] at the end of the character
+ class. */
+ PATFETCH (c);
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
+ {
+ /* This was split into 3 if's to
+ avoid an arbitrary limit in some compiler. */
+ if ( (is_alnum && ISALNUM (ch))
+ || (is_alpha && ISALPHA (ch))
+ || (is_blank && ISBLANK (ch))
+ || (is_cntrl && ISCNTRL (ch)))
+ SET_LIST_BIT (ch);
+ if ( (is_digit && ISDIGIT (ch))
+ || (is_graph && ISGRAPH (ch))
+ || (is_lower && ISLOWER (ch))
+ || (is_print && ISPRINT (ch)))
+ SET_LIST_BIT (ch);
+ if ( (is_punct && ISPUNCT (ch))
+ || (is_space && ISSPACE (ch))
+ || (is_upper && ISUPPER (ch))
+ || (is_xdigit && ISXDIGIT (ch)))
+ SET_LIST_BIT (ch);
+ }
+ had_char_class = true;
+ }
+ else
+ {
+ c1++;
+ while (c1--)
+ PATUNFETCH;
+ SET_LIST_BIT ('[');
+ SET_LIST_BIT (':');
+ had_char_class = false;
+ }
+ }
+ else
+ {
+ had_char_class = false;
+ SET_LIST_BIT (c);
+ }
+ }
+
+ /* Discard any (non)matching list bytes that are all 0 at the
+ end of the map. Decrease the map-length byte too. */
+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+ b[-1]--;
+ b += b[-1];
+ }
+ break;
+
+
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_open;
+ else
+ goto normal_char;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_close;
+ else
+ goto normal_char;
+
+
+ case '\n':
+ if (syntax & RE_NEWLINE_ALT)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '|':
+ if (syntax & RE_NO_BK_VBAR)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '{':
+ if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
+ goto handle_interval;
+ else
+ goto normal_char;
+
+
+ case '\\':
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ /* Do not translate the character after the \, so that we can
+ distinguish, e.g., \B from \b, even if we normally would
+ translate, e.g., B to b. */
+ PATFETCH_RAW (c);
+
+ switch (c)
+ {
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto normal_backslash;
+
+ handle_open:
+ bufp->re_nsub++;
+ regnum++;
+
+ if (COMPILE_STACK_FULL)
+ {
+ RETALLOC (compile_stack.stack, compile_stack.size << 1,
+ compile_stack_elt_t);
+ if (compile_stack.stack == NULL) return REG_ESPACE;
+
+ compile_stack.size <<= 1;
+ }
+
+ /* These are the values to restore when we hit end of this
+ group. They are all relative offsets, so that if the
+ whole pattern moves because of realloc, they will still
+ be valid. */
+ COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
+ COMPILE_STACK_TOP.fixup_alt_jump
+ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
+ COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
+ COMPILE_STACK_TOP.regnum = regnum;
+
+ /* We will eventually replace the 0 with the number of
+ groups inner to this one. But do not push a
+ start_memory for groups beyond the last one we can
+ represent in the compiled pattern. */
+ if (regnum <= MAX_REGNUM)
+ {
+ COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
+ BUF_PUSH_3 (start_memory, regnum, 0);
+ }
+
+ compile_stack.avail++;
+
+ fixup_alt_jump = 0;
+ laststart = 0;
+ begalt = b;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+ break;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
+
+ if (COMPILE_STACK_EMPTY)
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_backslash;
+ else
+ FREE_STACK_RETURN (REG_ERPAREN);
+
+ handle_close:
+ if (fixup_alt_jump)
+ { /* Push a dummy failure point at the end of the
+ alternative for a possible future
+ `pop_failure_jump' to pop. See comments at
+ `push_dummy_failure' in `re_match_2'. */
+ BUF_PUSH (push_dummy_failure);
+
+ /* We allocated space for this jump when we assigned
+ to `fixup_alt_jump', in the `handle_alt' case below. */
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
+ }
+
+ /* See similar code for backslashed left paren above. */
+ if (COMPILE_STACK_EMPTY)
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_char;
+ else
+ FREE_STACK_RETURN (REG_ERPAREN);
+
+ /* Since we just checked for an empty stack above, this
+ ``can't happen''. */
+ assert (compile_stack.avail != 0);
+ {
+ /* We don't just want to restore into `regnum', because
+ later groups should continue to be numbered higher,
+ as in `(ab)c(de)' -- the second group is #2. */
+ regnum_t this_group_regnum;
+
+ compile_stack.avail--;
+ begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
+ fixup_alt_jump
+ = COMPILE_STACK_TOP.fixup_alt_jump
+ ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
+ : 0;
+ laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
+ this_group_regnum = COMPILE_STACK_TOP.regnum;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+
+ /* We're at the end of the group, so now we know how many
+ groups were inside this one. */
+ if (this_group_regnum <= MAX_REGNUM)
+ {
+ unsigned char *inner_group_loc
+ = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
+
+ *inner_group_loc = regnum - this_group_regnum;
+ BUF_PUSH_3 (stop_memory, this_group_regnum,
+ regnum - this_group_regnum);
+ }
+ }
+ break;
+
+
+ case '|': /* `\|'. */
+ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
+ goto normal_backslash;
+ handle_alt:
+ if (syntax & RE_LIMITED_OPS)
+ goto normal_char;
+
+ /* Insert before the previous alternative a jump which
+ jumps to this alternative if the former fails. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (on_failure_jump, begalt, b + 6);
+ pending_exact = 0;
+ b += 3;
+
+ /* The alternative before this one has a jump after it
+ which gets executed if it gets matched. Adjust that
+ jump so it will jump to this alternative's analogous
+ jump (put in below, which in turn will jump to the next
+ (if any) alternative's such jump, etc.). The last such
+ jump jumps to the correct final destination. A picture:
+ _____ _____
+ | | | |
+ | v | v
+ a | b | c
+
+ If we are at `b', then fixup_alt_jump right now points to a
+ three-byte space after `a'. We'll put in the jump, set
+ fixup_alt_jump to right after `b', and leave behind three
+ bytes which we'll fill in when we get to after `c'. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ /* Mark and leave space for a jump after this alternative,
+ to be filled in later either by next alternative or
+ when know we're at the end of a series of alternatives. */
+ fixup_alt_jump = b;
+ GET_BUFFER_SPACE (3);
+ b += 3;
+
+ laststart = 0;
+ begalt = b;
+ break;
+
+
+ case '{':
+ /* If \{ is a literal. */
+ if (!(syntax & RE_INTERVALS)
+ /* If we're at `\{' and it's not the open-interval
+ operator. */
+ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+ || (p - 2 == pattern && p == pend))
+ goto normal_backslash;
+
+ handle_interval:
+ {
+ /* If got here, then the syntax allows intervals. */
+
+ /* At least (most) this many matches must be made. */
+ int lower_bound = -1, upper_bound = -1;
+
+ beg_interval = p - 1;
+
+ if (p == pend)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_EBRACE);
+ }
+
+ GET_UNSIGNED_NUMBER (lower_bound);
+
+ if (c == ',')
+ {
+ GET_UNSIGNED_NUMBER (upper_bound);
+ if (upper_bound < 0) upper_bound = RE_DUP_MAX;
+ }
+ else
+ /* Interval such as `{1}' => match exactly once. */
+ upper_bound = lower_bound;
+
+ if (lower_bound < 0 || upper_bound > RE_DUP_MAX
+ || lower_bound > upper_bound)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_BADBR);
+ }
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (c != '\\') FREE_STACK_RETURN (REG_EBRACE);
+
+ PATFETCH (c);
+ }
+
+ if (c != '}')
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_BADBR);
+ }
+
+ /* We just parsed a valid interval. */
+
+ /* If it's invalid to have no preceding re. */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ FREE_STACK_RETURN (REG_BADRPT);
+ else if (syntax & RE_CONTEXT_INDEP_OPS)
+ laststart = b;
+ else
+ goto unfetch_interval;
+ }
+
+ /* If the upper bound is zero, don't want to succeed at
+ all; jump from `laststart' to `b + 3', which will be
+ the end of the buffer after we insert the jump. */
+ if (upper_bound == 0)
+ {
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (jump, laststart, b + 3);
+ b += 3;
+ }
+
+ /* Otherwise, we have a nontrivial interval. When
+ we're all done, the pattern will look like:
+ set_number_at <jump count> <upper bound>
+ set_number_at <succeed_n count> <lower bound>
+ succeed_n <after jump addr> <succeed_n count>
+ <body of loop>
+ jump_n <succeed_n addr> <jump count>
+ (The upper bound and `jump_n' are omitted if
+ `upper_bound' is 1, though.) */
+ else
+ { /* If the upper bound is > 1, we need to insert
+ more at the end of the loop. */
+ unsigned nbytes = 10 + (upper_bound > 1) * 10;
+
+ GET_BUFFER_SPACE (nbytes);
+
+ /* Initialize lower bound of the `succeed_n', even
+ though it will be set during matching by its
+ attendant `set_number_at' (inserted next),
+ because `re_compile_fastmap' needs to know.
+ Jump to the `jump_n' we might insert below. */
+ INSERT_JUMP2 (succeed_n, laststart,
+ b + 5 + (upper_bound > 1) * 5,
+ lower_bound);
+ b += 5;
+
+ /* Code to initialize the lower bound. Insert
+ before the `succeed_n'. The `5' is the last two
+ bytes of this `set_number_at', plus 3 bytes of
+ the following `succeed_n'. */
+ insert_op2 (set_number_at, laststart, 5, lower_bound, b);
+ b += 5;
+
+ if (upper_bound > 1)
+ { /* More than one repetition is allowed, so
+ append a backward jump to the `succeed_n'
+ that starts this interval.
+
+ When we've reached this during matching,
+ we'll have matched the interval once, so
+ jump back only `upper_bound - 1' times. */
+ STORE_JUMP2 (jump_n, b, laststart + 5,
+ upper_bound - 1);
+ b += 5;
+
+ /* The location we want to set is the second
+ parameter of the `jump_n'; that is `b-2' as
+ an absolute address. `laststart' will be
+ the `set_number_at' we're about to insert;
+ `laststart+3' the number to set, the source
+ for the relative address. But we are
+ inserting into the middle of the pattern --
+ so everything is getting moved up by 5.
+ Conclusion: (b - 2) - (laststart + 3) + 5,
+ i.e., b - laststart.
+
+ We insert this at the beginning of the loop
+ so that if we fail during matching, we'll
+ reinitialize the bounds. */
+ insert_op2 (set_number_at, laststart, b - laststart,
+ upper_bound - 1, b);
+ b += 5;
+ }
+ }
+ pending_exact = 0;
+ beg_interval = NULL;
+ }
+ break;
+
+ unfetch_interval:
+ /* If an invalid interval, match the characters as literals. */
+ assert (beg_interval);
+ p = beg_interval;
+ beg_interval = NULL;
+
+ /* normal_char and normal_backslash need `c'. */
+ PATFETCH (c);
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (p > pattern && p[-1] == '\\')
+ goto normal_backslash;
+ }
+ goto normal_char;
+
+#ifdef emacs
+ /* There is no way to specify the before_dot and after_dot
+ operators. rms says this is ok. --karl */
+ case '=':
+ BUF_PUSH (at_dot);
+ break;
+
+ case 's':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
+ break;
+
+ case 'S':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
+ break;
+#endif /* emacs */
+
+
+ case 'w':
+ laststart = b;
+ BUF_PUSH (wordchar);
+ break;
+
+
+ case 'W':
+ laststart = b;
+ BUF_PUSH (notwordchar);
+ break;
+
+
+ case '<':
+ BUF_PUSH (wordbeg);
+ break;
+
+ case '>':
+ BUF_PUSH (wordend);
+ break;
+
+ case 'b':
+ BUF_PUSH (wordbound);
+ break;
+
+ case 'B':
+ BUF_PUSH (notwordbound);
+ break;
+
+ case '`':
+ BUF_PUSH (begbuf);
+ break;
+
+ case '\'':
+ BUF_PUSH (endbuf);
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ if (syntax & RE_NO_BK_REFS)
+ goto normal_char;
+
+ c1 = c - '0';
+
+ if (c1 > regnum)
+ FREE_STACK_RETURN (REG_ESUBREG);
+
+ /* Can't back reference to a subexpression if inside of it. */
+ if (group_in_compile_stack (compile_stack, c1))
+ goto normal_char;
+
+ laststart = b;
+ BUF_PUSH_2 (duplicate, c1);
+ break;
+
+
+ case '+':
+ case '?':
+ if (syntax & RE_BK_PLUS_QM)
+ goto handle_plus;
+ else
+ goto normal_backslash;
+
+ default:
+ normal_backslash:
+ /* You might think it would be useful for \ to mean
+ not to translate; but if we don't translate it
+ it will never match anything. */
+ c = TRANSLATE (c);
+ goto normal_char;
+ }
+ break;
+
+
+ default:
+ /* Expects the character in `c'. */
+ normal_char:
+ /* If no exactn currently being built. */
+ if (!pending_exact
+
+ /* If last exactn not at current position. */
+ || pending_exact + *pending_exact + 1 != b
+
+ /* We have only one byte following the exactn for the count. */
+ || *pending_exact == (1 << BYTEWIDTH) - 1
+
+ /* If followed by a repetition operator. */
+ || *p == '*' || *p == '^'
+ || ((syntax & RE_BK_PLUS_QM)
+ ? *p == '\\' && (p[1] == '+' || p[1] == '?')
+ : (*p == '+' || *p == '?'))
+ || ((syntax & RE_INTERVALS)
+ && ((syntax & RE_NO_BK_BRACES)
+ ? *p == '{'
+ : (p[0] == '\\' && p[1] == '{'))))
+ {
+ /* Start building a new exactn. */
+
+ laststart = b;
+
+ BUF_PUSH_2 (exactn, 0);
+ pending_exact = b - 1;
+ }
+
+ BUF_PUSH (c);
+ (*pending_exact)++;
+ break;
+ } /* switch (c) */
+ } /* while p != pend */
+
+
+ /* Through the pattern now. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ if (!COMPILE_STACK_EMPTY)
+ FREE_STACK_RETURN (REG_EPAREN);
+
+ free (compile_stack.stack);
+
+ /* We have succeeded; set the length of the buffer. */
+ bufp->used = b - bufp->buffer;
+
+#ifdef DEBUG
+ if (debug)
+ {
+ DEBUG_PRINT1 ("\nCompiled pattern: \n");
+ print_compiled_pattern (bufp);
+ }
+#endif /* DEBUG */
+
+#ifndef MATCH_MAY_ALLOCATE
+ /* Initialize the failure stack to the largest possible stack. This
+ isn't necessary unless we're trying to avoid calling alloca in
+ the search and match routines. */
+ {
+ int num_regs = bufp->re_nsub + 1;
+
+ /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
+ is strictly greater than re_max_failures, the largest possible stack
+ is 2 * re_max_failures failure points. */
+ if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
+ {
+ fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
+
+#ifdef emacs
+ if (! fail_stack.stack)
+ fail_stack.stack
+ = (fail_stack_elt_t *) xmalloc (fail_stack.size
+ * sizeof (fail_stack_elt_t));
+ else
+ fail_stack.stack
+ = (fail_stack_elt_t *) xrealloc (fail_stack.stack,
+ (fail_stack.size
+ * sizeof (fail_stack_elt_t)));
+#else /* not emacs */
+ if (! fail_stack.stack)
+ fail_stack.stack
+ = (fail_stack_elt_t *) malloc (fail_stack.size
+ * sizeof (fail_stack_elt_t));
+ else
+ fail_stack.stack
+ = (fail_stack_elt_t *) realloc (fail_stack.stack,
+ (fail_stack.size
+ * sizeof (fail_stack_elt_t)));
+#endif /* not emacs */
+ }
+
+ /* Initialize some other variables the matcher uses. */
+ RETALLOC_IF (regstart, num_regs, const char *);
+ RETALLOC_IF (regend, num_regs, const char *);
+ RETALLOC_IF (old_regstart, num_regs, const char *);
+ RETALLOC_IF (old_regend, num_regs, const char *);
+ RETALLOC_IF (best_regstart, num_regs, const char *);
+ RETALLOC_IF (best_regend, num_regs, const char *);
+ RETALLOC_IF (reg_info, num_regs, register_info_type);
+ RETALLOC_IF (reg_dummy, num_regs, const char *);
+ RETALLOC_IF (reg_info_dummy, num_regs, register_info_type);
+ }
+#endif
+
+ return REG_NOERROR;
+} /* regex_compile */
+
+/* Subroutines for `regex_compile'. */
+
+/* Store OP at LOC followed by two-byte integer parameter ARG. */
+
+static void
+store_op1 (op, loc, arg)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg);
+}
+
+
+/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+store_op2 (op, loc, arg1, arg2)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg1);
+ STORE_NUMBER (loc + 3, arg2);
+}
+
+
+/* Copy the bytes from LOC to END to open up three bytes of space at LOC
+ for OP followed by two-byte integer parameter ARG. */
+
+static void
+insert_op1 (op, loc, arg, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 3;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op1 (op, loc, arg);
+}
+
+
+/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+insert_op2 (op, loc, arg1, arg2, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 5;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op2 (op, loc, arg1, arg2);
+}
+
+
+/* P points to just after a ^ in PATTERN. Return true if that ^ comes
+ after an alternative or a begin-subexpression. We assume there is at
+ least one character before the ^. */
+
+static boolean
+at_begline_loc_p (pattern, p, syntax)
+ const char *pattern, *p;
+ reg_syntax_t syntax;
+{
+ const char *prev = p - 2;
+ boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
+
+ return
+ /* After a subexpression? */
+ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
+ /* After an alternative? */
+ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
+}
+
+
+/* The dual of at_begline_loc_p. This one is for $. We assume there is
+ at least one character after the $, i.e., `P < PEND'. */
+
+static boolean
+at_endline_loc_p (p, pend, syntax)
+ const char *p, *pend;
+ int syntax;
+{
+ const char *next = p;
+ boolean next_backslash = *next == '\\';
+ const char *next_next = p + 1 < pend ? p + 1 : NULL;
+
+ return
+ /* Before a subexpression? */
+ (syntax & RE_NO_BK_PARENS ? *next == ')'
+ : next_backslash && next_next && *next_next == ')')
+ /* Before an alternative? */
+ || (syntax & RE_NO_BK_VBAR ? *next == '|'
+ : next_backslash && next_next && *next_next == '|');
+}
+
+
+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
+ false if it's not. */
+
+static boolean
+group_in_compile_stack (compile_stack, regnum)
+ compile_stack_type compile_stack;
+ regnum_t regnum;
+{
+ int this_element;
+
+ for (this_element = compile_stack.avail - 1;
+ this_element >= 0;
+ this_element--)
+ if (compile_stack.stack[this_element].regnum == regnum)
+ return true;
+
+ return false;
+}
+
+
+/* Read the ending character of a range (in a bracket expression) from the
+ uncompiled pattern *P_PTR (which ends at PEND). We assume the
+ starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
+ Then we set the translation of all bits between the starting and
+ ending characters (inclusive) in the compiled pattern B.
+
+ Return an error code.
+
+ We use these short variable names so we can use the same macros as
+ `regex_compile' itself. */
+
+static reg_errcode_t
+compile_range (p_ptr, pend, translate, syntax, b)
+ const char **p_ptr, *pend;
+ char *translate;
+ reg_syntax_t syntax;
+ unsigned char *b;
+{
+ unsigned this_char;
+
+ const char *p = *p_ptr;
+ int range_start, range_end;
+
+ if (p == pend)
+ return REG_ERANGE;
+
+ /* Even though the pattern is a signed `char *', we need to fetch
+ with unsigned char *'s; if the high bit of the pattern character
+ is set, the range endpoints will be negative if we fetch using a
+ signed char *.
+
+ We also want to fetch the endpoints without translating them; the
+ appropriate translation is done in the bit-setting loop below. */
+ /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *. */
+ range_start = ((const unsigned char *) p)[-2];
+ range_end = ((const unsigned char *) p)[0];
+
+ /* Have to increment the pointer into the pattern string, so the
+ caller isn't still at the ending character. */
+ (*p_ptr)++;
+
+ /* If the start is after the end, the range is empty. */
+ if (range_start > range_end)
+ return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
+
+ /* Here we see why `this_char' has to be larger than an `unsigned
+ char' -- the range is inclusive, so if `range_end' == 0xff
+ (assuming 8-bit characters), we would otherwise go into an infinite
+ loop, since all characters <= 0xff. */
+ for (this_char = range_start; this_char <= range_end; this_char++)
+ {
+ SET_LIST_BIT (TRANSLATE (this_char));
+ }
+
+ return REG_NOERROR;
+}
+
+/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
+ BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
+ characters can start a string that matches the pattern. This fastmap
+ is used by re_search to skip quickly over impossible starting points.
+
+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
+ area as BUFP->fastmap.
+
+ We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
+ the pattern buffer.
+
+ Returns 0 if we succeed, -2 if an internal error. */
+
+int
+re_compile_fastmap (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ int j, k;
+#ifdef MATCH_MAY_ALLOCATE
+ fail_stack_type fail_stack;
+#endif
+#ifndef REGEX_MALLOC
+ char *destination;
+#endif
+ /* We don't push any register information onto the failure stack. */
+ unsigned num_regs = 0;
+
+ register char *fastmap = bufp->fastmap;
+ unsigned char *pattern = bufp->buffer;
+ unsigned long size = bufp->used;
+ unsigned char *p = pattern;
+ register unsigned char *pend = pattern + size;
+
+ /* Assume that each path through the pattern can be null until
+ proven otherwise. We set this false at the bottom of switch
+ statement, to which we get only if a particular path doesn't
+ match the empty string. */
+ boolean path_can_be_null = true;
+
+ /* We aren't doing a `succeed_n' to begin with. */
+ boolean succeed_n_p = false;
+
+ assert (fastmap != NULL && p != NULL);
+
+ INIT_FAIL_STACK ();
+ bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
+ bufp->fastmap_accurate = 1; /* It will be when we're done. */
+ bufp->can_be_null = 0;
+
+ while (p != pend || !FAIL_STACK_EMPTY ())
+ {
+ if (p == pend)
+ {
+ bufp->can_be_null |= path_can_be_null;
+
+ /* Reset for next path. */
+ path_can_be_null = true;
+
+ p = fail_stack.stack[--fail_stack.avail];
+ }
+
+ /* We should never be about to go beyond the end of the pattern. */
+ assert (p < pend);
+
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((re_opcode_t) *p++))
+#else
+ switch ((re_opcode_t) *p++)
+#endif
+ {
+
+ /* I guess the idea here is to simply not bother with a fastmap
+ if a backreference is used, since it's too hard to figure out
+ the fastmap for the corresponding group. Setting
+ `can_be_null' stops `re_search_2' from using the fastmap, so
+ that is all we do. */
+ case duplicate:
+ bufp->can_be_null = 1;
+ return 0;
+
+
+ /* Following are the cases which match a character. These end
+ with `break'. */
+
+ case exactn:
+ fastmap[p[1]] = 1;
+ break;
+
+
+ case charset:
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+ fastmap[j] = 1;
+ break;
+
+
+ case charset_not:
+ /* Chars beyond end of map must be allowed. */
+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+ fastmap[j] = 1;
+ break;
+
+
+ case wordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == Sword)
+ fastmap[j] = 1;
+ break;
+
+
+ case notwordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != Sword)
+ fastmap[j] = 1;
+ break;
+
+
+ case anychar:
+ {
+ int fastmap_newline = fastmap['\n'];
+
+ /* `.' matches anything ... */
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ /* ... except perhaps newline. */
+ if (!(bufp->syntax & RE_DOT_NEWLINE))
+ fastmap['\n'] = fastmap_newline;
+
+ /* Return if we have already set `can_be_null'; if we have,
+ then the fastmap is irrelevant. Something's wrong here. */
+ else if (bufp->can_be_null)
+ return 0;
+
+ /* Otherwise, have to check alternative paths. */
+ break;
+ }
+
+#ifdef emacs
+ case syntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+
+ case notsyntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+
+ /* All cases after this match the empty string. These end with
+ `continue'. */
+
+
+ case before_dot:
+ case at_dot:
+ case after_dot:
+ continue;
+#endif /* not emacs */
+
+
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+ case push_dummy_failure:
+ continue;
+
+
+ case jump_n:
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case jump_past_alt:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+ if (j > 0)
+ continue;
+
+ /* Jump backward implies we just went through the body of a
+ loop and matched nothing. Opcode jumped to should be
+ `on_failure_jump' or `succeed_n'. Just treat it like an
+ ordinary jump. For a * loop, it has pushed its failure
+ point already; if so, discard that as redundant. */
+ if ((re_opcode_t) *p != on_failure_jump
+ && (re_opcode_t) *p != succeed_n)
+ continue;
+
+ p++;
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+
+ /* If what's on the stack is where we are now, pop it. */
+ if (!FAIL_STACK_EMPTY ()
+ && fail_stack.stack[fail_stack.avail - 1] == p)
+ fail_stack.avail--;
+
+ continue;
+
+
+ case on_failure_jump:
+ case on_failure_keep_string_jump:
+ handle_on_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+
+ /* For some patterns, e.g., `(a?)?', `p+j' here points to the
+ end of the pattern. We don't want to push such a point,
+ since when we restore it above, entering the switch will
+ increment `p' past the end of the pattern. We don't need
+ to push such a point since we obviously won't find any more
+ fastmap entries beyond `pend'. Such a pattern can match
+ the null string, though. */
+ if (p + j < pend)
+ {
+ if (!PUSH_PATTERN_OP (p + j, fail_stack))
+ return -2;
+ }
+ else
+ bufp->can_be_null = 1;
+
+ if (succeed_n_p)
+ {
+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
+ succeed_n_p = false;
+ }
+
+ continue;
+
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p += 2;
+
+ /* Increment p past the n for when k != 0. */
+ EXTRACT_NUMBER_AND_INCR (k, p);
+ if (k == 0)
+ {
+ p -= 4;
+ succeed_n_p = true; /* Spaghetti code alert. */
+ goto handle_on_failure_jump;
+ }
+ continue;
+
+
+ case set_number_at:
+ p += 4;
+ continue;
+
+
+ case start_memory:
+ case stop_memory:
+ p += 2;
+ continue;
+
+
+ default:
+ abort (); /* We have listed all the cases. */
+ } /* switch *p++ */
+
+ /* Getting here means we have found the possible starting
+ characters for one path of the pattern -- and that the empty
+ string does not match. We need not follow this path further.
+ Instead, look at the next alternative (remembered on the
+ stack), or quit if no more. The test at the top of the loop
+ does these things. */
+ path_can_be_null = false;
+ p = pend;
+ } /* while p */
+
+ /* Set `can_be_null' for the last path (also the first path, if the
+ pattern is empty). */
+ bufp->can_be_null |= path_can_be_null;
+ return 0;
+} /* re_compile_fastmap */
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
+ this memory for recording register information. STARTS and ENDS
+ must be allocated using the malloc library routine, and must each
+ be at least NUM_REGS * sizeof (regoff_t) bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+
+void
+re_set_registers (bufp, regs, num_regs, starts, ends)
+ struct re_pattern_buffer *bufp;
+ struct re_registers *regs;
+ unsigned num_regs;
+ regoff_t *starts, *ends;
+{
+ if (num_regs)
+ {
+ bufp->regs_allocated = REGS_REALLOCATE;
+ regs->num_regs = num_regs;
+ regs->start = starts;
+ regs->end = ends;
+ }
+ else
+ {
+ bufp->regs_allocated = REGS_UNALLOCATED;
+ regs->num_regs = 0;
+ regs->start = regs->end = (regoff_t *) 0;
+ }
+}
+
+/* Searching routines. */
+
+/* Like re_search_2, below, but only one string is specified, and
+ doesn't let you say where to stop matching. */
+
+int
+re_search (bufp, string, size, startpos, range, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, startpos, range;
+ struct re_registers *regs;
+{
+ return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
+ regs, size);
+}
+
+
+/* Using the compiled pattern in BUFP->buffer, first tries to match the
+ virtual concatenation of STRING1 and STRING2, starting first at index
+ STARTPOS, then at STARTPOS + 1, and so on.
+
+ STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
+
+ RANGE is how far to scan while trying to match. RANGE = 0 means try
+ only at STARTPOS; in general, the last start tried is STARTPOS +
+ RANGE.
+
+ In REGS, return the indices of the virtual concatenation of STRING1
+ and STRING2 that matched the entire BUFP->buffer and its contained
+ subexpressions.
+
+ Do not consider matching one past the index STOP in the virtual
+ concatenation of STRING1 and STRING2.
+
+ We return either the position in the strings at which the match was
+ found, -1 if no match, or -2 if error (such as failure
+ stack overflow). */
+
+int
+re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int startpos;
+ int range;
+ struct re_registers *regs;
+ int stop;
+{
+ int val;
+ register char *fastmap = bufp->fastmap;
+ register char *translate = bufp->translate;
+ int total_size = size1 + size2;
+ int endpos = startpos + range;
+
+ /* Check for out-of-range STARTPOS. */
+ if (startpos < 0 || startpos > total_size)
+ return -1;
+
+ /* Fix up RANGE if it might eventually take us outside
+ the virtual concatenation of STRING1 and STRING2. */
+ if (endpos < -1)
+ range = -1 - startpos;
+ else if (endpos > total_size)
+ range = total_size - startpos;
+
+ /* If the search isn't to be a backwards one, don't waste time in a
+ search for a pattern that must be anchored. */
+ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0)
+ {
+ if (startpos > 0)
+ return -1;
+ else
+ range = 1;
+ }
+
+ /* Update the fastmap now if not correct already. */
+ if (fastmap && !bufp->fastmap_accurate)
+ if (re_compile_fastmap (bufp) == -2)
+ return -2;
+
+ /* Loop through the string, looking for a place to start matching. */
+ for (;;)
+ {
+ /* If a fastmap is supplied, skip quickly over characters that
+ cannot be the start of a match. If the pattern can match the
+ null string, however, we don't need to skip characters; we want
+ the first null string. */
+ if (fastmap && startpos < total_size && !bufp->can_be_null)
+ {
+ if (range > 0) /* Searching forwards. */
+ {
+ register const char *d;
+ register int lim = 0;
+ int irange = range;
+
+ if (startpos < size1 && startpos + range >= size1)
+ lim = range - (size1 - startpos);
+
+ d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
+
+ /* Written out as an if-else to avoid testing `translate'
+ inside the loop. */
+ if (translate)
+ while (range > lim
+ && !fastmap[(unsigned char)
+ translate[(unsigned char) *d++]])
+ range--;
+ else
+ while (range > lim && !fastmap[(unsigned char) *d++])
+ range--;
+
+ startpos += irange - range;
+ }
+ else /* Searching backwards. */
+ {
+ register char c = (size1 == 0 || startpos >= size1
+ ? string2[startpos - size1]
+ : string1[startpos]);
+
+ if (!fastmap[(unsigned char) TRANSLATE (c)])
+ goto advance;
+ }
+ }
+
+ /* If can't match the null string, and that's all we have left, fail. */
+ if (range >= 0 && startpos == total_size && fastmap
+ && !bufp->can_be_null)
+ return -1;
+
+ val = re_match_2_internal (bufp, string1, size1, string2, size2,
+ startpos, regs, stop);
+#ifndef REGEX_MALLOC
+#ifdef C_ALLOCA
+ alloca (0);
+#endif
+#endif
+
+ if (val >= 0)
+ return startpos;
+
+ if (val == -2)
+ return -2;
+
+ advance:
+ if (!range)
+ break;
+ else if (range > 0)
+ {
+ range--;
+ startpos++;
+ }
+ else
+ {
+ range++;
+ startpos--;
+ }
+ }
+ return -1;
+} /* re_search_2 */
+
+/* Declarations and macros for re_match_2. */
+
+static int bcmp_translate ();
+static boolean alt_match_null_string_p (),
+ common_op_match_null_string_p (),
+ group_match_null_string_p ();
+
+/* This converts PTR, a pointer into one of the search strings `string1'
+ and `string2' into an offset from the beginning of that string. */
+#define POINTER_TO_OFFSET(ptr) \
+ (FIRST_STRING_P (ptr) \
+ ? ((regoff_t) ((ptr) - string1)) \
+ : ((regoff_t) ((ptr) - string2 + size1)))
+
+/* Macros for dealing with the split strings in re_match_2. */
+
+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
+
+/* Call before fetching a character with *d. This switches over to
+ string2 if necessary. */
+#define PREFETCH() \
+ while (d == dend) \
+ { \
+ /* End of string2 => fail. */ \
+ if (dend == end_match_2) \
+ goto fail; \
+ /* End of string1 => advance to string2. */ \
+ d = string2; \
+ dend = end_match_2; \
+ }
+
+
+/* Test if at very beginning or at very end of the virtual concatenation
+ of `string1' and `string2'. If only one string, it's `string2'. */
+#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
+#define AT_STRINGS_END(d) ((d) == end2)
+
+
+/* Test if D points to a character which is word-constituent. We have
+ two special cases to check for: if past the end of string1, look at
+ the first character in string2; and if before the beginning of
+ string2, look at the last character in string1. */
+#define WORDCHAR_P(d) \
+ (SYNTAX ((d) == end1 ? *string2 \
+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
+ == Sword)
+
+/* Test if the character before D and the one at D differ with respect
+ to being word-constituent. */
+#define AT_WORD_BOUNDARY(d) \
+ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
+ || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
+
+
+/* Free everything we malloc. */
+#ifdef MATCH_MAY_ALLOCATE
+#ifdef REGEX_MALLOC
+#define FREE_VAR(var) if (var) free (var); var = NULL
+#define FREE_VARIABLES() \
+ do { \
+ FREE_VAR (fail_stack.stack); \
+ FREE_VAR (regstart); \
+ FREE_VAR (regend); \
+ FREE_VAR (old_regstart); \
+ FREE_VAR (old_regend); \
+ FREE_VAR (best_regstart); \
+ FREE_VAR (best_regend); \
+ FREE_VAR (reg_info); \
+ FREE_VAR (reg_dummy); \
+ FREE_VAR (reg_info_dummy); \
+ } while (0)
+#else /* not REGEX_MALLOC */
+/* This used to do alloca (0), but now we do that in the caller. */
+#define FREE_VARIABLES() /* Nothing */
+#endif /* not REGEX_MALLOC */
+#else
+#define FREE_VARIABLES() /* Do nothing! */
+#endif /* not MATCH_MAY_ALLOCATE */
+
+/* These values must meet several constraints. They must not be valid
+ register values; since we have a limit of 255 registers (because
+ we use only one byte in the pattern for the register number), we can
+ use numbers larger than 255. They must differ by 1, because of
+ NUM_FAILURE_ITEMS above. And the value for the lowest register must
+ be larger than the value for the highest register, so we do not try
+ to actually save any registers when none are active. */
+#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
+#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
+
+/* Matching routines. */
+
+#ifndef emacs /* Emacs never uses this. */
+/* re_match is like re_match_2 except it takes only a single string. */
+
+int
+re_match (bufp, string, size, pos, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, pos;
+ struct re_registers *regs;
+{
+ int result = re_match_2_internal (bufp, NULL, 0, string, size,
+ pos, regs, size);
+ alloca (0);
+ return result;
+}
+#endif /* not emacs */
+
+
+/* re_match_2 matches the compiled pattern in BUFP against the
+ the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
+ and SIZE2, respectively). We start matching at POS, and stop
+ matching at STOP.
+
+ If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
+ store offsets for the substring each group matched in REGS. See the
+ documentation for exactly how many groups we fill.
+
+ We return -1 if no match, -2 if an internal error (such as the
+ failure stack overflowing). Otherwise, we return the length of the
+ matched substring. */
+
+int
+re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int pos;
+ struct re_registers *regs;
+ int stop;
+{
+ int result = re_match_2_internal (bufp, string1, size1, string2, size2,
+ pos, regs, stop);
+ alloca (0);
+ return result;
+}
+
+/* This is a separate function so that we can force an alloca cleanup
+ afterwards. */
+static int
+re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int pos;
+ struct re_registers *regs;
+ int stop;
+{
+ /* General temporaries. */
+ int mcnt;
+ unsigned char *p1;
+
+ /* Just past the end of the corresponding string. */
+ const char *end1, *end2;
+
+ /* Pointers into string1 and string2, just past the last characters in
+ each to consider matching. */
+ const char *end_match_1, *end_match_2;
+
+ /* Where we are in the data, and the end of the current string. */
+ const char *d, *dend;
+
+ /* Where we are in the pattern, and the end of the pattern. */
+ unsigned char *p = bufp->buffer;
+ register unsigned char *pend = p + bufp->used;
+
+ /* Mark the opcode just after a start_memory, so we can test for an
+ empty subpattern when we get to the stop_memory. */
+ unsigned char *just_past_start_mem = 0;
+
+ /* We use this to map every character in the string. */
+ char *translate = bufp->translate;
+
+ /* Failure point stack. Each place that can handle a failure further
+ down the line pushes a failure point on this stack. It consists of
+ restart, regend, and reg_info for all registers corresponding to
+ the subexpressions we're currently inside, plus the number of such
+ registers, and, finally, two char *'s. The first char * is where
+ to resume scanning the pattern; the second one is where to resume
+ scanning the strings. If the latter is zero, the failure point is
+ a ``dummy''; if a failure happens and the failure point is a dummy,
+ it gets discarded and the next next one is tried. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
+ fail_stack_type fail_stack;
+#endif
+#ifdef DEBUG
+ static unsigned failure_id = 0;
+ unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
+#endif
+
+ /* We fill all the registers internally, independent of what we
+ return, for use in backreferences. The number here includes
+ an element for register zero. */
+ unsigned num_regs = bufp->re_nsub + 1;
+
+ /* The currently active registers. */
+ unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+
+ /* Information on the contents of registers. These are pointers into
+ the input strings; they record just what was matched (on this
+ attempt) by a subexpression part of the pattern, that is, the
+ regnum-th regstart pointer points to where in the pattern we began
+ matching and the regnum-th regend points to right after where we
+ stopped matching the regnum-th subexpression. (The zeroth register
+ keeps track of what the whole pattern matches.) */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **regstart, **regend;
+#endif
+
+ /* If a group that's operated upon by a repetition operator fails to
+ match anything, then the register for its start will need to be
+ restored because it will have been set to wherever in the string we
+ are when we last see its open-group operator. Similarly for a
+ register's end. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **old_regstart, **old_regend;
+#endif
+
+ /* The is_active field of reg_info helps us keep track of which (possibly
+ nested) subexpressions we are currently in. The matched_something
+ field of reg_info[reg_num] helps us tell whether or not we have
+ matched any of the pattern so far this time through the reg_num-th
+ subexpression. These two fields get reset each time through any
+ loop their register is in. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
+ register_info_type *reg_info;
+#endif
+
+ /* The following record the register info as found in the above
+ variables when we find a match better than any we've seen before.
+ This happens as we backtrack through the failure points, which in
+ turn happens only if we have not yet matched the entire string. */
+ unsigned best_regs_set = false;
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **best_regstart, **best_regend;
+#endif
+
+ /* Logically, this is `best_regend[0]'. But we don't want to have to
+ allocate space for that if we're not allocating space for anything
+ else (see below). Also, we never need info about register 0 for
+ any of the other register vectors, and it seems rather a kludge to
+ treat `best_regend' differently than the rest. So we keep track of
+ the end of the best match so far in a separate variable. We
+ initialize this to NULL so that when we backtrack the first time
+ and need to test it, it's not garbage. */
+ const char *match_end = NULL;
+
+ /* Used when we pop values we don't care about. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **reg_dummy;
+ register_info_type *reg_info_dummy;
+#endif
+
+#ifdef DEBUG
+ /* Counts the total number of registers pushed. */
+ unsigned num_regs_pushed = 0;
+#endif
+
+ DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
+
+ INIT_FAIL_STACK ();
+
+#ifdef MATCH_MAY_ALLOCATE
+ /* Do not bother to initialize all the register variables if there are
+ no groups in the pattern, as it takes a fair amount of time. If
+ there are groups, we include space for register 0 (the whole
+ pattern), even though we never use it, since it simplifies the
+ array indexing. We should fix this. */
+ if (bufp->re_nsub)
+ {
+ regstart = REGEX_TALLOC (num_regs, const char *);
+ regend = REGEX_TALLOC (num_regs, const char *);
+ old_regstart = REGEX_TALLOC (num_regs, const char *);
+ old_regend = REGEX_TALLOC (num_regs, const char *);
+ best_regstart = REGEX_TALLOC (num_regs, const char *);
+ best_regend = REGEX_TALLOC (num_regs, const char *);
+ reg_info = REGEX_TALLOC (num_regs, register_info_type);
+ reg_dummy = REGEX_TALLOC (num_regs, const char *);
+ reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
+
+ if (!(regstart && regend && old_regstart && old_regend && reg_info
+ && best_regstart && best_regend && reg_dummy && reg_info_dummy))
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ }
+#if defined (REGEX_MALLOC)
+ else
+ {
+ /* We must initialize all our variables to NULL, so that
+ `FREE_VARIABLES' doesn't try to free them. */
+ regstart = regend = old_regstart = old_regend = best_regstart
+ = best_regend = reg_dummy = NULL;
+ reg_info = reg_info_dummy = (register_info_type *) NULL;
+ }
+#endif /* REGEX_MALLOC */
+#endif /* MATCH_MAY_ALLOCATE */
+
+ /* The starting position is bogus. */
+ if (pos < 0 || pos > size1 + size2)
+ {
+ FREE_VARIABLES ();
+ return -1;
+ }
+
+ /* Initialize subexpression text positions to -1 to mark ones that no
+ start_memory/stop_memory has been seen for. Also initialize the
+ register information struct. */
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = regend[mcnt]
+ = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
+
+ REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
+ IS_ACTIVE (reg_info[mcnt]) = 0;
+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ }
+
+ /* We move `string1' into `string2' if the latter's empty -- but not if
+ `string1' is null. */
+ if (size2 == 0 && string1 != NULL)
+ {
+ string2 = string1;
+ size2 = size1;
+ string1 = 0;
+ size1 = 0;
+ }
+ end1 = string1 + size1;
+ end2 = string2 + size2;
+
+ /* Compute where to stop matching, within the two strings. */
+ if (stop <= size1)
+ {
+ end_match_1 = string1 + stop;
+ end_match_2 = string2;
+ }
+ else
+ {
+ end_match_1 = end1;
+ end_match_2 = string2 + stop - size1;
+ }
+
+ /* `p' scans through the pattern as `d' scans through the data.
+ `dend' is the end of the input string that `d' points within. `d'
+ is advanced into the following input string whenever necessary, but
+ this happens before fetching; therefore, at the beginning of the
+ loop, `d' can be pointing at the end of a string, but it cannot
+ equal `string2'. */
+ if (size1 > 0 && pos <= size1)
+ {
+ d = string1 + pos;
+ dend = end_match_1;
+ }
+ else
+ {
+ d = string2 + pos - size1;
+ dend = end_match_2;
+ }
+
+ DEBUG_PRINT1 ("The compiled pattern is: ");
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
+ DEBUG_PRINT1 ("The string to match is: `");
+ DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
+ DEBUG_PRINT1 ("'\n");
+
+ /* This loops over pattern commands. It exits by returning from the
+ function if the match is complete, or it drops through if the match
+ fails at this starting point in the input data. */
+ for (;;)
+ {
+ DEBUG_PRINT2 ("\n0x%x: ", p);
+
+ if (p == pend)
+ { /* End of pattern means we might have succeeded. */
+ DEBUG_PRINT1 ("end of pattern ... ");
+
+ /* If we haven't matched the entire string, and we want the
+ longest match, try backtracking. */
+ if (d != end_match_2)
+ {
+ /* 1 if this match ends in the same string (string1 or string2)
+ as the best previous match. */
+ boolean same_str_p = (FIRST_STRING_P (match_end)
+ == MATCHING_IN_FIRST_STRING);
+ /* 1 if this match is the best seen so far. */
+ boolean best_match_p;
+
+ /* AIX compiler got confused when this was combined
+ with the previous declaration. */
+ if (same_str_p)
+ best_match_p = d > match_end;
+ else
+ best_match_p = !MATCHING_IN_FIRST_STRING;
+
+ DEBUG_PRINT1 ("backtracking.\n");
+
+ if (!FAIL_STACK_EMPTY ())
+ { /* More failure points to try. */
+
+ /* If exceeds best match so far, save it. */
+ if (!best_regs_set || best_match_p)
+ {
+ best_regs_set = true;
+ match_end = d;
+
+ DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
+
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ best_regstart[mcnt] = regstart[mcnt];
+ best_regend[mcnt] = regend[mcnt];
+ }
+ }
+ goto fail;
+ }
+
+ /* If no failure points, don't restore garbage. And if
+ last match is real best match, don't restore second
+ best one. */
+ else if (best_regs_set && !best_match_p)
+ {
+ restore_best_regs:
+ /* Restore best match. It may happen that `dend ==
+ end_match_1' while the restored d is in string2.
+ For example, the pattern `x.*y.*z' against the
+ strings `x-' and `y-z-', if the two strings are
+ not consecutive in memory. */
+ DEBUG_PRINT1 ("Restoring best registers.\n");
+
+ d = match_end;
+ dend = ((d >= string1 && d <= end1)
+ ? end_match_1 : end_match_2);
+
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = best_regstart[mcnt];
+ regend[mcnt] = best_regend[mcnt];
+ }
+ }
+ } /* d != end_match_2 */
+
+ DEBUG_PRINT1 ("Accepting match.\n");
+
+ /* If caller wants register contents data back, do it. */
+ if (regs && !bufp->no_sub)
+ {
+ /* Have the register data arrays been allocated? */
+ if (bufp->regs_allocated == REGS_UNALLOCATED)
+ { /* No. So allocate them with malloc. We need one
+ extra element beyond `num_regs' for the `-1' marker
+ GNU code uses. */
+ regs->num_regs = MAX (RE_NREGS, num_regs + 1);
+ regs->start = TALLOC (regs->num_regs, regoff_t);
+ regs->end = TALLOC (regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ return -2;
+ bufp->regs_allocated = REGS_REALLOCATE;
+ }
+ else if (bufp->regs_allocated == REGS_REALLOCATE)
+ { /* Yes. If we need more elements than were already
+ allocated, reallocate them. If we need fewer, just
+ leave it alone. */
+ if (regs->num_regs < num_regs + 1)
+ {
+ regs->num_regs = num_regs + 1;
+ RETALLOC (regs->start, regs->num_regs, regoff_t);
+ RETALLOC (regs->end, regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ return -2;
+ }
+ }
+ else
+ {
+ /* These braces fend off a "empty body in an else-statement"
+ warning under GCC when assert expands to nothing. */
+ assert (bufp->regs_allocated == REGS_FIXED);
+ }
+
+ /* Convert the pointer data in `regstart' and `regend' to
+ indices. Register zero has to be set differently,
+ since we haven't kept track of any info for it. */
+ if (regs->num_regs > 0)
+ {
+ regs->start[0] = pos;
+ regs->end[0] = (MATCHING_IN_FIRST_STRING
+ ? ((regoff_t) (d - string1))
+ : ((regoff_t) (d - string2 + size1)));
+ }
+
+ /* Go through the first `min (num_regs, regs->num_regs)'
+ registers, since that is all we initialized. */
+ for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++)
+ {
+ if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ else
+ {
+ regs->start[mcnt]
+ = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
+ regs->end[mcnt]
+ = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
+ }
+ }
+
+ /* If the regs structure we return has more elements than
+ were in the pattern, set the extra elements to -1. If
+ we (re)allocated the registers, this is the case,
+ because we always allocate enough to have at least one
+ -1 at the end. */
+ for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++)
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ } /* regs && !bufp->no_sub */
+
+ FREE_VARIABLES ();
+ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
+ nfailure_points_pushed, nfailure_points_popped,
+ nfailure_points_pushed - nfailure_points_popped);
+ DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
+
+ mcnt = d - pos - (MATCHING_IN_FIRST_STRING
+ ? string1
+ : string2 - size1);
+
+ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
+
+ return mcnt;
+ }
+
+ /* Otherwise match next pattern command. */
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((re_opcode_t) *p++))
+#else
+ switch ((re_opcode_t) *p++)
+#endif
+ {
+ /* Ignore these. Used to ignore the n of succeed_n's which
+ currently have n == 0. */
+ case no_op:
+ DEBUG_PRINT1 ("EXECUTING no_op.\n");
+ break;
+
+
+ /* Match the next n pattern characters exactly. The following
+ byte in the pattern defines n, and the n bytes after that
+ are the characters to match. */
+ case exactn:
+ mcnt = *p++;
+ DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
+
+ /* This is written out as an if-else so we don't waste time
+ testing `translate' inside the loop. */
+ if (translate)
+ {
+ do
+ {
+ PREFETCH ();
+ if (translate[(unsigned char) *d++] != (char) *p++)
+ goto fail;
+ }
+ while (--mcnt);
+ }
+ else
+ {
+ do
+ {
+ PREFETCH ();
+ if (*d++ != (char) *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ SET_REGS_MATCHED ();
+ break;
+
+
+ /* Match any character except possibly a newline or a null. */
+ case anychar:
+ DEBUG_PRINT1 ("EXECUTING anychar.\n");
+
+ PREFETCH ();
+
+ if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
+ || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
+ goto fail;
+
+ SET_REGS_MATCHED ();
+ DEBUG_PRINT2 (" Matched `%d'.\n", *d);
+ d++;
+ break;
+
+
+ case charset:
+ case charset_not:
+ {
+ register unsigned char c;
+ boolean not = (re_opcode_t) *(p - 1) == charset_not;
+
+ DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
+
+ PREFETCH ();
+ c = TRANSLATE (*d); /* The character to match. */
+
+ /* Cast to `unsigned' instead of `unsigned char' in case the
+ bit list is a full 32 bytes long. */
+ if (c < (unsigned) (*p * BYTEWIDTH)
+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ p += 1 + *p;
+
+ if (!not) goto fail;
+
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+ }
+
+
+ /* The beginning of a group is represented by start_memory.
+ The arguments are the register number in the next byte, and the
+ number of groups inner to this one in the next. The text
+ matched within the group is recorded (in the internal
+ registers data structure) under the register number. */
+ case start_memory:
+ DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]);
+
+ /* Find out if this group can match the empty string. */
+ p1 = p; /* To send to group_match_null_string_p. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[*p])
+ = group_match_null_string_p (&p1, pend, reg_info);
+
+ /* Save the position in the string where we were the last time
+ we were at this open-group operator in case the group is
+ operated upon by a repetition operator, e.g., with `(a*)*b'
+ against `ab'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
+ : regstart[*p];
+ DEBUG_PRINT2 (" old_regstart: %d\n",
+ POINTER_TO_OFFSET (old_regstart[*p]));
+
+ regstart[*p] = d;
+ DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
+
+ IS_ACTIVE (reg_info[*p]) = 1;
+ MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* This is the new highest active register. */
+ highest_active_reg = *p;
+
+ /* If nothing was active before, this is the new lowest active
+ register. */
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *p;
+
+ /* Move past the register number and inner group count. */
+ p += 2;
+ just_past_start_mem = p;
+ break;
+
+
+ /* The stop_memory opcode represents the end of a group. Its
+ arguments are the same as start_memory's: the register
+ number, and the number of inner groups. */
+ case stop_memory:
+ DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
+
+ /* We need to save the string position the last time we were at
+ this close-group operator in case the group is operated
+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
+ against `aba'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
+ : regend[*p];
+ DEBUG_PRINT2 (" old_regend: %d\n",
+ POINTER_TO_OFFSET (old_regend[*p]));
+
+ regend[*p] = d;
+ DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
+
+ /* This register isn't active anymore. */
+ IS_ACTIVE (reg_info[*p]) = 0;
+
+ /* If this was the only register active, nothing is active
+ anymore. */
+ if (lowest_active_reg == highest_active_reg)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ { /* We must scan for the new highest active register, since
+ it isn't necessarily one less than now: consider
+ (a(b)c(d(e)f)g). When group 3 ends, after the f), the
+ new highest active register is 1. */
+ unsigned char r = *p - 1;
+ while (r > 0 && !IS_ACTIVE (reg_info[r]))
+ r--;
+
+ /* If we end up at register zero, that means that we saved
+ the registers as the result of an `on_failure_jump', not
+ a `start_memory', and we jumped to past the innermost
+ `stop_memory'. For example, in ((.)*) we save
+ registers 1 and 2 as a result of the *, but when we pop
+ back to the second ), we are at the stop_memory 1.
+ Thus, nothing is active. */
+ if (r == 0)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ highest_active_reg = r;
+ }
+
+ /* If just failed to match something this time around with a
+ group that's operated on by a repetition operator, try to
+ force exit from the ``loop'', and restore the register
+ information for this group that we had before trying this
+ last match. */
+ if ((!MATCHED_SOMETHING (reg_info[*p])
+ || just_past_start_mem == p - 1)
+ && (p + 2) < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ p1 = p + 2;
+ mcnt = 0;
+ switch ((re_opcode_t) *p1++)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (is_a_jump_n)
+ p1 += 2;
+ break;
+
+ default:
+ /* do nothing */ ;
+ }
+ p1 += mcnt;
+
+ /* If the next operation is a jump backwards in the pattern
+ to an on_failure_jump right before the start_memory
+ corresponding to this stop_memory, exit from the loop
+ by forcing a failure after pushing on the stack the
+ on_failure_jump's jump in the pattern, and d. */
+ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
+ && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
+ {
+ /* If this group ever matched anything, then restore
+ what its registers were before trying this last
+ failed match, e.g., with `(a*)*b' against `ab' for
+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
+ against `aba' for regend[3].
+
+ Also restore the registers for inner groups for,
+ e.g., `((a*)(b*))*' against `aba' (register 3 would
+ otherwise get trashed). */
+
+ if (EVER_MATCHED_SOMETHING (reg_info[*p]))
+ {
+ unsigned r;
+
+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* Restore this and inner groups' (if any) registers. */
+ for (r = *p; r < *p + *(p + 1); r++)
+ {
+ regstart[r] = old_regstart[r];
+
+ /* xx why this test? */
+ if ((int) old_regend[r] >= (int) regstart[r])
+ regend[r] = old_regend[r];
+ }
+ }
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
+
+ goto fail;
+ }
+ }
+
+ /* Move past the register number and the inner group count. */
+ p += 2;
+ break;
+
+
+ /* \<digit> has been turned into a `duplicate' command which is
+ followed by the numeric value of <digit> as the register number. */
+ case duplicate:
+ {
+ register const char *d2, *dend2;
+ int regno = *p++; /* Get which register to match against. */
+ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
+
+ /* Can't back reference a group which we've never matched. */
+ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
+ goto fail;
+
+ /* Where in input to try to start matching. */
+ d2 = regstart[regno];
+
+ /* Where to stop matching; if both the place to start and
+ the place to stop matching are in the same string, then
+ set to the place to stop, otherwise, for now have to use
+ the end of the first string. */
+
+ dend2 = ((FIRST_STRING_P (regstart[regno])
+ == FIRST_STRING_P (regend[regno]))
+ ? regend[regno] : end_match_1);
+ for (;;)
+ {
+ /* If necessary, advance to next segment in register
+ contents. */
+ while (d2 == dend2)
+ {
+ if (dend2 == end_match_2) break;
+ if (dend2 == regend[regno]) break;
+
+ /* End of string1 => advance to string2. */
+ d2 = string2;
+ dend2 = regend[regno];
+ }
+ /* At end of register contents => success */
+ if (d2 == dend2) break;
+
+ /* If necessary, advance to next segment in data. */
+ PREFETCH ();
+
+ /* How many characters left in this segment to match. */
+ mcnt = dend - d;
+
+ /* Want how many consecutive characters we can match in
+ one shot, so, if necessary, adjust the count. */
+ if (mcnt > dend2 - d2)
+ mcnt = dend2 - d2;
+
+ /* Compare that many; failure if mismatch, else move
+ past them. */
+ if (translate
+ ? bcmp_translate (d, d2, mcnt, translate)
+ : bcmp (d, d2, mcnt))
+ goto fail;
+ d += mcnt, d2 += mcnt;
+ }
+ }
+ break;
+
+
+ /* begline matches the empty string at the beginning of the string
+ (unless `not_bol' is set in `bufp'), and, if
+ `newline_anchor' is set, after newlines. */
+ case begline:
+ DEBUG_PRINT1 ("EXECUTING begline.\n");
+
+ if (AT_STRINGS_BEG (d))
+ {
+ if (!bufp->not_bol) break;
+ }
+ else if (d[-1] == '\n' && bufp->newline_anchor)
+ {
+ break;
+ }
+ /* In all other cases, we fail. */
+ goto fail;
+
+
+ /* endline is the dual of begline. */
+ case endline:
+ DEBUG_PRINT1 ("EXECUTING endline.\n");
+
+ if (AT_STRINGS_END (d))
+ {
+ if (!bufp->not_eol) break;
+ }
+
+ /* We have to ``prefetch'' the next character. */
+ else if ((d == end1 ? *string2 : *d) == '\n'
+ && bufp->newline_anchor)
+ {
+ break;
+ }
+ goto fail;
+
+
+ /* Match at the very beginning of the data. */
+ case begbuf:
+ DEBUG_PRINT1 ("EXECUTING begbuf.\n");
+ if (AT_STRINGS_BEG (d))
+ break;
+ goto fail;
+
+
+ /* Match at the very end of the data. */
+ case endbuf:
+ DEBUG_PRINT1 ("EXECUTING endbuf.\n");
+ if (AT_STRINGS_END (d))
+ break;
+ goto fail;
+
+
+ /* on_failure_keep_string_jump is used to optimize `.*\n'. It
+ pushes NULL as the value for the string on the stack. Then
+ `pop_failure_point' will keep the current value for the
+ string, instead of restoring it. To see why, consider
+ matching `foo\nbar' against `.*\n'. The .* matches the foo;
+ then the . fails against the \n. But the next thing we want
+ to do is match the \n against the \n; if we restored the
+ string value, we would be back at the foo.
+
+ Because this is used only in specific cases, we don't need to
+ check all the things that `on_failure_jump' does, to make
+ sure the right things get saved on the stack. Hence we don't
+ share its code. The only reason to push anything on the
+ stack at all is that otherwise we would have to change
+ `anychar's code to do something besides goto fail in this
+ case; that seems worse than this. */
+ case on_failure_keep_string_jump:
+ DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
+
+ PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
+ break;
+
+
+ /* Uses of on_failure_jump:
+
+ Each alternative starts with an on_failure_jump that points
+ to the beginning of the next alternative. Each alternative
+ except the last ends with a jump that in effect jumps past
+ the rest of the alternatives. (They really jump to the
+ ending jump of the following alternative, because tensioning
+ these jumps is a hassle.)
+
+ Repeats start with an on_failure_jump that points past both
+ the repetition text and either the following jump or
+ pop_failure_jump back to this on_failure_jump. */
+ case on_failure_jump:
+ on_failure:
+ DEBUG_PRINT1 ("EXECUTING on_failure_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
+
+ /* If this on_failure_jump comes right before a group (i.e.,
+ the original * applied to a group), save the information
+ for that group and all inner ones, so that if we fail back
+ to this point, the group's information will be correct.
+ For example, in \(a*\)*\1, we need the preceding group,
+ and in \(\(a*\)b*\)\2, we need the inner group. */
+
+ /* We can't use `p' to check ahead because we push
+ a failure point to `p + mcnt' after we do this. */
+ p1 = p;
+
+ /* We need to skip no_op's before we look for the
+ start_memory in case this on_failure_jump is happening as
+ the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
+ against aba. */
+ while (p1 < pend && (re_opcode_t) *p1 == no_op)
+ p1++;
+
+ if (p1 < pend && (re_opcode_t) *p1 == start_memory)
+ {
+ /* We have a new highest active register now. This will
+ get reset at the start_memory we are about to get to,
+ but we will have saved all the registers relevant to
+ this repetition op, as described above. */
+ highest_active_reg = *(p1 + 1) + *(p1 + 2);
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *(p1 + 1);
+ }
+
+ DEBUG_PRINT1 (":\n");
+ PUSH_FAILURE_POINT (p + mcnt, d, -2);
+ break;
+
+
+ /* A smart repeat ends with `maybe_pop_jump'.
+ We change it to either `pop_failure_jump' or `jump'. */
+ case maybe_pop_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
+ {
+ register unsigned char *p2 = p;
+
+ /* Compare the beginning of the repeat with what in the
+ pattern follows its end. If we can establish that there
+ is nothing that they would both match, i.e., that we
+ would have to backtrack because of (as in, e.g., `a*a')
+ then we can change to pop_failure_jump, because we'll
+ never have to backtrack.
+
+ This is not true in the case of alternatives: in
+ `(a|ab)*' we do need to backtrack to the `ab' alternative
+ (e.g., if the string was `ab'). But instead of trying to
+ detect that here, the alternative has put on a dummy
+ failure point which is what we will end up popping. */
+
+ /* Skip over open/close-group commands.
+ If what follows this loop is a ...+ construct,
+ look at what begins its body, since we will have to
+ match at least one of that. */
+ while (1)
+ {
+ if (p2 + 2 < pend
+ && ((re_opcode_t) *p2 == stop_memory
+ || (re_opcode_t) *p2 == start_memory))
+ p2 += 3;
+ else if (p2 + 6 < pend
+ && (re_opcode_t) *p2 == dummy_failure_jump)
+ p2 += 6;
+ else
+ break;
+ }
+
+ p1 = p + mcnt;
+ /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
+ to the `maybe_finalize_jump' of this case. Examine what
+ follows. */
+
+ /* If we're at the end of the pattern, we can change. */
+ if (p2 == pend)
+ {
+ /* Consider what happens when matching ":\(.*\)"
+ against ":/". I don't really understand this code
+ yet. */
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1
+ (" End of pattern: change to `pop_failure_jump'.\n");
+ }
+
+ else if ((re_opcode_t) *p2 == exactn
+ || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
+ {
+ register unsigned char c
+ = *p2 == (unsigned char) endline ? '\n' : p2[2];
+
+ if ((re_opcode_t) p1[3] == exactn && p1[5] != c)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
+ c, p1[5]);
+ }
+
+ else if ((re_opcode_t) p1[3] == charset
+ || (re_opcode_t) p1[3] == charset_not)
+ {
+ int not = (re_opcode_t) p1[3] == charset_not;
+
+ if (c < (unsigned char) (p1[4] * BYTEWIDTH)
+ && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ /* `not' is equal to 1 if c would match, which means
+ that we can't change to pop_failure_jump. */
+ if (!not)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ }
+ else if ((re_opcode_t) *p2 == charset)
+ {
+#ifdef DEBUG
+ register unsigned char c
+ = *p2 == (unsigned char) endline ? '\n' : p2[2];
+#endif
+
+ if ((re_opcode_t) p1[3] == exactn
+ && ! ((int) p2[1] * BYTEWIDTH > (int) p1[4]
+ && (p2[1 + p1[4] / BYTEWIDTH]
+ & (1 << (p1[4] % BYTEWIDTH)))))
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
+ c, p1[5]);
+ }
+
+ else if ((re_opcode_t) p1[3] == charset_not)
+ {
+ int idx;
+ /* We win if the charset_not inside the loop
+ lists every character listed in the charset after. */
+ for (idx = 0; idx < (int) p2[1]; idx++)
+ if (! (p2[2 + idx] == 0
+ || (idx < (int) p1[4]
+ && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
+ break;
+
+ if (idx == p2[1])
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ else if ((re_opcode_t) p1[3] == charset)
+ {
+ int idx;
+ /* We win if the charset inside the loop
+ has no overlap with the one after the loop. */
+ for (idx = 0;
+ idx < (int) p2[1] && idx < (int) p1[4];
+ idx++)
+ if ((p2[2 + idx] & p1[5 + idx]) != 0)
+ break;
+
+ if (idx == p2[1] || idx == p1[4])
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ }
+ }
+ p -= 2; /* Point at relative address again. */
+ if ((re_opcode_t) p[-1] != pop_failure_jump)
+ {
+ p[-1] = (unsigned char) jump;
+ DEBUG_PRINT1 (" Match => jump.\n");
+ goto unconditional_jump;
+ }
+ /* Note fall through. */
+
+
+ /* The end of a simple repeat has a pop_failure_jump back to
+ its matching on_failure_jump, where the latter will push a
+ failure point. The pop_failure_jump takes off failure
+ points put on by this pop_failure_jump's matching
+ on_failure_jump; we got through the pattern to here from the
+ matching on_failure_jump, so didn't fail. */
+ case pop_failure_jump:
+ {
+ /* We need to pass separate storage for the lowest and
+ highest registers, even though we don't care about the
+ actual values. Otherwise, we will restore only one
+ register from the stack, since lowest will == highest in
+ `pop_failure_point'. */
+ unsigned dummy_low_reg, dummy_high_reg;
+ unsigned char *pdummy;
+ const char *sdummy;
+
+ DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
+ POP_FAILURE_POINT (sdummy, pdummy,
+ dummy_low_reg, dummy_high_reg,
+ reg_dummy, reg_dummy, reg_info_dummy);
+ }
+ /* Note fall through. */
+
+
+ /* Unconditionally jump (without popping any failure points). */
+ case jump:
+ unconditional_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
+ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
+ p += mcnt; /* Do the jump. */
+ DEBUG_PRINT2 ("(to 0x%x).\n", p);
+ break;
+
+
+ /* We need this opcode so we can detect where alternatives end
+ in `group_match_null_string_p' et al. */
+ case jump_past_alt:
+ DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
+ goto unconditional_jump;
+
+
+ /* Normally, the on_failure_jump pushes a failure point, which
+ then gets popped at pop_failure_jump. We will end up at
+ pop_failure_jump, also, and with a pattern of, say, `a+', we
+ are skipping over the on_failure_jump, so we have to push
+ something meaningless for pop_failure_jump to pop. */
+ case dummy_failure_jump:
+ DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
+ /* It doesn't matter what we push for the string here. What
+ the code at `fail' tests is the value for the pattern. */
+ PUSH_FAILURE_POINT (0, 0, -2);
+ goto unconditional_jump;
+
+
+ /* At the end of an alternative, we need to push a dummy failure
+ point in case we are followed by a `pop_failure_jump', because
+ we don't want the failure point for the alternative to be
+ popped. For example, matching `(a|ab)*' against `aab'
+ requires that we match the `ab' alternative. */
+ case push_dummy_failure:
+ DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
+ /* See comments just above at `dummy_failure_jump' about the
+ two zeroes. */
+ PUSH_FAILURE_POINT (0, 0, -2);
+ break;
+
+ /* Have to succeed matching what follows at least n times.
+ After that, handle like `on_failure_jump'. */
+ case succeed_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
+
+ assert (mcnt >= 0);
+ /* Originally, this is how many times we HAVE to succeed. */
+ if (mcnt > 0)
+ {
+ mcnt--;
+ p += 2;
+ STORE_NUMBER_AND_INCR (p, mcnt);
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt);
+ }
+ else if (mcnt == 0)
+ {
+ DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2);
+ p[2] = (unsigned char) no_op;
+ p[3] = (unsigned char) no_op;
+ goto on_failure;
+ }
+ break;
+
+ case jump_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
+
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt)
+ {
+ mcnt--;
+ STORE_NUMBER (p + 2, mcnt);
+ goto unconditional_jump;
+ }
+ /* If don't have to jump any more, skip over the rest of command. */
+ else
+ p += 4;
+ break;
+
+ case set_number_at:
+ {
+ DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p1 = p + mcnt;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
+ STORE_NUMBER (p1, mcnt);
+ break;
+ }
+
+ case wordbound:
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
+ break;
+ goto fail;
+
+ case notwordbound:
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
+ goto fail;
+ break;
+
+ case wordbeg:
+ DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
+ if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
+ break;
+ goto fail;
+
+ case wordend:
+ DEBUG_PRINT1 ("EXECUTING wordend.\n");
+ if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
+ && (!WORDCHAR_P (d) || AT_STRINGS_END (d)))
+ break;
+ goto fail;
+
+#ifdef emacs
+ case before_dot:
+ DEBUG_PRINT1 ("EXECUTING before_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) >= point)
+ goto fail;
+ break;
+
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) != point)
+ goto fail;
+ break;
+
+ case after_dot:
+ DEBUG_PRINT1 ("EXECUTING after_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) <= point)
+ goto fail;
+ break;
+#if 0 /* not emacs19 */
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point)
+ goto fail;
+ break;
+#endif /* not emacs19 */
+
+ case syntaxspec:
+ DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
+ mcnt = *p++;
+ goto matchsyntax;
+
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
+ mcnt = (int) Sword;
+ matchsyntax:
+ PREFETCH ();
+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
+ d++;
+ if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+ case notsyntaxspec:
+ DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
+ mcnt = *p++;
+ goto matchnotsyntax;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
+ mcnt = (int) Sword;
+ matchnotsyntax:
+ PREFETCH ();
+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
+ d++;
+ if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+#else /* not emacs */
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
+ PREFETCH ();
+ if (!WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
+ PREFETCH ();
+ if (WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+#endif /* not emacs */
+
+ default:
+ abort ();
+ }
+ continue; /* Successfully executed one pattern command; keep going. */
+
+
+ /* We goto here if a matching operation fails. */
+ fail:
+ if (!FAIL_STACK_EMPTY ())
+ { /* A restart point is known. Restore to that state. */
+ DEBUG_PRINT1 ("\nFAIL:\n");
+ POP_FAILURE_POINT (d, p,
+ lowest_active_reg, highest_active_reg,
+ regstart, regend, reg_info);
+
+ /* If this failure point is a dummy, try the next one. */
+ if (!p)
+ goto fail;
+
+ /* If we failed to the end of the pattern, don't examine *p. */
+ assert (p <= pend);
+ if (p < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ /* If failed to a backwards jump that's part of a repetition
+ loop, need to pop this failure point and use the next one. */
+ switch ((re_opcode_t) *p)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case maybe_pop_jump:
+ case pop_failure_jump:
+ case jump:
+ p1 = p + 1;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+
+ if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
+ || (!is_a_jump_n
+ && (re_opcode_t) *p1 == on_failure_jump))
+ goto fail;
+ break;
+ default:
+ /* do nothing */ ;
+ }
+ }
+
+ if (d >= string1 && d <= end1)
+ dend = end_match_1;
+ }
+ else
+ break; /* Matching at this starting point really fails. */
+ } /* for (;;) */
+
+ if (best_regs_set)
+ goto restore_best_regs;
+
+ FREE_VARIABLES ();
+
+ return -1; /* Failure to match. */
+} /* re_match_2 */
+
+/* Subroutine definitions for re_match_2. */
+
+
+/* We are passed P pointing to a register number after a start_memory.
+
+ Return true if the pattern up to the corresponding stop_memory can
+ match the empty string, and false otherwise.
+
+ If we find the matching stop_memory, sets P to point to one past its number.
+ Otherwise, sets P to an undefined byte less than or equal to END.
+
+ We don't handle duplicates properly (yet). */
+
+static boolean
+group_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ /* Point to after the args to the start_memory. */
+ unsigned char *p1 = *p + 2;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and return true or
+ false, as appropriate, when we get to one that can't, or to the
+ matching stop_memory. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* Could be either a loop or a series of alternatives. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ /* If the next operation is not a jump backwards in the
+ pattern. */
+
+ if (mcnt >= 0)
+ {
+ /* Go through the on_failure_jumps of the alternatives,
+ seeing if any of the alternatives cannot match nothing.
+ The last alternative starts with only a jump,
+ whereas the rest start with on_failure_jump and end
+ with a jump, e.g., here is the pattern for `a|b|c':
+
+ /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
+ /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
+ /exactn/1/c
+
+ So, we have to first go through the first (n-1)
+ alternatives and then deal with the last one separately. */
+
+
+ /* Deal with the first (n-1) alternatives, which start
+ with an on_failure_jump (see above) that jumps to right
+ past a jump_past_alt. */
+
+ while ((re_opcode_t) p1[mcnt-3] == jump_past_alt)
+ {
+ /* `mcnt' holds how many bytes long the alternative
+ is, including the ending `jump_past_alt' and
+ its number. */
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
+ reg_info))
+ return false;
+
+ /* Move to right after this alternative, including the
+ jump_past_alt. */
+ p1 += mcnt;
+
+ /* Break if it's the beginning of an n-th alternative
+ that doesn't begin with an on_failure_jump. */
+ if ((re_opcode_t) *p1 != on_failure_jump)
+ break;
+
+ /* Still have to check that it's not an n-th
+ alternative that starts with an on_failure_jump. */
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if ((re_opcode_t) p1[mcnt-3] != jump_past_alt)
+ {
+ /* Get to the beginning of the n-th alternative. */
+ p1 -= 3;
+ break;
+ }
+ }
+
+ /* Deal with the last alternative: go back and get number
+ of the `jump_past_alt' just before it. `mcnt' contains
+ the length of the alternative. */
+ EXTRACT_NUMBER (mcnt, p1 - 2);
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
+ return false;
+
+ p1 += mcnt; /* Get past the n-th alternative. */
+ } /* if mcnt > 0 */
+ break;
+
+
+ case stop_memory:
+ assert (p1[1] == **p);
+ *p = p1 + 2;
+ return true;
+
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return false;
+} /* group_match_null_string_p */
+
+
+/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
+ It expects P to be the first byte of a single alternative and END one
+ byte past the last. The alternative can contain groups. */
+
+static boolean
+alt_match_null_string_p (p, end, reg_info)
+ unsigned char *p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ unsigned char *p1 = p;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and break when we get
+ to one that can't. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* It's a loop. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ break;
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return true;
+} /* alt_match_null_string_p */
+
+
+/* Deals with the ops common to group_match_null_string_p and
+ alt_match_null_string_p.
+
+ Sets P to one after the op and its arguments, if any. */
+
+static boolean
+common_op_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ boolean ret;
+ int reg_no;
+ unsigned char *p1 = *p;
+
+ switch ((re_opcode_t) *p1++)
+ {
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbeg:
+ case wordend:
+ case wordbound:
+ case notwordbound:
+#ifdef emacs
+ case before_dot:
+ case at_dot:
+ case after_dot:
+#endif
+ break;
+
+ case start_memory:
+ reg_no = *p1;
+ assert (reg_no > 0 && reg_no <= MAX_REGNUM);
+ ret = group_match_null_string_p (&p1, end, reg_info);
+
+ /* Have to set this here in case we're checking a group which
+ contains a group and a back reference to it. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
+
+ if (!ret)
+ return false;
+ break;
+
+ /* If this is an optimized succeed_n for zero times, make the jump. */
+ case jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (mcnt >= 0)
+ p1 += mcnt;
+ else
+ return false;
+ break;
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p1 += 2;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ if (mcnt == 0)
+ {
+ p1 -= 4;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ }
+ else
+ return false;
+ break;
+
+ case duplicate:
+ if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
+ return false;
+ break;
+
+ case set_number_at:
+ p1 += 4;
+
+ default:
+ /* All other opcodes mean we cannot match the empty string. */
+ return false;
+ }
+
+ *p = p1;
+ return true;
+} /* common_op_match_null_string_p */
+
+
+/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
+ bytes; nonzero otherwise. */
+
+static int
+bcmp_translate (s1, s2, len, translate)
+ unsigned char *s1, *s2;
+ register int len;
+ char *translate;
+{
+ register unsigned char *p1 = s1, *p2 = s2;
+ while (len)
+ {
+ if (translate[*p1++] != translate[*p2++]) return 1;
+ len--;
+ }
+ return 0;
+}
+
+/* Entry points for GNU code. */
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+ compiles PATTERN (of length SIZE) and puts the result in BUFP.
+ Returns 0 if the pattern was valid, otherwise an error string.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+ are set in BUFP on entry.
+
+ We call regex_compile to do the actual compilation. */
+
+const char *
+re_compile_pattern (pattern, length, bufp)
+ const char *pattern;
+ int length;
+ struct re_pattern_buffer *bufp;
+{
+ reg_errcode_t ret;
+
+ /* GNU code is written to assume at least RE_NREGS registers will be set
+ (and at least one extra will be -1). */
+ bufp->regs_allocated = REGS_UNALLOCATED;
+
+ /* And GNU code determines whether or not to get register information
+ by passing null for the REGS argument to re_match, etc., not by
+ setting no_sub. */
+ bufp->no_sub = 0;
+
+ /* Match anchors at newline. */
+ bufp->newline_anchor = 1;
+
+ ret = regex_compile (pattern, length, re_syntax_options, bufp);
+
+ return re_error_msg[(int) ret];
+}
+
+/* Entry points compatible with 4.2 BSD regex library. We don't define
+ them unless specifically requested. */
+
+#ifdef _REGEX_RE_COMP
+
+/* BSD has one and only one pattern buffer. */
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+re_comp (s)
+ const char *s;
+{
+ reg_errcode_t ret;
+
+ if (!s)
+ {
+ if (!re_comp_buf.buffer)
+ return "No previous regular expression";
+ return 0;
+ }
+
+ if (!re_comp_buf.buffer)
+ {
+ re_comp_buf.buffer = (unsigned char *) malloc (200);
+ if (re_comp_buf.buffer == NULL)
+ return "Memory exhausted";
+ re_comp_buf.allocated = 200;
+
+ re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
+ if (re_comp_buf.fastmap == NULL)
+ return "Memory exhausted";
+ }
+
+ /* Since `re_exec' always passes NULL for the `regs' argument, we
+ don't need to initialize the pattern buffer fields which affect it. */
+
+ /* Match anchors at newlines. */
+ re_comp_buf.newline_anchor = 1;
+
+ ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
+
+ /* Yes, we're discarding `const' here. */
+ return (char *) re_error_msg[(int) ret];
+}
+
+
+int
+re_exec (s)
+ const char *s;
+{
+ const int len = strlen (s);
+ return
+ 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
+}
+#endif /* _REGEX_RE_COMP */
+
+/* POSIX.2 functions. Don't define these for Emacs. */
+
+#ifndef emacs
+
+/* regcomp takes a regular expression as a string and compiles it.
+
+ PREG is a regex_t *. We do not expect any fields to be initialized,
+ since POSIX says we shouldn't. Thus, we set
+
+ `buffer' to the compiled pattern;
+ `used' to the length of the compiled pattern;
+ `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+ REG_EXTENDED bit in CFLAGS is set; otherwise, to
+ RE_SYNTAX_POSIX_BASIC;
+ `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+ `fastmap' and `fastmap_accurate' to zero;
+ `re_nsub' to the number of subexpressions in PATTERN.
+
+ PATTERN is the address of the pattern string.
+
+ CFLAGS is a series of bits which affect compilation.
+
+ If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+ use POSIX basic syntax.
+
+ If REG_NEWLINE is set, then . and [^...] don't match newline.
+ Also, regexec will try a match beginning after every newline.
+
+ If REG_ICASE is set, then we considers upper- and lowercase
+ versions of letters to be equivalent when matching.
+
+ If REG_NOSUB is set, then when PREG is passed to regexec, that
+ routine will report only success or failure, and nothing about the
+ registers.
+
+ It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for
+ the return codes and their meanings.) */
+
+int
+regcomp (preg, pattern, cflags)
+ regex_t *preg;
+ const char *pattern;
+ int cflags;
+{
+ reg_errcode_t ret;
+ unsigned syntax
+ = (cflags & REG_EXTENDED) ?
+ RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
+
+ /* regex_compile will allocate the space for the compiled pattern. */
+ preg->buffer = 0;
+ preg->allocated = 0;
+ preg->used = 0;
+
+ /* Don't bother to use a fastmap when searching. This simplifies the
+ REG_NEWLINE case: if we used a fastmap, we'd have to put all the
+ characters after newlines into the fastmap. This way, we just try
+ every character. */
+ preg->fastmap = 0;
+
+ if (cflags & REG_ICASE)
+ {
+ unsigned i;
+
+ preg->translate = (char *) malloc (CHAR_SET_SIZE);
+ if (preg->translate == NULL)
+ return (int) REG_ESPACE;
+
+ /* Map uppercase characters to corresponding lowercase ones. */
+ for (i = 0; i < CHAR_SET_SIZE; i++)
+ preg->translate[i] = ISUPPER (i) ? tolower (i) : i;
+ }
+ else
+ preg->translate = NULL;
+
+ /* If REG_NEWLINE is set, newlines are treated differently. */
+ if (cflags & REG_NEWLINE)
+ { /* REG_NEWLINE implies neither . nor [^...] match newline. */
+ syntax &= ~RE_DOT_NEWLINE;
+ syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+ /* It also changes the matching behavior. */
+ preg->newline_anchor = 1;
+ }
+ else
+ preg->newline_anchor = 0;
+
+ preg->no_sub = !!(cflags & REG_NOSUB);
+
+ /* POSIX says a null character in the pattern terminates it, so we
+ can use strlen here in compiling the pattern. */
+ ret = regex_compile (pattern, strlen (pattern), syntax, preg);
+
+ /* POSIX doesn't distinguish between an unmatched open-group and an
+ unmatched close-group: both are REG_EPAREN. */
+ if (ret == REG_ERPAREN) ret = REG_EPAREN;
+
+ return (int) ret;
+}
+
+
+/* regexec searches for a given pattern, specified by PREG, in the
+ string STRING.
+
+ If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+ `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
+ least NMATCH elements, and we set them to the offsets of the
+ corresponding matched substrings.
+
+ EFLAGS specifies `execution flags' which affect matching: if
+ REG_NOTBOL is set, then ^ does not match at the beginning of the
+ string; if REG_NOTEOL is set, then $ does not match at the end.
+
+ We return 0 if we find a match and REG_NOMATCH if not. */
+
+int
+regexec (preg, string, nmatch, pmatch, eflags)
+ const regex_t *preg;
+ const char *string;
+ size_t nmatch;
+ regmatch_t pmatch[];
+ int eflags;
+{
+ int ret;
+ struct re_registers regs;
+ regex_t private_preg;
+ int len = strlen (string);
+ boolean want_reg_info = !preg->no_sub && nmatch > 0;
+
+ private_preg = *preg;
+
+ private_preg.not_bol = !!(eflags & REG_NOTBOL);
+ private_preg.not_eol = !!(eflags & REG_NOTEOL);
+
+ /* The user has told us exactly how many registers to return
+ information about, via `nmatch'. We have to pass that on to the
+ matching routines. */
+ private_preg.regs_allocated = REGS_FIXED;
+
+ if (want_reg_info)
+ {
+ regs.num_regs = nmatch;
+ regs.start = TALLOC (nmatch, regoff_t);
+ regs.end = TALLOC (nmatch, regoff_t);
+ if (regs.start == NULL || regs.end == NULL)
+ return (int) REG_NOMATCH;
+ }
+
+ /* Perform the searching operation. */
+ ret = re_search (&private_preg, string, len,
+ /* start: */ 0, /* range: */ len,
+ want_reg_info ? &regs : (struct re_registers *) 0);
+
+ /* Copy the register information to the POSIX structure. */
+ if (want_reg_info)
+ {
+ if (ret >= 0)
+ {
+ unsigned r;
+
+ for (r = 0; r < nmatch; r++)
+ {
+ pmatch[r].rm_so = regs.start[r];
+ pmatch[r].rm_eo = regs.end[r];
+ }
+ }
+
+ /* If we needed the temporary register info, free the space now. */
+ free (regs.start);
+ free (regs.end);
+ }
+
+ /* We want zero return to mean success, unlike `re_search'. */
+ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
+}
+
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+ from either regcomp or regexec. We don't use PREG here. */
+
+size_t
+regerror (errcode, preg, errbuf, errbuf_size)
+ int errcode;
+ const regex_t *preg;
+ char *errbuf;
+ size_t errbuf_size;
+{
+ const char *msg;
+ size_t msg_size;
+
+ if (errcode < 0
+ || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0])))
+ /* Only error codes returned by the rest of the code should be passed
+ to this routine. If we are given anything else, or if other regex
+ code generates an invalid error code, then the program has a bug.
+ Dump core so we can fix it. */
+ abort ();
+
+ msg = re_error_msg[errcode];
+
+ /* POSIX doesn't require that we do anything in this case, but why
+ not be nice. */
+ if (! msg)
+ msg = "Success";
+
+ msg_size = strlen (msg) + 1; /* Includes the null. */
+
+ if (errbuf_size != 0)
+ {
+ if (msg_size > errbuf_size)
+ {
+ strncpy (errbuf, msg, errbuf_size - 1);
+ errbuf[errbuf_size - 1] = 0;
+ }
+ else
+ strcpy (errbuf, msg);
+ }
+
+ return msg_size;
+}
+
+
+/* Free dynamically allocated space used by PREG. */
+
+void
+regfree (preg)
+ regex_t *preg;
+{
+ if (preg->buffer != NULL)
+ free (preg->buffer);
+ preg->buffer = NULL;
+
+ preg->allocated = 0;
+ preg->used = 0;
+
+ if (preg->fastmap != NULL)
+ free (preg->fastmap);
+ preg->fastmap = NULL;
+ preg->fastmap_accurate = 0;
+
+ if (preg->translate != NULL)
+ free (preg->translate);
+ preg->translate = NULL;
+}
+
+#endif /* not emacs */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/lib/regex.h b/lib/regex.h
new file mode 100644
index 00000000..55927f62
--- /dev/null
+++ b/lib/regex.h
@@ -0,0 +1,487 @@
+/* Definitions for data structures and routines for the regular
+ expression library, version 0.12.
+
+ Copyright (C) 1985, 89, 90, 91, 92, 1993 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef __REGEXP_LIBRARY_H__
+#define __REGEXP_LIBRARY_H__
+
+/* POSIX says that <sys/types.h> must be included (by the caller) before
+ <regex.h>. */
+
+#ifdef VMS
+/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
+ should be there. */
+#include <stddef.h>
+#endif
+
+
+/* The following bits are used to determine the regexp syntax we
+ recognize. The set/not-set meanings are chosen so that Emacs syntax
+ remains the value 0. The bits are given in alphabetical order, and
+ the definitions shifted by one from the previous bit; thus, when we
+ add or remove a bit, only one other definition need change. */
+typedef unsigned reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+ If set, then such a \ quotes the following character. */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+ literals.
+ If set, then \+ and \? are operators and + and ? are literals. */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported. They are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+ expressions, of course).
+ If this bit is not set, then it depends:
+ ^ is an anchor if it is at the beginning of a regular
+ expression or after an open-group or an alternation operator;
+ $ is an anchor if it is at the end of a regular expression, or
+ before a close-group or an alternation operator.
+
+ This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+ POSIX draft 11.2 says that * etc. in leading positions is undefined.
+ We already implemented a previous draft which made those constructs
+ invalid, though, so we haven't changed the code back. */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+ regardless of where they are in the pattern.
+ If this bit is not set, then special characters are special only in
+ some contexts; otherwise they are ordinary. Specifically,
+ * + ? and intervals are only special when not after the beginning,
+ open-group, or alternation operator. */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+ If not set, then it doesn't. */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+ If not set, then it does. */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+ If not set, they do. */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+ interval, depending on RE_NO_BK_BRACES.
+ If not set, \{, \}, {, and } are literals. */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+ If not set, they are. */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+ If not set, newline is literal. */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+ are literals.
+ If not set, then `\{...\}' defines an interval. */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+ If not set, \(...\) defines a group, and ( and ) are literals. */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+ If not set, then \<digit> is a back-reference. */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+ If not set, then \| is an alternation operator, and | is literal. */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+ than the starting range point, as in [z-a], is invalid.
+ If not set, then when ending range point collates higher than the
+ starting range point, the range is ignored. */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+ If not set, then an unmatched ) is invalid. */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+ some interfaces). When a regexp is compiled, the syntax used is
+ stored in the pattern buffer, so changing this does not affect
+ already-compiled regexps. */
+extern reg_syntax_t re_syntax_options;
+
+/* Define combinations of the above bits for the standard possibilities.
+ (The [[[ comments delimit what gets put into the Texinfo file, so
+ don't delete them!) */
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK \
+ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+#define RE_SYNTAX_POSIX_AWK \
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
+
+#define RE_SYNTAX_GREP \
+ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
+ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
+ | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP \
+ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
+ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
+ | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP \
+ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax. */
+#define _RE_SYNTAX_POSIX_COMMON \
+ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
+ | RE_INTERVALS | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+ RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
+ isn't minimal, since other operators, such as \`, aren't disabled. */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+ replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+/* Maximum number of duplicates an interval can allow. Some systems
+ (erroneously) define this in other header files, but we want our
+ value, so remove any previous define. */
+#ifdef RE_DUP_MAX
+#undef RE_DUP_MAX
+#endif
+#define RE_DUP_MAX ((1 << 15) - 1)
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp'). */
+
+/* If this bit is set, then use extended regular expression syntax.
+ If not set, then use basic regular expression syntax. */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+ characters in the string.
+ If not set, then anchors do match at newlines. */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+ If not set, then returns differ between not matching and errors. */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec). */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+ the beginning of the string (presumably because it's not the
+ beginning of a line).
+ If not set, then the beginning-of-line operator does match the
+ beginning of the string. */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line. */
+#define REG_NOTEOL (1 << 1)
+
+
+/* If any error codes are removed, changed, or added, update the
+ `re_error_msg' table in regex.c. */
+typedef enum
+{
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT, /* Invalid pattern. */
+ REG_ECOLLATE, /* Not implemented. */
+ REG_ECTYPE, /* Invalid character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* Unmatched left bracket. */
+ REG_EPAREN, /* Parenthesis imbalance. */
+ REG_EBRACE, /* Unmatched \{. */
+ REG_BADBR, /* Invalid contents of \{\}. */
+ REG_ERANGE, /* Invalid range end. */
+ REG_ESPACE, /* Ran out of memory. */
+ REG_BADRPT, /* No preceding re for repetition op. */
+
+ /* Error codes we've added. */
+ REG_EEND, /* Premature end. */
+ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
+ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
+} reg_errcode_t;
+
+/* This data structure represents a compiled pattern. Before calling
+ the pattern compiler, the fields `buffer', `allocated', `fastmap',
+ `translate', and `no_sub' can be set. After the pattern has been
+ compiled, the `re_nsub' field is available. All other fields are
+ private to the regex routines. */
+
+struct re_pattern_buffer
+{
+/* [[[begin pattern_buffer]]] */
+ /* Space that holds the compiled pattern. It is declared as
+ `unsigned char *' because its elements are
+ sometimes used as array indexes. */
+ unsigned char *buffer;
+
+ /* Number of bytes to which `buffer' points. */
+ unsigned long allocated;
+
+ /* Number of bytes actually used in `buffer'. */
+ unsigned long used;
+
+ /* Syntax setting with which the pattern was compiled. */
+ reg_syntax_t syntax;
+
+ /* Pointer to a fastmap, if any, otherwise zero. re_search uses
+ the fastmap, if there is one, to skip over impossible
+ starting points for matches. */
+ char *fastmap;
+
+ /* Either a translate table to apply to all characters before
+ comparing them, or zero for no translation. The translation
+ is applied to a pattern when it is compiled and to a string
+ when it is matched. */
+ char *translate;
+
+ /* Number of subexpressions found by the compiler. */
+ size_t re_nsub;
+
+ /* Zero if this pattern cannot match the empty string, one else.
+ Well, in truth it's used only in `re_search_2', to see
+ whether or not we should use the fastmap, so we don't set
+ this absolutely perfectly; see `re_compile_fastmap' (the
+ `duplicate' case). */
+ unsigned can_be_null : 1;
+
+ /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+ for `max (RE_NREGS, re_nsub + 1)' groups.
+ If REGS_REALLOCATE, reallocate space if necessary.
+ If REGS_FIXED, use what's there. */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+ unsigned regs_allocated : 2;
+
+ /* Set to zero when `regex_compile' compiles a pattern; set to one
+ by `re_compile_fastmap' if it updates the fastmap. */
+ unsigned fastmap_accurate : 1;
+
+ /* If set, `re_match_2' does not return information about
+ subexpressions. */
+ unsigned no_sub : 1;
+
+ /* If set, a beginning-of-line anchor doesn't match at the
+ beginning of the string. */
+ unsigned not_bol : 1;
+
+ /* Similarly for an end-of-line anchor. */
+ unsigned not_eol : 1;
+
+ /* If true, an anchor at a newline matches. */
+ unsigned newline_anchor : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+/* Type for byte offsets within the string. POSIX mandates this. */
+typedef int regoff_t;
+
+
+/* This is the structure we store register match data in. See
+ regex.texinfo for a full description of what registers match. */
+struct re_registers
+{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+ `re_match_2' returns information about at least this many registers
+ the first time a `regs' structure is passed. */
+#ifndef RE_NREGS
+#define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers. Aside from the different names than
+ `re_registers', POSIX uses an array of structures, instead of a
+ structure of arrays. */
+typedef struct
+{
+ regoff_t rm_so; /* Byte offset from string's start to substring's start. */
+ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
+} regmatch_t;
+
+/* Declarations for routines. */
+
+/* To avoid duplicating every routine declaration -- once with a
+ prototype (if we are ANSI), and once without (if we aren't) -- we
+ use the following macro to declare argument types. This
+ unfortunately clutters up the declarations a bit, but I think it's
+ worth it. */
+
+#if __STDC__
+
+#define _RE_ARGS(args) args
+
+#else /* not __STDC__ */
+
+#define _RE_ARGS(args) ()
+
+#endif /* not __STDC__ */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+ You can also simply assign to the `re_syntax_options' variable. */
+extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
+
+/* Compile the regular expression PATTERN, with length LENGTH
+ and syntax given by the global `re_syntax_options', into the buffer
+ BUFFER. Return NULL if successful, and an error string if not. */
+extern const char *re_compile_pattern
+ _RE_ARGS ((const char *pattern, int length,
+ struct re_pattern_buffer *buffer));
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+ accelerate searches. Return 0 if successful and -2 if was an
+ internal error. */
+extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+ compiled into BUFFER. Start searching at position START, for RANGE
+ characters. Return the starting position of the match, -1 for no
+ match, or -2 for an internal error. Also return register
+ information in REGS (if REGS and BUFFER->no_sub are nonzero). */
+extern int re_search
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, int range, struct re_registers *regs));
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+ STRING2. Also, stop searching at index START + STOP. */
+extern int re_search_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, int range, struct re_registers *regs, int stop));
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+ in BUFFER matched, starting at position START. */
+extern int re_match
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, struct re_registers *regs));
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
+extern int re_match_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, struct re_registers *regs, int stop));
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using BUFFER and REGS will use this memory
+ for recording register information. STARTS and ENDS must be
+ allocated with malloc, and must each be at least `NUM_REGS * sizeof
+ (regoff_t)' bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+extern void re_set_registers
+ _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
+ unsigned num_regs, regoff_t *starts, regoff_t *ends));
+
+#ifdef _REGEX_RE_COMP
+/* 4.2 bsd compatibility. */
+extern char *re_comp _RE_ARGS ((const char *));
+extern int re_exec _RE_ARGS ((const char *));
+#endif
+
+/* POSIX compatibility. */
+extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
+extern int regexec
+ _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
+ regmatch_t pmatch[], int eflags));
+extern size_t regerror
+ _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
+ size_t errbuf_size));
+extern void regfree _RE_ARGS ((regex_t *preg));
+
+#endif /* not __REGEXP_LIBRARY_H__ */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/lib/strtol.c b/lib/strtol.c
new file mode 100644
index 00000000..08ef0a47
--- /dev/null
+++ b/lib/strtol.c
@@ -0,0 +1,186 @@
+/* Copyright (C) 1991, 1992 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
+
+#ifndef ULONG_MAX
+#define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
+#endif
+
+#ifndef LONG_MAX
+#define LONG_MAX (~(1 << (sizeof (long) * 8 - 1)))
+#endif
+
+#ifndef LONG_MIN
+#define LONG_MIN (-LONG_MAX - 1)
+#endif
+
+#if STDC_HEADERS
+#include <stddef.h>
+#include <stdlib.h>
+#else
+#define NULL 0
+extern int errno;
+#endif
+
+#ifndef UNSIGNED
+#define UNSIGNED 0
+#endif
+
+/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
+ If BASE is 0 the base is determined by the presence of a leading
+ zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
+ If BASE is < 2 or > 36, it is reset to 10.
+ If ENDPTR is not NULL, a pointer to the character after the last
+ one converted is stored in *ENDPTR. */
+#if UNSIGNED
+unsigned long int
+#define strtol strtoul
+#else
+long int
+#endif
+strtol (nptr, endptr, base)
+ const char *nptr;
+ char **endptr;
+ int base;
+{
+ int negative;
+ register unsigned long int cutoff;
+ register unsigned int cutlim;
+ register unsigned long int i;
+ register const char *s;
+ register unsigned char c;
+ const char *save;
+ int overflow;
+
+ if (base < 0 || base == 1 || base > 36)
+ base = 10;
+
+ s = nptr;
+
+ /* Skip white space. */
+ while (isspace (*s))
+ ++s;
+ if (*s == '\0')
+ goto noconv;
+
+ /* Check for a sign. */
+ if (*s == '-')
+ {
+ negative = 1;
+ ++s;
+ }
+ else if (*s == '+')
+ {
+ negative = 0;
+ ++s;
+ }
+ else
+ negative = 0;
+
+ if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
+ s += 2;
+
+ /* If BASE is zero, figure it out ourselves. */
+ if (base == 0)
+ {
+ if (*s == '0')
+ {
+ if (toupper (s[1]) == 'X')
+ {
+ s += 2;
+ base = 16;
+ }
+ else
+ base = 8;
+ }
+ else
+ base = 10;
+ }
+
+ /* Save the pointer so we can check later if anything happened. */
+ save = s;
+
+ cutoff = ULONG_MAX / (unsigned long int) base;
+ cutlim = ULONG_MAX % (unsigned long int) base;
+
+ overflow = 0;
+ i = 0;
+ for (c = *s; c != '\0'; c = *++s)
+ {
+ if (isdigit (c))
+ c -= '0';
+ else if (isalpha (c))
+ c = toupper (c) - 'A' + 10;
+ else
+ break;
+ if (c >= base)
+ break;
+ /* Check for overflow. */
+ if (i > cutoff || (i == cutoff && c > cutlim))
+ overflow = 1;
+ else
+ {
+ i *= (unsigned long int) base;
+ i += c;
+ }
+ }
+
+ /* Check if anything actually happened. */
+ if (s == save)
+ goto noconv;
+
+ /* Store in ENDPTR the address of one character
+ past the last character we converted. */
+ if (endptr != NULL)
+ *endptr = (char *) s;
+
+#if !UNSIGNED
+ /* Check for a value that is within the range of
+ `unsigned long int', but outside the range of `long int'. */
+ if (i > (negative ?
+ -(unsigned long int) LONG_MIN : (unsigned long int) LONG_MAX))
+ overflow = 1;
+#endif
+
+ if (overflow)
+ {
+ errno = ERANGE;
+#if UNSIGNED
+ return ULONG_MAX;
+#else
+ return negative ? LONG_MIN : LONG_MAX;
+#endif
+ }
+
+ /* Return the result of the appropriate sign. */
+ return (negative ? -i : i);
+
+noconv:;
+ /* There was no number to convert. */
+ if (endptr != NULL)
+ *endptr = (char *) nptr;
+ return 0L;
+}
diff --git a/lib/xmalloc.c b/lib/xmalloc.c
new file mode 100644
index 00000000..9f701111
--- /dev/null
+++ b/lib/xmalloc.c
@@ -0,0 +1,95 @@
+/* xmalloc.c -- malloc with out of memory checking
+ Copyright (C) 1990, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if __STDC__
+#define VOID void
+#else
+#define VOID char
+#endif
+
+#include <sys/types.h>
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#else
+VOID *malloc ();
+VOID *realloc ();
+void free ();
+#endif
+
+#ifndef EXIT_FAILURE
+#define EXIT_FAILURE 1
+#endif
+
+/* Exit value when the requested amount of memory is not available.
+ The caller may set it to some other value. */
+int xmalloc_exit_failure = EXIT_FAILURE;
+
+#if __STDC__ && (HAVE_VPRINTF || HAVE_DOPRNT)
+void error (int, int, const char *, ...);
+#else
+void error ();
+#endif
+
+static VOID *
+fixup_null_alloc (n)
+ size_t n;
+{
+ VOID *p;
+
+ p = 0;
+ if (n == 0)
+ p = malloc ((size_t) 1);
+ if (p == 0)
+ error (xmalloc_exit_failure, 0, "memory exhausted");
+ return p;
+}
+
+/* Allocate N bytes of memory dynamically, with error checking. */
+
+VOID *
+xmalloc (n)
+ size_t n;
+{
+ VOID *p;
+
+ p = malloc (n);
+ if (p == 0)
+ p = fixup_null_alloc (n);
+ return p;
+}
+
+/* Change the size of an allocated block of memory P to N bytes,
+ with error checking.
+ If P is NULL, run xmalloc. */
+
+VOID *
+xrealloc (p, n)
+ VOID *p;
+ size_t n;
+{
+ if (p == 0)
+ return xmalloc (n);
+ p = realloc (p, n);
+ if (p == 0)
+ p = fixup_null_alloc (n);
+ return p;
+}
diff --git a/lib/xstrdup.c b/lib/xstrdup.c
new file mode 100644
index 00000000..27cd0c67
--- /dev/null
+++ b/lib/xstrdup.c
@@ -0,0 +1,36 @@
+/* xstrdup.c -- copy a string with out of memory checking
+ Copyright (C) 1990 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if defined(STDC_HEADERS) || defined(HAVE_STRING_H)
+#include <string.h>
+#else
+#include <strings.h>
+#endif
+char *xmalloc ();
+
+/* Return a newly allocated copy of STRING. */
+
+char *
+xstrdup (string)
+ char *string;
+{
+ return strcpy (xmalloc (strlen (string) + 1), string);
+}
diff --git a/libltdl/COPYING.LIB b/libltdl/COPYING.LIB
new file mode 100644
index 00000000..eb685a5e
--- /dev/null
+++ b/libltdl/COPYING.LIB
@@ -0,0 +1,481 @@
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL. It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+ This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it. You can use it for
+your libraries, 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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+ For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you. You must make sure that they, too, receive or can get the source
+code. If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it. And you must show them these terms so they know their rights.
+
+ Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+ Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library. If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software. To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+ Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs. This
+license, the GNU Library General Public License, applies to certain
+designated libraries. This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+ The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it. Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program. However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+ Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries. We
+concluded that weaker conditions might promote sharing better.
+
+ However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves. This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them. (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.) The hope is that this
+will lead to faster development of free libraries.
+
+ The precise terms and conditions for copying, distribution and
+modification follow. Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library". The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+ Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+ GNU LIBRARY GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License"). Each licensee is
+addressed as "you".
+
+ A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+ The "Library", below, refers to any such software library or work
+which has been distributed under these terms. A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language. (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+ "Source code" for a work means the preferred form of the work for
+making modifications to it. For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+ Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it). Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+ 1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+ You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+ 2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) The modified work must itself be a software library.
+
+ b) You must cause the files modified to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ c) You must cause the whole of the work to be licensed at no
+ charge to all third parties under the terms of this License.
+
+ d) If a facility in the modified Library refers to a function or a
+ table of data to be supplied by an application program that uses
+ the facility, other than as an argument passed when the facility
+ is invoked, then you must make a good faith effort to ensure that,
+ in the event an application does not supply such function or
+ table, the facility still operates, and performs whatever part of
+ its purpose remains meaningful.
+
+ (For example, a function in a library to compute square roots has
+ a purpose that is entirely well-defined independent of the
+ application. Therefore, Subsection 2d requires that any
+ application-supplied function or table used by this function must
+ be optional: if the application does not supply it, the square
+ root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library. To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License. (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.) Do not make any other change in
+these notices.
+
+ Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+ This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+ 4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+ If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library". Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+ However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library". The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+ When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library. The
+threshold for this to be true is not precisely defined by law.
+
+ If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work. (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+ Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+ 6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+ You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License. You must supply a copy of this License. If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License. Also, you must do one
+of these things:
+
+ a) Accompany the work with the complete corresponding
+ machine-readable source code for the Library including whatever
+ changes were used in the work (which must be distributed under
+ Sections 1 and 2 above); and, if the work is an executable linked
+ with the Library, with the complete machine-readable "work that
+ uses the Library", as object code and/or source code, so that the
+ user can modify the Library and then relink to produce a modified
+ executable containing the modified Library. (It is understood
+ that the user who changes the contents of definitions files in the
+ Library will not necessarily be able to recompile the application
+ to use the modified definitions.)
+
+ b) Accompany the work with a written offer, valid for at
+ least three years, to give the same user the materials
+ specified in Subsection 6a, above, for a charge no more
+ than the cost of performing this distribution.
+
+ c) If distribution of the work is made by offering access to copy
+ from a designated place, offer equivalent access to copy the above
+ specified materials from the same place.
+
+ d) Verify that the user has already received a copy of these
+ materials or that you have already sent this user a copy.
+
+ For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it. However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+ It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system. Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+ 7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+ a) Accompany the combined library with a copy of the same work
+ based on the Library, uncombined with any other library
+ facilities. This must be distributed under the terms of the
+ Sections above.
+
+ b) Give prominent notice with the combined library of the fact
+ that part of it is a work based on the Library, and explaining
+ where to find the accompanying uncombined form of the same work.
+
+ 8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License. Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+ 9. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Library or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+ 10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all. For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded. In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+ 13. The Free Software Foundation may publish revised and/or new
+versions of the Library 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 Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation. If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+ 14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission. For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this. Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+ NO WARRANTY
+
+ 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "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
+LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY 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
+LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey 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 library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this library; if not, write to the Free
+ Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/libltdl/Makefile.am b/libltdl/Makefile.am
new file mode 100644
index 00000000..12bdcbbf
--- /dev/null
+++ b/libltdl/Makefile.am
@@ -0,0 +1,44 @@
+## Process this file with automake to produce Makefile.in
+
+AUTOMAKE_OPTIONS = no-dependencies foreign
+
+if INSTALL_LTDL
+include_HEADERS = ltdl.h
+lib_LTLIBRARIES = libltdl.la
+else
+noinst_HEADERS = ltdl.h
+endif
+
+if CONVENIENCE_LTDL
+noinst_LTLIBRARIES = libltdlc.la
+endif
+
+libltdl_la_SOURCES = ltdl.c
+libltdl_la_LDFLAGS = -version-info 1:1:1
+libltdl_la_LIBADD = $(LIBADD_DL)
+
+libltdlc_la_SOURCES = ltdl.c
+libltdlc_la_LIBADD = $(LIBADD_DL)
+
+## Because we do not have automatic dependency tracking:
+ltdl.lo: ltdl.h config.h
+
+$(OBJECTS): libtool
+libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+
+## This allows us to install libltdl without using ln and without creating
+## a world writeable directory.
+## FIXME: Removed this rule once automake can do this properly by itself.
+local-install-files: $(DISTFILES)
+ -rm -rf $(DESTDIR)$(datadir)/libtool/libltdl
+ $(mkinstalldirs) $(DESTDIR)$(datadir)/libtool/libltdl
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(DESTDIR)$(datadir)/libtool/libltdl/$$file; \
+ else \
+ test -f $(DESTDIR)$(datadir)/libtool/libltdl/$$file \
+ || cp -p $$d/$$file $(DESTDIR)$(datadir)/libtool/libltdl/$$file || :; \
+ fi; \
+ done
diff --git a/libltdl/Makefile.in b/libltdl/Makefile.in
new file mode 100644
index 00000000..6d4c93b2
--- /dev/null
+++ b/libltdl/Makefile.in
@@ -0,0 +1,454 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+CC = @CC@
+DLLTOOL = @DLLTOOL@
+LD = @LD@
+LIBADD_DL = @LIBADD_DL@
+LIBTOOL = @LIBTOOL@
+LIBTOOL_DEPS = @LIBTOOL_DEPS@
+LN_S = @LN_S@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+NM = @NM@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+
+AUTOMAKE_OPTIONS = no-dependencies foreign
+
+@INSTALL_LTDL_TRUE@include_HEADERS = ltdl.h
+@INSTALL_LTDL_TRUE@lib_LTLIBRARIES = libltdl.la
+@INSTALL_LTDL_FALSE@noinst_HEADERS = ltdl.h
+
+@CONVENIENCE_LTDL_TRUE@noinst_LTLIBRARIES = libltdlc.la
+
+libltdl_la_SOURCES = ltdl.c
+libltdl_la_LDFLAGS = -version-info 1:1:1
+libltdl_la_LIBADD = $(LIBADD_DL)
+
+libltdlc_la_SOURCES = ltdl.c
+libltdlc_la_LIBADD = $(LIBADD_DL)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_HEADER = config.h
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I.
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libltdl_la_DEPENDENCIES =
+libltdl_la_OBJECTS = ltdl.lo
+libltdlc_la_LDFLAGS =
+libltdlc_la_DEPENDENCIES =
+libltdlc_la_OBJECTS = ltdl.lo
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+HEADERS = $(include_HEADERS) $(noinst_HEADERS)
+
+DIST_COMMON = README ./stamp-h.in COPYING.LIB Makefile.am Makefile.in \
+acconfig.h acinclude.m4 aclocal.m4 config.h.in configure configure.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(libltdl_la_SOURCES) $(libltdlc_la_SOURCES)
+OBJECTS = $(libltdl_la_OBJECTS) $(libltdlc_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ configure.in acinclude.m4
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: @MAINTAINER_MODE_TRUE@$(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+config.h: stamp-h
+ @if test ! -f $@; then \
+ rm -f stamp-h; \
+ $(MAKE) stamp-h; \
+ else :; fi
+stamp-h: $(srcdir)/config.h.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES= CONFIG_HEADERS=config.h \
+ $(SHELL) ./config.status
+ @echo timestamp > stamp-h 2> /dev/null
+$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@$(srcdir)/stamp-h.in
+ @if test ! -f $@; then \
+ rm -f $(srcdir)/stamp-h.in; \
+ $(MAKE) $(srcdir)/stamp-h.in; \
+ else :; fi
+$(srcdir)/stamp-h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4) acconfig.h
+ cd $(top_srcdir) && $(AUTOHEADER)
+ @echo timestamp > $(srcdir)/stamp-h.in 2> /dev/null
+
+mostlyclean-hdr:
+
+clean-hdr:
+
+distclean-hdr:
+ -rm -f config.h
+
+maintainer-clean-hdr:
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+mostlyclean-noinstLTLIBRARIES:
+
+clean-noinstLTLIBRARIES:
+ -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
+
+distclean-noinstLTLIBRARIES:
+
+maintainer-clean-noinstLTLIBRARIES:
+
+.c.o:
+ $(COMPILE) -c $<
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libltdl.la: $(libltdl_la_OBJECTS) $(libltdl_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libltdl_la_LDFLAGS) $(libltdl_la_OBJECTS) $(libltdl_la_LIBADD) $(LIBS)
+
+libltdlc.la: $(libltdlc_la_OBJECTS) $(libltdlc_la_DEPENDENCIES)
+ $(LINK) $(libltdlc_la_LDFLAGS) $(libltdlc_la_OBJECTS) $(libltdlc_la_LIBADD) $(LIBS)
+
+install-includeHEADERS: $(include_HEADERS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(includedir)
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ done
+
+uninstall-includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ list='$(include_HEADERS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(includedir)/$$p; \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)config.h.in$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags config.h.in $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+all-recursive-am: config.h
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-am
+
+install-data-am: install-includeHEADERS
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES) $(HEADERS) config.h
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-hdr mostlyclean-libLTLIBRARIES \
+ mostlyclean-noinstLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-hdr clean-libLTLIBRARIES clean-noinstLTLIBRARIES \
+ clean-compile clean-libtool clean-tags clean-generic \
+ mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-hdr distclean-libLTLIBRARIES \
+ distclean-noinstLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-hdr \
+ maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-noinstLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+ -rm -f config.status
+
+.PHONY: mostlyclean-hdr distclean-hdr clean-hdr maintainer-clean-hdr \
+mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES \
+mostlyclean-noinstLTLIBRARIES distclean-noinstLTLIBRARIES \
+clean-noinstLTLIBRARIES maintainer-clean-noinstLTLIBRARIES \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool uninstall-includeHEADERS \
+install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
+maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \
+installcheck-am installcheck all-recursive-am install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+ltdl.lo: ltdl.h config.h
+
+$(OBJECTS): libtool
+libtool: $(LIBTOOL_DEPS)
+ $(SHELL) ./config.status --recheck
+
+local-install-files: $(DISTFILES)
+ -rm -rf $(DESTDIR)$(datadir)/libtool/libltdl
+ $(mkinstalldirs) $(DESTDIR)$(datadir)/libtool/libltdl
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(DESTDIR)$(datadir)/libtool/libltdl/$$file; \
+ else \
+ test -f $(DESTDIR)$(datadir)/libtool/libltdl/$$file \
+ || cp -p $$d/$$file $(DESTDIR)$(datadir)/libtool/libltdl/$$file || :; \
+ fi; \
+ done
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libltdl/README b/libltdl/README
new file mode 100644
index 00000000..0b08ae28
--- /dev/null
+++ b/libltdl/README
@@ -0,0 +1 @@
+This is GNU libltdl, a system independent dlopen wrapper for GNU libtool.
diff --git a/libltdl/acconfig.h b/libltdl/acconfig.h
new file mode 100644
index 00000000..15f115c7
--- /dev/null
+++ b/libltdl/acconfig.h
@@ -0,0 +1,12 @@
+/* Some of these are defined here, not in configure.in, because
+ they're AC_DEFINEd in two different places, which causes two
+ defines to appear. Some C compilers might now appreciate it... */
+
+/* Define if you have the libdl library or equivalent. */
+#undef HAVE_LIBDL
+
+/* Define if you have the GNU dld library. */
+#undef HAVE_DLD
+
+/* Define if you have the shl_load function. */
+#undef HAVE_SHL_LOAD
diff --git a/libltdl/acinclude.m4 b/libltdl/acinclude.m4
new file mode 100644
index 00000000..2ad32064
--- /dev/null
+++ b/libltdl/acinclude.m4
@@ -0,0 +1,427 @@
+## libtool.m4 - Configure libtool for the target system. -*-Shell-script-*-
+## Copyright (C) 1996-1999 Free Software Foundation, Inc.
+## Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+##
+## 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 2 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, write to the Free Software
+## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+##
+## As a special exception to the GNU General Public License, if you
+## distribute this file as part of a program that contains a
+## configuration script generated by Autoconf, you may include it under
+## the same distribution terms that you use for the rest of that program.
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+ [ --disable-libtool-lock avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$host" in
+*-*-beos* | *-*-cygwin*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, main, LIBM="-lm")
+ ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case "$enable_ltdl_convenience" in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, main,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ INCLTDL=
+ fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
diff --git a/libltdl/aclocal.m4 b/libltdl/aclocal.m4
new file mode 100644
index 00000000..7ade1e6e
--- /dev/null
+++ b/libltdl/aclocal.m4
@@ -0,0 +1,566 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, 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.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+ [ --disable-libtool-lock avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_SUBST(LD)
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+AC_SUBST(NM)
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$host" in
+*-*-beos* | *-*-cygwin*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, main, LIBM="-lm")
+ ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library, adds --enable-ltdl-convenience to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case "$enable_ltdl_convenience" in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdlc.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library, and adds --enable-ltdl-install to
+# the configure arguments. Note that LIBLTDL is not AC_SUBSTed, nor
+# is AC_CONFIG_SUBDIRS called. If DIR is not provided, it is assumed
+# to be `${top_builddir}/libltdl'. Make sure you start DIR with
+# '${top_builddir}/' (note the single quotes!) if your package is not
+# flat, and, if you're not using automake, define top_builddir as
+# appropriate in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, main,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL=ifelse($#,1,$1,['${top_builddir}/libltdl'])/libltdl.la
+ INCLTDL=ifelse($#,1,-I$1,['-I${top_builddir}/libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ INCLTDL=
+ fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
+# Like AC_CONFIG_HEADER, but automatically create stamp file.
+
+AC_DEFUN(AM_CONFIG_HEADER,
+[AC_PREREQ([2.12])
+AC_CONFIG_HEADER([$1])
+dnl When config.status generates a header, we must update the stamp-h file.
+dnl This file resides in the same directory as the config header
+dnl that is generated. We must strip everything past the first ":",
+dnl and everything past the last "/".
+AC_OUTPUT_COMMANDS(changequote(<<,>>)dnl
+ifelse(patsubst(<<$1>>, <<[^ ]>>, <<>>), <<>>,
+<<test -z "<<$>>CONFIG_HEADERS" || echo timestamp > patsubst(<<$1>>, <<^\([^:]*/\)?.*>>, <<\1>>)stamp-h<<>>dnl>>,
+<<am_indx=1
+for am_file in <<$1>>; do
+ case " <<$>>CONFIG_HEADERS " in
+ *" <<$>>am_file "*<<)>>
+ echo timestamp > `echo <<$>>am_file | sed -e 's%:.*%%' -e 's%[^/]*$%%'`stamp-h$am_indx
+ ;;
+ esac
+ am_indx=`expr "<<$>>am_indx" + 1`
+done<<>>dnl>>)
+changequote([,]))])
+
+# Add --enable-maintainer-mode option to configure.
+# From Jim Meyering
+
+# serial 1
+
+AC_DEFUN(AM_MAINTAINER_MODE,
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+ dnl maintainer-mode is disabled by default
+ AC_ARG_ENABLE(maintainer-mode,
+[ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ USE_MAINTAINER_MODE=$enableval,
+ USE_MAINTAINER_MODE=no)
+ AC_MSG_RESULT($USE_MAINTAINER_MODE)
+ AM_CONDITIONAL(MAINTAINER_MODE, test $USE_MAINTAINER_MODE = yes)
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST(MAINT)dnl
+]
+)
+
+# Define a conditional.
+
+AC_DEFUN(AM_CONDITIONAL,
+[AC_SUBST($1_TRUE)
+AC_SUBST($1_FALSE)
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi])
+
diff --git a/libltdl/config.h.in b/libltdl/config.h.in
new file mode 100644
index 00000000..1e7613ef
--- /dev/null
+++ b/libltdl/config.h.in
@@ -0,0 +1,80 @@
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define as __inline if that's what the C compiler calls it. */
+#undef inline
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you have the libdl library or equivalent. */
+#undef HAVE_LIBDL
+
+/* Define if you have the GNU dld library. */
+#undef HAVE_DLD
+
+/* Define if you have the shl_load function. */
+#undef HAVE_SHL_LOAD
+
+/* Define if you have the dlerror function. */
+#undef HAVE_DLERROR
+
+/* Define if you have the index function. */
+#undef HAVE_INDEX
+
+/* Define if you have the rindex function. */
+#undef HAVE_RINDEX
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the strrchr function. */
+#undef HAVE_STRRCHR
+
+/* Define if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
+/* Define if you have the <dl.h> header file. */
+#undef HAVE_DL_H
+
+/* Define if you have the <dld.h> header file. */
+#undef HAVE_DLD_H
+
+/* Define if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define if you have the <malloc.h> header file. */
+#undef HAVE_MALLOC_H
+
+/* Define if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to the extension used for shared libraries, say, .so. */
+#undef LTDL_SHLIB_EXT
+
+/* Define to the name of the environment variable that determines the dynamic library search path. */
+#undef LTDL_SHLIBPATH_VAR
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries. */
+#undef LTDL_OBJDIR
+
+/* Define if libtool can extract symbol lists from object files. */
+#undef HAVE_PRELOADED_SYMBOLS
+
+/* Define if dlsym() requires a leading underscode in symbol names. */
+#undef NEED_USCORE
+
diff --git a/libltdl/configure b/libltdl/configure
new file mode 100755
index 00000000..91329a88
--- /dev/null
+++ b/libltdl/configure
@@ -0,0 +1,3077 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer"
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --disable-libtool-lock avoid locking (might break parallel builds)"
+ac_help="$ac_help
+ --enable-ltdl-install install libltdl"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=ltdl.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+if test -z "$enable_ltdl_install$enable_ltdl_convenience"; then
+ if test -f ${srcdir}/ltconfig && test -f ${srcdir}/ltmain.sh; then
+ # if libltdl is libtoolized, it is assumed to be stand-alone and
+ # installed unless the command line overrides it (tested above)
+ enable_ltdl_install=yes
+ else
+ echo "configure: warning: *** The top-level configure must select either" 1>&2
+ echo "configure: warning: *** A""C_LIBLTDL_INSTALLABLE or A""C_LIBLTDL_CONVENIENCE." 1>&2
+ { echo "configure: error: *** Maybe you want to --enable-ltdl-install?" 1>&2; exit 1; }
+ fi
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:584: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:637: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:694: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=libltdl
+
+VERSION=1.0
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:733: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:746: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:759: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:772: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:785: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+
+
+echo $ac_n "checking whether to enable maintainer-specific portions of Makefiles""... $ac_c" 1>&6
+echo "configure:802: checking whether to enable maintainer-specific portions of Makefiles" >&5
+ # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+ enableval="$enable_maintainer_mode"
+ USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ echo "$ac_t""$USE_MAINTAINER_MODE" 1>&6
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:828: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:858: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:909: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:941: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 952 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:957: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:983: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:988: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:997: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:1016: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1048: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1053 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1102: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for inline""... $ac_c" 1>&6
+echo "configure:1123: checking for inline" >&5
+if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_inline=no
+for ac_kw in inline __inline__ __inline; do
+ cat > conftest.$ac_ext <<EOF
+#line 1130 "configure"
+#include "confdefs.h"
+
+int main() {
+} $ac_kw foo() {
+; return 0; }
+EOF
+if { (eval echo configure:1137: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_inline=$ac_kw; break
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+done
+
+fi
+
+echo "$ac_t""$ac_cv_c_inline" 1>&6
+case "$ac_cv_c_inline" in
+ inline | yes) ;;
+ no) cat >> confdefs.h <<\EOF
+#define inline
+EOF
+ ;;
+ *) cat >> confdefs.h <<EOF
+#define inline $ac_cv_c_inline
+EOF
+ ;;
+esac
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:1238: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:1259: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1279: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1318: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1342: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1345: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1381: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1397: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1434: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+# Check for any special flags to pass to ltconfig.
+libtool_flags="--cache-file=$cache_file"
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$host" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 1478 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1479: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1500: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1505 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1512: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $host \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
+# Check whether --enable-ltdl-install or --disable-ltdl-install was given.
+if test "${enable_ltdl_install+set}" = set; then
+ enableval="$enable_ltdl_install"
+ :
+fi
+
+
+
+
+if test x"${enable_ltdl_install-no}" != xno; then
+ INSTALL_LTDL_TRUE=
+ INSTALL_LTDL_FALSE='#'
+else
+ INSTALL_LTDL_TRUE='#'
+ INSTALL_LTDL_FALSE=
+fi
+
+
+if test x"${enable_ltdl_convenience-no}" != xno; then
+ CONVENIENCE_LTDL_TRUE=
+ CONVENIENCE_LTDL_FALSE='#'
+else
+ CONVENIENCE_LTDL_TRUE='#'
+ CONVENIENCE_LTDL_FALSE=
+fi
+
+rm -f conftest
+./libtool --config > conftest
+. ./conftest
+rm -f conftest
+
+echo $ac_n "checking which extension is used for shared libraries""... $ac_c" 1>&6
+echo "configure:1647: checking which extension is used for shared libraries" >&5
+if eval "test \"`echo '$''{'libltdl_cv_shlibext'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ (
+ last=
+ for spec in $library_names_spec; do
+ last="$spec"
+ done
+
+ echo "$last" | sed 's/\[.*\]//;s/^[^.]*//;s/\$.*$//;s/\.$//' > conftest
+
+)
+libltdl_cv_shlibext=`cat conftest`
+rm -f conftest
+
+fi
+
+echo "$ac_t""$libltdl_cv_shlibext" 1>&6
+if test -n "$libltdl_cv_shlibext"; then
+ cat >> confdefs.h <<EOF
+#define LTDL_SHLIB_EXT "$libltdl_cv_shlibext"
+EOF
+
+fi
+
+echo $ac_n "checking which variable specifies run-time library path""... $ac_c" 1>&6
+echo "configure:1674: checking which variable specifies run-time library path" >&5
+if eval "test \"`echo '$''{'libltdl_cv_shlibpath_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ libltdl_cv_shlibpath_var="$shlibpath_var"
+fi
+
+echo "$ac_t""$libltdl_cv_shlibpath_var" 1>&6
+if test -n "$libltdl_cv_shlibpath_var"; then
+ cat >> confdefs.h <<EOF
+#define LTDL_SHLIBPATH_VAR "$libltdl_cv_shlibpath_var"
+EOF
+
+fi
+
+echo $ac_n "checking for objdir""... $ac_c" 1>&6
+echo "configure:1690: checking for objdir" >&5
+if eval "test \"`echo '$''{'libltdl_cv_objdir'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ libltdl_cv_objdir="$objdir"
+fi
+
+echo "$ac_t""$libltdl_cv_objdir" 1>&6
+test -z "$libltdl_cv_objdir" && libltdl_cv_objdir=".libs"
+cat >> confdefs.h <<EOF
+#define LTDL_OBJDIR "$libltdl_cv_objdir/"
+EOF
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1705: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1720 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1726: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1737 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1743: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1754 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1760: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1785: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1790 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1798: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1815 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1833 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1854 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in malloc.h memory.h stdlib.h stdio.h ctype.h dlfcn.h dl.h dld.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1892: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1897 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1902: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in string.h strings.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1932: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1937 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1942: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strchr index
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:1971: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1976 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in strrchr rindex
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2026: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2031 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2054: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking whether libtool supports -dlopen/-dlpreopen""... $ac_c" 1>&6
+echo "configure:2080: checking whether libtool supports -dlopen/-dlpreopen" >&5
+if eval "test \"`echo '$''{'libltdl_cv_preloaded_symbols'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$global_symbol_pipe"; then
+ libltdl_cv_preloaded_symbols=yes
+ else
+ libltdl_cv_preloaded_symbols=no
+ fi
+
+fi
+
+echo "$ac_t""$libltdl_cv_preloaded_symbols" 1>&6
+if test x"$libltdl_cv_preloaded_symbols" = x"yes"; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_PRELOADED_SYMBOLS 1
+EOF
+
+fi
+
+LIBADD_DL=
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:2102: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2110 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:2121: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_LIBDL 1
+EOF
+ LIBADD_DL="-ldl"
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for dlopen""... $ac_c" 1>&6
+echo "configure:2143: checking for dlopen" >&5
+if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2148 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char dlopen(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_dlopen) || defined (__stub___dlopen)
+choke me
+#else
+dlopen();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2171: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_dlopen=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_LIBDL 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for shl_load""... $ac_c" 1>&6
+echo "configure:2196: checking for shl_load" >&5
+if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2201 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char shl_load(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_shl_load) || defined (__stub___shl_load)
+choke me
+#else
+shl_load();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_shl_load=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SHL_LOAD 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6
+echo "configure:2245: checking for shl_load in -ldld" >&5
+ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2253 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char shl_load();
+
+int main() {
+shl_load()
+; return 0; }
+EOF
+if { (eval echo configure:2264: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_SHL_LOAD 1
+EOF
+ LIBADD_DL="$LIBADD_DL -ldld"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6
+echo "configure:2290: checking for dld_link in -ldld" >&5
+ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldld $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 2298 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dld_link();
+
+int main() {
+dld_link()
+; return 0; }
+EOF
+if { (eval echo configure:2309: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_DLD 1
+EOF
+test "x$ac_cv_lib_dld_shl_load" = yes || LIBADD_DL="$LIBADD_DL -ldld"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+if test "x$ac_cv_func_dlopen" = xyes || test "x$ac_cv_lib_dl_dlopen" = xyes; then
+ LIBS_SAVE="$LIBS"
+ LIBS="$LIBS $LIBADD_DL"
+ for ac_func in dlerror
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2340: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2345 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2368: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+ LIBS="$LIBS_SAVE"
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output""... $ac_c" 1>&6
+echo "configure:2397: checking command to parse $NM output" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_global_symbol_pipe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.* \($ac_symcode\) *\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if { (eval echo configure:2460: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if { (eval echo configure:2464: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo configure:2516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&5
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+echo "$ac_t""$ac_result" 1>&6
+
+echo $ac_n "checking for _ prefix in compiled symbols""... $ac_c" 1>&6
+echo "configure:2562: checking for _ prefix in compiled symbols" >&5
+if eval "test \"`echo '$''{'ac_cv_sys_symbol_underscore'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if { (eval echo configure:2571: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if { (eval echo configure:2574: \"$NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) 2>&5; } && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&5
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&5
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.c >&5
+fi
+rm -rf conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_sys_symbol_underscore" 1>&6
+
+if test x"$ac_cv_sys_symbol_underscore" = xyes; then
+ if test x"$ac_cv_func_dlopen" = xyes ||
+ test x"$ac_cv_lib_dl_dlopen" = xyes ; then
+ echo $ac_n "checking whether we have to add an underscore for dlsym""... $ac_c" 1>&6
+echo "configure:2602: checking whether we have to add an underscore for dlsym" >&5
+if eval "test \"`echo '$''{'libltdl_cv_need_uscore'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ libltdl_cv_need_uscore=cross
+
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2611 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 && !ptr2) exit(0); } exit(1); }
+
+EOF
+if { (eval echo configure:2658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ libltdl_cv_need_uscore=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ libltdl_cv_need_uscore=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$libltdl_cv_need_uscore" 1>&6
+ fi
+fi
+
+if test x"$libltdl_cv_need_uscore" = xyes; then
+ cat >> confdefs.h <<\EOF
+#define NEED_USCORE 1
+EOF
+
+fi
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile config.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@MAINTAINER_MODE_TRUE@%$MAINTAINER_MODE_TRUE%g
+s%@MAINTAINER_MODE_FALSE@%$MAINTAINER_MODE_FALSE%g
+s%@MAINT@%$MAINT%g
+s%@CC@%$CC%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@RANLIB@%$RANLIB%g
+s%@LD@%$LD%g
+s%@NM@%$NM%g
+s%@LN_S@%$LN_S%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@LIBTOOL_DEPS@%$LIBTOOL_DEPS%g
+s%@INSTALL_LTDL_TRUE@%$INSTALL_LTDL_TRUE%g
+s%@INSTALL_LTDL_FALSE@%$INSTALL_LTDL_FALSE%g
+s%@CONVENIENCE_LTDL_TRUE@%$CONVENIENCE_LTDL_TRUE%g
+s%@CONVENIENCE_LTDL_FALSE@%$CONVENIENCE_LTDL_FALSE%g
+s%@CPP@%$CPP%g
+s%@LIBADD_DL@%$LIBADD_DL%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="config.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+test -z "$CONFIG_HEADERS" || echo timestamp > stamp-h
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/libltdl/configure.in b/libltdl/configure.in
new file mode 100644
index 00000000..10233c6c
--- /dev/null
+++ b/libltdl/configure.in
@@ -0,0 +1,373 @@
+dnl Process this file with autoconf to create configure.
+
+AC_INIT(ltdl.c)
+
+if test -z "$enable_ltdl_install$enable_ltdl_convenience"; then
+ if test -f ${srcdir}/ltconfig && test -f ${srcdir}/ltmain.sh; then
+ # if libltdl is libtoolized, it is assumed to be stand-alone and
+ # installed unless the command line overrides it (tested above)
+ enable_ltdl_install=yes
+ else
+ AC_MSG_WARN([*** The top-level configure must select either])
+ AC_MSG_WARN([*** [A""C_LIBLTDL_INSTALLABLE] or [A""C_LIBLTDL_CONVENIENCE].])
+ AC_MSG_ERROR([*** Maybe you want to --enable-ltdl-install?])
+ fi
+fi
+
+AM_INIT_AUTOMAKE(libltdl,1.0,-)
+AM_CONFIG_HEADER(config.h)
+AM_MAINTAINER_MODE
+
+AC_PROG_CC
+AC_C_CONST
+AC_C_INLINE
+AM_PROG_LIBTOOL
+AC_SUBST(LIBTOOL_DEPS)
+
+AC_ARG_ENABLE(ltdl-install,
+[ --enable-ltdl-install install libltdl])
+
+AM_CONDITIONAL(INSTALL_LTDL, test x"${enable_ltdl_install-no}" != xno)
+AM_CONDITIONAL(CONVENIENCE_LTDL, test x"${enable_ltdl_convenience-no}" != xno)
+
+dnl Read the libtool configuration
+rm -f conftest
+./libtool --config > conftest
+. ./conftest
+rm -f conftest
+
+AC_CACHE_CHECK([which extension is used for shared libraries],
+ libltdl_cv_shlibext, [dnl
+(
+ last=
+ for spec in $library_names_spec; do
+ last="$spec"
+ done
+changequote(, )
+ echo "$last" | sed 's/\[.*\]//;s/^[^.]*//;s/\$.*$//;s/\.$//' > conftest
+changequote([, ])
+)
+libltdl_cv_shlibext=`cat conftest`
+rm -f conftest
+])
+if test -n "$libltdl_cv_shlibext"; then
+ AC_DEFINE_UNQUOTED(LTDL_SHLIB_EXT, "$libltdl_cv_shlibext",
+ [Define to the extension used for shared libraries, say, ".so". ])
+fi
+
+AC_CACHE_CHECK([which variable specifies run-time library path],
+ libltdl_cv_shlibpath_var, [libltdl_cv_shlibpath_var="$shlibpath_var"])
+if test -n "$libltdl_cv_shlibpath_var"; then
+ AC_DEFINE_UNQUOTED(LTDL_SHLIBPATH_VAR, "$libltdl_cv_shlibpath_var",
+ [Define to the name of the environment variable that determines the dynamic library search path. ])
+fi
+
+AC_CACHE_CHECK([for objdir],
+ libltdl_cv_objdir, [libltdl_cv_objdir="$objdir"])
+test -z "$libltdl_cv_objdir" && libltdl_cv_objdir=".libs"
+AC_DEFINE_UNQUOTED(LTDL_OBJDIR, "$libltdl_cv_objdir/",
+ [Define to the sub-directory in which libtool stores uninstalled libraries. ])
+
+AC_HEADER_STDC
+AC_CHECK_HEADERS(malloc.h memory.h stdlib.h stdio.h ctype.h dlfcn.h dl.h dld.h)
+AC_CHECK_HEADERS(string.h strings.h, break)
+AC_CHECK_FUNCS(strchr index, break)
+AC_CHECK_FUNCS(strrchr rindex, break)
+
+AC_CACHE_CHECK([whether libtool supports -dlopen/-dlpreopen],
+ libltdl_cv_preloaded_symbols, [dnl
+ if test -n "$global_symbol_pipe"; then
+ libltdl_cv_preloaded_symbols=yes
+ else
+ libltdl_cv_preloaded_symbols=no
+ fi
+])
+if test x"$libltdl_cv_preloaded_symbols" = x"yes"; then
+ AC_DEFINE(HAVE_PRELOADED_SYMBOLS, 1,
+ [Define if libtool can extract symbol lists from object files. ])
+fi
+
+LIBADD_DL=
+AC_CHECK_LIB(dl, dlopen, [AC_DEFINE(HAVE_LIBDL, 1) LIBADD_DL="-ldl"],
+[AC_CHECK_FUNC(dlopen, [AC_DEFINE(HAVE_LIBDL, 1)])])
+AC_CHECK_FUNC(shl_load, [AC_DEFINE(HAVE_SHL_LOAD, 1)],
+[AC_CHECK_LIB(dld, shl_load, [AC_DEFINE(HAVE_SHL_LOAD, 1) LIBADD_DL="$LIBADD_DL -ldld"])])
+AC_CHECK_LIB(dld, dld_link, [AC_DEFINE(HAVE_DLD, 1)dnl
+test "x$ac_cv_lib_dld_shl_load" = yes || LIBADD_DL="$LIBADD_DL -ldld"])
+AC_SUBST(LIBADD_DL)
+
+if test "x$ac_cv_func_dlopen" = xyes || test "x$ac_cv_lib_dl_dlopen" = xyes; then
+ LIBS_SAVE="$LIBS"
+ LIBS="$LIBS $LIBADD_DL"
+ AC_CHECK_FUNCS(dlerror)
+ LIBS="$LIBS_SAVE"
+fi
+
+dnl Check for command to grab the raw symbol name followed
+dnl by C symbol name from nm.
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+AC_MSG_CHECKING([command to parse $NM output])
+AC_CACHE_VAL(ac_cv_sys_global_symbol_pipe,
+[# These are sane defaults that work on at least a few old systems.
+# {They come from Ultrix. What could be older than Ultrix?!! ;)}
+
+changequote(,)dnl
+# Character class describing NM global symbol codes.
+ac_symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+ac_sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+ac_symxfrm='\1 \2\3 \3'
+
+# Transform an extracted symbol line into a proper C declaration
+ac_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'"
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ ac_symcode='[BCDT]'
+ ;;
+cygwin* | mingw*)
+ ac_symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ ac_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'"
+ ;;
+irix*)
+ ac_symcode='[BCDEGRST]'
+ ;;
+solaris*)
+ ac_symcode='[BDT]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ ac_symcode='[ABCDGISTW]'
+fi
+changequote([,])dnl
+
+# Try without a prefix undercore, then with it.
+for ac_symprfx in "" "_"; do
+
+ ac_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($ac_symcode\)[ ][ ]*\($ac_symprfx\)$ac_sympat$/$ac_symxfrm/p'"
+
+ # Check to see that the pipe works correctly.
+ ac_pipe_works=no
+ rm -f conftest.$ac_ext
+ cat > conftest.$ac_ext <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func;return 0;}
+EOF
+
+ if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$ac_nlist" | uniq > "$ac_nlist"T; then
+ mv -f "$ac_nlist"T "$ac_nlist"
+ else
+ rm -f "$ac_nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$ac_nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$ac_nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ eval "$ac_global_symbol_to_cdecl"' < "$ac_nlist" >> conftest.c'
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+changequote(,)dnl
+lt_preloaded_symbols[] =
+changequote([,])dnl
+{
+EOF
+ sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$ac_nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (lt_ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ ac_save_LIBS="$LIBS"
+ ac_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if AC_TRY_EVAL(ac_link) && test -s conftest; then
+ ac_pipe_works=yes
+ else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ LIBS="$ac_save_LIBS"
+ CFLAGS="$ac_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot find nm_test_var in $ac_nlist" >&AC_FD_CC
+ fi
+ else
+ echo "cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+ else
+ echo "$progname: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$ac_pipe_works" = yes; then
+ if test x"$ac_symprfx" = x"_"; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ ac_cv_sys_symbol_underscore=no
+ fi
+ break
+ else
+ ac_cv_sys_global_symbol_pipe=
+ fi
+done
+])
+
+ac_result=yes
+if test -z "$ac_cv_sys_global_symbol_pipe"; then
+ ac_result=no
+fi
+AC_MSG_RESULT($ac_result)
+
+dnl does the compiler prefix global symbols with an underscore?
+AC_MSG_CHECKING([for _ prefix in compiled symbols])
+AC_CACHE_VAL(ac_cv_sys_symbol_underscore,
+[ac_cv_sys_symbol_underscore=no
+cat > conftest.$ac_ext <<EOF
+void nm_test_func(){}
+int main(){nm_test_func;return 0;}
+EOF
+if AC_TRY_EVAL(ac_compile); then
+ # Now try to grab the symbols.
+ ac_nlist=conftest.nm
+ if AC_TRY_EVAL(NM conftest.$ac_objext \| $ac_cv_sys_global_symbol_pipe \> $ac_nlist) && test -s "$ac_nlist"; then
+ # See whether the symbols have a leading underscore.
+ if egrep '^. _nm_test_func' "$ac_nlist" >/dev/null; then
+ ac_cv_sys_symbol_underscore=yes
+ else
+ if egrep '^. nm_test_func ' "$ac_nlist" >/dev/null; then
+ :
+ else
+ echo "configure: cannot find nm_test_func in $ac_nlist" >&AC_FD_CC
+ fi
+ fi
+ else
+ echo "configure: cannot run $ac_cv_sys_global_symbol_pipe" >&AC_FD_CC
+ fi
+else
+ echo "configure: failed program was:" >&AC_FD_CC
+ cat conftest.c >&AC_FD_CC
+fi
+rm -rf conftest*
+])
+AC_MSG_RESULT($ac_cv_sys_symbol_underscore)
+
+if test x"$ac_cv_sys_symbol_underscore" = xyes; then
+ if test x"$ac_cv_func_dlopen" = xyes ||
+ test x"$ac_cv_lib_dl_dlopen" = xyes ; then
+ AC_CACHE_CHECK([whether we have to add an underscore for dlsym],
+ libltdl_cv_need_uscore, [dnl
+ AC_TRY_RUN([
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+fnord() { int i=42;}
+main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW);
+ if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord");
+ if(ptr1 && !ptr2) exit(0); } exit(1); }
+], libltdl_cv_need_uscore=no, libltdl_cv_need_uscore=yes,
+ libltdl_cv_need_uscore=cross
+)])
+ fi
+fi
+
+if test x"$libltdl_cv_need_uscore" = xyes; then
+ AC_DEFINE(NEED_USCORE, 1,
+ [Define if dlsym() requires a leading underscode in symbol names. ])
+fi
+
+dnl Output the makefile
+AC_OUTPUT(Makefile)
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/libltdl/ltdl.c b/libltdl/ltdl.c
new file mode 100644
index 00000000..ce37e27e
--- /dev/null
+++ b/libltdl/ltdl.c
@@ -0,0 +1,1577 @@
+/* ltdl.c -- system independent dlopen wrapper
+ Copyright (C) 1998-1999 Free Software Foundation, Inc.
+ Originally by Thomas Tanner <tanner@gmx.de>
+ This file is part of GNU Libtool.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+As a special exception to the GNU Library General Public License,
+if you distribute this file as part of a program that uses GNU libtool
+to create libraries and programs, you may include it under the same
+distribution terms that you use for the rest of that program.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free
+Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#define _LTDL_COMPILE_
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#if HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#if HAVE_MEMORY_H
+#include <memory.h>
+#endif
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#include "ltdl.h"
+
+/* max. filename length */
+#ifndef LTDL_FILENAME_MAX
+#define LTDL_FILENAME_MAX 1024
+#endif
+
+#undef LTDL_READTEXT_MODE
+/* fopen() mode flags for reading a text file */
+#ifdef _WIN32
+#define LTDL_READTEXT_MODE "rt"
+#else
+#define LTDL_READTEXT_MODE "r"
+#endif
+
+#undef LTDL_SYMBOL_LENGTH
+/* This is the maximum symbol size that won't require malloc/free */
+#define LTDL_SYMBOL_LENGTH 128
+
+#undef LTDL_SYMBOL_OVERHEAD
+/* This accounts for the _LTX_ separator */
+#define LTDL_SYMBOL_OVERHEAD 5
+
+static const char objdir[] = LTDL_OBJDIR;
+#ifdef LTDL_SHLIB_EXT
+static const char shlib_ext[] = LTDL_SHLIB_EXT;
+#endif
+
+static const char unknown_error[] = "unknown error";
+static const char dlopen_not_supported_error[] = "dlopen support not available";
+static const char file_not_found_error[] = "file not found";
+static const char no_symbols_error[] = "no symbols defined";
+static const char cannot_open_error[] = "can't open the module";
+static const char cannot_close_error[] = "can't close the module";
+static const char symbol_error[] = "symbol not found";
+static const char memory_error[] = "not enough memory";
+static const char invalid_handle_error[] = "invalid handle";
+static const char buffer_overflow_error[] = "internal buffer overflow";
+static const char shutdown_error[] = "library already shutdown";
+
+#ifndef HAVE_PRELOADED_SYMBOLS
+/* If libtool won't define it, we'd better do */
+const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
+#endif
+
+static const char *last_error = 0;
+
+lt_ptr_t (*lt_dlmalloc) LTDL_PARAMS((size_t size)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc;
+void (*lt_dlfree) LTDL_PARAMS((lt_ptr_t ptr)) = (void(*)LTDL_PARAMS((lt_ptr_t)))free;
+
+typedef struct lt_dltype_t {
+ struct lt_dltype_t *next;
+ const char *sym_prefix; /* prefix for symbols */
+ int (*mod_init) LTDL_PARAMS((void));
+ int (*mod_exit) LTDL_PARAMS((void));
+ int (*lib_open) LTDL_PARAMS((lt_dlhandle handle, const char *filename));
+ int (*lib_close) LTDL_PARAMS((lt_dlhandle handle));
+ lt_ptr_t (*find_sym) LTDL_PARAMS((lt_dlhandle handle, const char *symbol));
+} lt_dltype_t;
+
+#define LTDL_TYPE_TOP 0
+
+typedef struct lt_dlhandle_t {
+ struct lt_dlhandle_t *next;
+ lt_dltype_t *type; /* dlopening interface */
+ char *filename; /* file name */
+ char *name; /* module name */
+ int usage; /* usage */
+ int depcount; /* number of dependencies */
+ lt_dlhandle *deplibs; /* dependencies */
+ lt_ptr_t handle; /* system handle */
+ lt_ptr_t system; /* system specific data */
+} lt_dlhandle_t;
+
+#undef strdup
+#define strdup xstrdup
+
+static inline char *
+strdup(str)
+ const char *str;
+{
+ char *tmp;
+
+ if (!str)
+ return 0;
+ tmp = (char*) lt_dlmalloc(strlen(str)+1);
+ if (tmp)
+ strcpy(tmp, str);
+ return tmp;
+}
+
+#if ! HAVE_STRCHR
+
+# if HAVE_INDEX
+
+# define strchr index
+
+# else
+
+# define strchr xstrchr
+
+static inline const char*
+strchr(str, ch)
+ const char *str;
+ int ch;
+{
+ const char *p;
+
+ for (p = str; *p != (char)ch && p != '\0'; p++)
+ /*NOWORK*/;
+
+ return (*p == (char)ch) ? p : 0;
+}
+
+# endif
+
+#endif
+
+#if ! HAVE_STRRCHR
+
+# if HAVE_RINDEX
+
+# define strrchr rindex
+
+# else
+
+# define strrchr xstrrchr
+
+static inline const char*
+strrchr(str, ch)
+ const char *str;
+ int ch;
+{
+ const char *p;
+
+ for (p = str; p != '\0'; p++)
+ /*NOWORK*/;
+
+ while (*p != (char)ch && p >= str)
+ p--;
+
+ return (*p == (char)ch) ? p : 0;
+}
+
+# endif
+
+#endif
+
+#if HAVE_LIBDL
+
+/* dynamic linking with dlopen/dlsym */
+
+#if HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+static int
+sys_dl_init LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_dl_exit LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_dl_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ handle->handle = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
+ if (!handle->handle) {
+#if HAVE_DLERROR
+ last_error = dlerror();
+#else
+ last_error = cannot_open_error;
+#endif
+ return 1;
+ }
+ return 0;
+}
+
+static int
+sys_dl_close (handle)
+ lt_dlhandle handle;
+{
+ if (dlclose(handle->handle) != 0) {
+#if HAVE_DLERROR
+ last_error = dlerror();
+#else
+ last_error = cannot_close_error;
+#endif
+ return 1;
+ }
+ return 0;
+}
+
+static lt_ptr_t
+sys_dl_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_ptr_t address = dlsym(handle->handle, symbol);
+
+ if (!address)
+#if HAVE_DLERROR
+ last_error = dlerror();
+#else
+ last_error = symbol_error;
+#endif
+ return address;
+}
+
+static
+lt_dltype_t
+#ifdef NEED_USCORE
+sys_dl = { LTDL_TYPE_TOP, "_", sys_dl_init, sys_dl_exit,
+ sys_dl_open, sys_dl_close, sys_dl_sym };
+#else
+sys_dl = { LTDL_TYPE_TOP, 0, sys_dl_init, sys_dl_exit,
+ sys_dl_open, sys_dl_close, sys_dl_sym };
+#endif
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &sys_dl
+
+#endif
+
+#if HAVE_SHL_LOAD
+
+/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
+
+#ifdef HAVE_DL_H
+#include <dl.h>
+#endif
+
+/* some flags are missing on some systems, so we provide
+ * harmless defaults.
+ *
+ * Mandatory:
+ * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
+ * BIND_DEFERRED - Delay code symbol resolution until actual reference.
+ *
+ * Optionally:
+ * BIND_FIRST - Place the library at the head of the symbol search order.
+ * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all unsatisfied
+ * symbols as fatal. This flag allows binding of unsatisfied code
+ * symbols to be deferred until use.
+ * [Perl: For certain libraries, like DCE, deferred binding often
+ * causes run time problems. Adding BIND_NONFATAL to BIND_IMMEDIATE
+ * still allows unresolved references in situations like this.]
+ * BIND_NOSTART - Do not call the initializer for the shared library when the
+ * library is loaded, nor on a future call to shl_unload().
+ * BIND_VERBOSE - Print verbose messages concerning possible unsatisfied symbols.
+ *
+ * hp9000s700/hp9000s800:
+ * BIND_RESTRICTED - Restrict symbols visible by the library to those present at
+ * library load time.
+ * DYNAMIC_PATH - Allow the loader to dynamically search for the library specified
+ * by the path argument.
+ */
+
+#ifndef DYNAMIC_PATH
+#define DYNAMIC_PATH 0
+#endif /* DYNAMIC_PATH */
+#ifndef BIND_RESTRICTED
+#define BIND_RESTRICTED 0
+#endif /* BIND_RESTRICTED */
+
+#define LTDL_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE | DYNAMIC_PATH)
+
+static int
+sys_shl_init LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_shl_exit LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_shl_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ handle->handle = shl_load(filename, LTDL_BIND_FLAGS, 0L);
+ if (!handle->handle) {
+ last_error = cannot_open_error;
+ return 1;
+ }
+ return 0;
+}
+
+static int
+sys_shl_close (handle)
+ lt_dlhandle handle;
+{
+ if (shl_unload((shl_t) (handle->handle)) != 0) {
+ last_error = cannot_close_error;
+ return 1;
+ }
+ return 0;
+}
+
+static lt_ptr_t
+sys_shl_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_ptr_t address;
+
+ if (handle->handle && shl_findsym((shl_t*) &(handle->handle),
+ symbol, TYPE_UNDEFINED, &address) == 0)
+ if (address)
+ return address;
+ last_error = symbol_error;
+ return 0;
+}
+
+static
+lt_dltype_t
+sys_shl = { LTDL_TYPE_TOP, 0, sys_shl_init, sys_shl_exit,
+ sys_shl_open, sys_shl_close, sys_shl_sym };
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &sys_shl
+
+#endif
+
+#if HAVE_DLD
+
+/* dynamic linking with dld */
+
+#if HAVE_DLD_H
+#include <dld.h>
+#endif
+
+static int
+sys_dld_init LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_dld_exit LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_dld_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ handle->handle = strdup(filename);
+ if (!handle->handle) {
+ last_error = memory_error;
+ return 1;
+ }
+ if (dld_link(filename) != 0) {
+ last_error = cannot_open_error;
+ lt_dlfree(handle->handle);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+sys_dld_close (handle)
+ lt_dlhandle handle;
+{
+ if (dld_unlink_by_file((char*)(handle->handle), 1) != 0) {
+ last_error = cannot_close_error;
+ return 1;
+ }
+ lt_dlfree(handle->filename);
+ return 0;
+}
+
+static lt_ptr_t
+sys_dld_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_ptr_t address = dld_get_func(symbol);
+
+ if (!address)
+ last_error = symbol_error;
+ return address;
+}
+
+static
+lt_dltype_t
+sys_dld = { LTDL_TYPE_TOP, 0, sys_dld_init, sys_dld_exit,
+ sys_dld_open, sys_dld_close, sys_dld_sym };
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &sys_dld
+
+#endif
+
+#ifdef _WIN32
+
+/* dynamic linking for Win32 */
+
+#include <windows.h>
+
+static int
+sys_wll_init LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_wll_exit LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_wll_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ handle->handle = LoadLibrary(filename);
+ if (!handle->handle) {
+ last_error = cannot_open_error;
+ return 1;
+ }
+ return 0;
+}
+
+static int
+sys_wll_close (handle)
+ lt_dlhandle handle;
+{
+ if (FreeLibrary(handle->handle) != 0) {
+ last_error = cannot_close_error;
+ return 1;
+ }
+ return 0;
+}
+
+static lt_ptr_t
+sys_wll_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_ptr_t address = GetProcAddress(handle->handle, symbol);
+
+ if (!address)
+ last_error = symbol_error;
+ return address;
+}
+
+static
+lt_dltype_t
+sys_wll = { LTDL_TYPE_TOP, 0, sys_wll_init, sys_wll_exit,
+ sys_wll_open, sys_wll_close, sys_wll_sym };
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &sys_wll
+
+#endif
+
+#ifdef __BEOS__
+
+/* dynamic linking for BeOS */
+
+#include <kernel/image.h>
+
+static int
+sys_bedl_init LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_bedl_exit LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_bedl_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ image_id image = 0;
+
+ if (filename) {
+ image = load_add_on(filename);
+ } else {
+ image_info info;
+ int32 cookie = 0;
+ if (get_next_image_info(0, &cookie, &info) == B_OK)
+ image = load_add_on(info.name);
+ }
+ if (image <= 0) {
+ last_error = cannot_open_error;
+ return 1;
+ }
+ handle->handle = (void*) image;
+ return 0;
+}
+
+static int
+sys_bedl_close (handle)
+ lt_dlhandle handle;
+{
+ if (unload_add_on((image_id)handle->handle) != B_OK) {
+ last_error = cannot_close_error;
+ return 1;
+ }
+ return 0;
+}
+
+static lt_ptr_t
+sys_bedl_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_ptr_t address = 0;
+ image_id image = (image_id)handle->handle;
+
+ if (get_image_symbol(image, symbol, B_SYMBOL_TYPE_ANY,
+ &address) != B_OK) {
+ last_error = symbol_error;
+ return 0;
+ }
+ return address;
+}
+
+static
+lt_dltype_t
+sys_bedl = { LTDL_TYPE_TOP, 0, sys_bedl_init, sys_bedl_exit,
+ sys_bedl_open, sys_bedl_close, sys_bedl_sym };
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &sys_bedl
+
+#endif
+
+/* emulate dynamic linking using preloaded_symbols */
+
+typedef struct lt_dlsymlists_t {
+ struct lt_dlsymlists_t *next;
+ const lt_dlsymlist *syms;
+} lt_dlsymlists_t;
+
+static const lt_dlsymlist *default_preloaded_symbols = 0;
+static lt_dlsymlists_t *preloaded_symbols = 0;
+
+static int
+presym_init LTDL_PARAMS((void))
+{
+ preloaded_symbols = 0;
+ if (default_preloaded_symbols)
+ return lt_dlpreload(default_preloaded_symbols);
+ return 0;
+}
+
+static int
+presym_free_symlists LTDL_PARAMS((void))
+{
+ lt_dlsymlists_t *lists = preloaded_symbols;
+
+ while (lists) {
+ lt_dlsymlists_t *tmp = lists;
+
+ lists = lists->next;
+ lt_dlfree(tmp);
+ }
+ preloaded_symbols = 0;
+ return 0;
+}
+
+static int
+presym_exit LTDL_PARAMS((void))
+{
+ presym_free_symlists();
+ return 0;
+}
+
+static int
+presym_add_symlist (preloaded)
+ const lt_dlsymlist *preloaded;
+{
+ lt_dlsymlists_t *tmp;
+ lt_dlsymlists_t *lists = preloaded_symbols;
+
+ while (lists) {
+ if (lists->syms == preloaded)
+ return 0;
+ lists = lists->next;
+ }
+
+ tmp = (lt_dlsymlists_t*) lt_dlmalloc(sizeof(lt_dlsymlists_t));
+ if (!tmp) {
+ last_error = memory_error;
+ return 1;
+ }
+ tmp->syms = preloaded;
+ tmp->next = 0;
+ if (!preloaded_symbols)
+ preloaded_symbols = tmp;
+ else {
+ /* append to the end */
+ lists = preloaded_symbols;
+ while (lists->next)
+ lists = lists->next;
+ lists->next = tmp;
+ }
+ return 0;
+}
+
+static int
+presym_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ lt_dlsymlists_t *lists = preloaded_symbols;
+
+ if (!lists) {
+ last_error = no_symbols_error;
+ return 1;
+ }
+ if (!filename)
+ filename = "@PROGRAM@";
+ while (lists) {
+ const lt_dlsymlist *syms = lists->syms;
+
+ while (syms->name) {
+ if (!syms->address &&
+ strcmp(syms->name, filename) == 0) {
+ handle->handle = (lt_ptr_t) syms;
+ return 0;
+ }
+ syms++;
+ }
+ lists = lists->next;
+ }
+ last_error = file_not_found_error;
+ return 1;
+}
+
+static int
+presym_close (handle)
+ lt_dlhandle handle;
+{
+ /* Just to silence gcc -Wall */
+ handle = 0;
+ return 0;
+}
+
+static lt_ptr_t
+presym_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_dlsymlist *syms = (lt_dlsymlist*)(handle->handle);
+
+ syms++;
+ while (syms->address) {
+ if (strcmp(syms->name, symbol) == 0)
+ return syms->address;
+ syms++;
+ }
+ last_error = symbol_error;
+ return 0;
+}
+
+static
+lt_dltype_t
+presym = { LTDL_TYPE_TOP, 0, presym_init, presym_exit,
+ presym_open, presym_close, presym_sym };
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &presym
+
+static char *user_search_path = 0;
+static lt_dlhandle handles = 0;
+static int initialized = 0;
+
+static lt_dltype_t *types = LTDL_TYPE_TOP;
+#undef LTDL_TYPE_TOP
+
+int
+lt_dlinit LTDL_PARAMS((void))
+{
+ /* initialize libltdl */
+ lt_dltype_t **type = &types;
+ int typecount = 0;
+
+ if (initialized) { /* Initialize only at first call. */
+ initialized++;
+ return 0;
+ }
+ handles = 0;
+ user_search_path = 0; /* empty search path */
+
+ while (*type) {
+ if ((*type)->mod_init())
+ *type = (*type)->next; /* Remove it from the list */
+ else {
+ type = &(*type)->next; /* Keep it */
+ typecount++;
+ }
+ }
+ if (typecount == 0) {
+ last_error = dlopen_not_supported_error;
+ return 1;
+ }
+ last_error = 0;
+ initialized = 1;
+ return 0;
+}
+
+int
+lt_dlpreload (preloaded)
+ const lt_dlsymlist *preloaded;
+{
+ if (preloaded)
+ return presym_add_symlist(preloaded);
+ presym_free_symlists();
+ if (default_preloaded_symbols)
+ return lt_dlpreload(default_preloaded_symbols);
+ return 0;
+}
+
+int
+lt_dlpreload_default (preloaded)
+ const lt_dlsymlist *preloaded;
+{
+ default_preloaded_symbols = preloaded;
+ return 0;
+}
+
+int
+lt_dlexit LTDL_PARAMS((void))
+{
+ /* shut down libltdl */
+ lt_dltype_t *type = types;
+ int errors;
+
+ if (!initialized) {
+ last_error = shutdown_error;
+ return 1;
+ }
+ if (initialized != 1) { /* shut down only at last call. */
+ initialized--;
+ return 0;
+ }
+ /* close all modules */
+ errors = 0;
+ while (handles) {
+ /* FIXME: what if a module depends on another one? */
+ if (lt_dlclose(handles))
+ errors++;
+ }
+ initialized = 0;
+ while (type) {
+ if (type->mod_exit())
+ errors++;
+ type = type->next;
+ }
+ return errors;
+}
+
+static int
+tryall_dlopen (handle, filename)
+ lt_dlhandle *handle;
+ const char *filename;
+{
+ lt_dlhandle cur;
+ lt_dltype_t *type = types;
+ const char *saved_error = last_error;
+
+ /* check whether the module was already opened */
+ cur = handles;
+ while (cur) {
+ if (!cur->filename && !filename)
+ break;
+ if (cur->filename && filename &&
+ strcmp(cur->filename, filename) == 0)
+ break;
+ cur = cur->next;
+ }
+ if (cur) {
+ cur->usage++;
+ *handle = cur;
+ return 0;
+ }
+
+ cur = *handle;
+ if (filename) {
+ cur->filename = strdup(filename);
+ if (!cur->filename) {
+ last_error = memory_error;
+ return 1;
+ }
+ } else
+ cur->filename = 0;
+ while (type) {
+ if (type->lib_open(cur, filename) == 0)
+ break;
+ type = type->next;
+ }
+ if (!type) {
+ if (cur->filename)
+ lt_dlfree(cur->filename);
+ return 1;
+ }
+ cur->type = type;
+ last_error = saved_error;
+ return 0;
+}
+
+static int
+find_module (handle, dir, libdir, dlname, old_name, installed)
+ lt_dlhandle *handle;
+ const char *dir;
+ const char *libdir;
+ const char *dlname;
+ const char *old_name;
+ int installed;
+{
+ int error;
+ char *filename;
+ /* try to open the old library first; if it was dlpreopened,
+ we want the preopened version of it, even if a dlopenable
+ module is available */
+ if (old_name && tryall_dlopen(handle, old_name) == 0)
+ return 0;
+ /* try to open the dynamic library */
+ if (dlname) {
+ /* try to open the installed module */
+ if (installed && libdir) {
+ filename = (char*)
+ lt_dlmalloc(strlen(libdir)+1+strlen(dlname)+1);
+ if (!filename) {
+ last_error = memory_error;
+ return 1;
+ }
+ strcpy(filename, libdir);
+ strcat(filename, "/");
+ strcat(filename, dlname);
+ error = tryall_dlopen(handle, filename) == 0;
+ lt_dlfree(filename);
+ if (error)
+ return 0;
+ }
+ /* try to open the not-installed module */
+ if (!installed) {
+ filename = (char*)
+ lt_dlmalloc((dir ? strlen(dir) : 0)
+ + strlen(objdir) + strlen(dlname) + 1);
+ if (!filename) {
+ last_error = memory_error;
+ return 1;
+ }
+ if (dir)
+ strcpy(filename, dir);
+ else
+ *filename = 0;
+ strcat(filename, objdir);
+ strcat(filename, dlname);
+
+ error = tryall_dlopen(handle, filename) == 0;
+ lt_dlfree(filename);
+ if (error)
+ return 0;
+ }
+ /* hmm, maybe it was moved to another directory */
+ {
+ filename = (char*)
+ lt_dlmalloc((dir ? strlen(dir) : 0)
+ + strlen(dlname) + 1);
+ if (dir)
+ strcpy(filename, dir);
+ else
+ *filename = 0;
+ strcat(filename, dlname);
+ error = tryall_dlopen(handle, filename) == 0;
+ lt_dlfree(filename);
+ if (error)
+ return 0;
+ }
+ }
+ last_error = file_not_found_error;
+ return 1;
+}
+
+static lt_ptr_t
+find_file (basename, search_path, pdir, handle)
+ const char *basename;
+ const char *search_path;
+ char **pdir;
+ lt_dlhandle *handle;
+{
+ /* when handle != NULL search a library, otherwise a file */
+ /* return NULL on failure, otherwise the file/handle */
+
+ char *filename = 0;
+ int filenamesize = 0;
+ const char *next = search_path;
+ int lenbase = strlen(basename);
+
+ if (!next || !*next) {
+ last_error = file_not_found_error;
+ return 0;
+ }
+ while (next) {
+ int lendir;
+ const char *cur = next;
+
+ next = strchr(cur, ':');
+ if (!next)
+ next = cur + strlen(cur);
+ lendir = next - cur;
+ if (*next == ':')
+ ++next;
+ else
+ next = 0;
+ if (lendir == 0)
+ continue;
+ if (lendir + 1 + lenbase >= filenamesize) {
+ if (filename)
+ lt_dlfree(filename);
+ filenamesize = lendir + 1 + lenbase + 1;
+ filename = (char*) lt_dlmalloc(filenamesize);
+ if (!filename) {
+ last_error = memory_error;
+ return 0;
+ }
+ }
+ strncpy(filename, cur, lendir);
+ if (filename[lendir-1] != '/')
+ filename[lendir++] = '/';
+ strcpy(filename+lendir, basename);
+ if (handle) {
+ if (tryall_dlopen(handle, filename) == 0) {
+ lt_dlfree(filename);
+ return (lt_ptr_t) handle;
+ }
+ } else {
+ FILE *file = fopen(filename, LTDL_READTEXT_MODE);
+ if (file) {
+ if (*pdir)
+ lt_dlfree(*pdir);
+ filename[lendir] = '\0';
+ *pdir = strdup(filename);
+ if (!*pdir) {
+ /* We could have even avoided the
+ strdup, but there would be some
+ memory overhead. */
+ *pdir = filename;
+ } else
+ lt_dlfree(filename);
+ return (lt_ptr_t) file;
+ }
+ }
+ }
+ if (filename)
+ lt_dlfree(filename);
+ last_error = file_not_found_error;
+ return 0;
+}
+
+static int
+load_deplibs(handle, deplibs)
+ lt_dlhandle handle;
+ const char *deplibs;
+{
+ /* FIXME: load deplibs */
+ handle->depcount = 0;
+ handle->deplibs = 0;
+ /* Just to silence gcc -Wall */
+ deplibs = 0;
+ return 0;
+}
+
+static int
+unload_deplibs(handle)
+ lt_dlhandle handle;
+{
+ /* FIXME: unload deplibs */
+ /* Just to silence gcc -Wall */
+ handle = 0;
+ return 0;
+}
+
+static inline int
+trim (dest, str)
+ char **dest;
+ const char *str;
+{
+ /* remove the leading and trailing "'" from str
+ and store the result in dest */
+ char *tmp;
+ char *end = strrchr(str, '\'');
+ int len = strlen(str);
+
+ if (*dest)
+ lt_dlfree(*dest);
+ if (len > 3 && str[0] == '\'') {
+ tmp = (char*) lt_dlmalloc(end - str);
+ if (!tmp) {
+ last_error = memory_error;
+ return 1;
+ }
+ strncpy(tmp, &str[1], (end - str) - 1);
+ tmp[len-3] = '\0';
+ *dest = tmp;
+ } else
+ *dest = 0;
+ return 0;
+}
+
+static inline int
+free_vars(dir, name, dlname, oldname, libdir, deplibs)
+ char *dir;
+ char *name;
+ char *dlname;
+ char *oldname;
+ char *libdir;
+ char *deplibs;
+{
+ if (dir)
+ lt_dlfree(dir);
+ if (name)
+ lt_dlfree(name);
+ if (dlname)
+ lt_dlfree(dlname);
+ if (oldname)
+ lt_dlfree(oldname);
+ if (libdir)
+ lt_dlfree(libdir);
+ if (deplibs)
+ lt_dlfree(deplibs);
+ return 0;
+}
+
+lt_dlhandle
+lt_dlopen (filename)
+ const char *filename;
+{
+ lt_dlhandle handle, newhandle;
+ const char *basename, *ext;
+ const char *saved_error = last_error;
+ char *dir = 0, *name = 0;
+
+ if (!filename) {
+ handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
+ if (!handle) {
+ last_error = memory_error;
+ return 0;
+ }
+ handle->usage = 0;
+ handle->depcount = 0;
+ handle->deplibs = 0;
+ newhandle = handle;
+ if (tryall_dlopen(&newhandle, 0) != 0) {
+ lt_dlfree(handle);
+ return 0;
+ }
+ goto register_handle;
+ }
+ basename = strrchr(filename, '/');
+ if (basename) {
+ basename++;
+ dir = (char*) lt_dlmalloc(basename - filename + 1);
+ if (!dir) {
+ last_error = memory_error;
+ return 0;
+ }
+ strncpy(dir, filename, basename - filename);
+ dir[basename - filename] = '\0';
+ } else
+ basename = filename;
+ /* check whether we open a libtool module (.la extension) */
+ ext = strrchr(basename, '.');
+ if (ext && strcmp(ext, ".la") == 0) {
+ /* this seems to be a libtool module */
+ FILE *file;
+ int i;
+ char *dlname = 0, *old_name = 0;
+ char *libdir = 0, *deplibs = 0;
+ char *line;
+ int error = 0;
+ /* if we can't find the installed flag, it is probably an
+ installed libtool archive, produced with an old version
+ of libtool */
+ int installed = 1;
+
+ /* extract the module name from the file name */
+ name = (char*) lt_dlmalloc(ext - basename + 1);
+ if (!name) {
+ last_error = memory_error;
+ if (dir)
+ lt_dlfree(dir);
+ return 0;
+ }
+ /* canonicalize the module name */
+ for (i = 0; i < ext - basename; i++)
+ if (isalnum((int)(basename[i])))
+ name[i] = basename[i];
+ else
+ name[i] = '_';
+ name[ext - basename] = '\0';
+ /* now try to open the .la file */
+ file = fopen(filename, LTDL_READTEXT_MODE);
+ if (!file)
+ last_error = file_not_found_error;
+ if (!file && !dir) {
+ /* try other directories */
+ file = (FILE*) find_file(basename,
+ user_search_path,
+ &dir, 0);
+ if (!file)
+ file = (FILE*) find_file(basename,
+ getenv("LTDL_LIBRARY_PATH"),
+ &dir, 0);
+#ifdef LTDL_SHLIBPATH_VAR
+ if (!file)
+ file = (FILE*) find_file(basename,
+ getenv(LTDL_SHLIBPATH_VAR),
+ &dir, 0);
+#endif
+ }
+ if (!file) {
+ if (name)
+ lt_dlfree(name);
+ if (dir)
+ lt_dlfree(dir);
+ return 0;
+ }
+ line = (char*) lt_dlmalloc(LTDL_FILENAME_MAX);
+ if (!line) {
+ fclose(file);
+ last_error = memory_error;
+ return 0;
+ }
+ /* read the .la file */
+ while (!feof(file)) {
+ if (!fgets(line, LTDL_FILENAME_MAX, file))
+ break;
+ if (line[0] == '\n' || line[0] == '#')
+ continue;
+# undef STR_DLNAME
+# define STR_DLNAME "dlname="
+ if (strncmp(line, STR_DLNAME,
+ sizeof(STR_DLNAME) - 1) == 0)
+ error = trim(&dlname,
+ &line[sizeof(STR_DLNAME) - 1]);
+ else
+# undef STR_OLD_LIBRARY
+# define STR_OLD_LIBRARY "old_library="
+ if (strncmp(line, STR_OLD_LIBRARY,
+ sizeof(STR_OLD_LIBRARY) - 1) == 0)
+ error = trim(&old_name,
+ &line[sizeof(STR_OLD_LIBRARY) - 1]);
+ else
+# undef STR_LIBDIR
+# define STR_LIBDIR "libdir="
+ if (strncmp(line, STR_LIBDIR,
+ sizeof(STR_LIBDIR) - 1) == 0)
+ error = trim(&libdir,
+ &line[sizeof(STR_LIBDIR) - 1]);
+ else
+# undef STR_DL_DEPLIBS
+# define STR_DL_DEPLIBS "dl_dependency_libs="
+ if (strncmp(line, STR_DL_DEPLIBS,
+ sizeof(STR_DL_DEPLIBS) - 1) == 0)
+ error = trim(&deplibs,
+ &line[sizeof(STR_DL_DEPLIBS) - 1]);
+ else
+ if (strcmp(line, "installed=yes\n") == 0)
+ installed = 1;
+ else
+ if (strcmp(line, "installed=no\n") == 0)
+ installed = 0;
+ if (error)
+ break;
+ }
+ fclose(file);
+ lt_dlfree(line);
+ /* allocate the handle */
+ handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
+ if (!handle || error) {
+ if (handle)
+ lt_dlfree(handle);
+ if (!error)
+ last_error = memory_error;
+ free_vars(name, dir, dlname, old_name, libdir, deplibs);
+ return 0;
+ }
+ handle->usage = 0;
+ if (load_deplibs(handle, deplibs) == 0) {
+ newhandle = handle;
+ /* find_module may replace newhandle */
+ if (find_module(&newhandle, dir, libdir,
+ dlname, old_name, installed)) {
+ unload_deplibs(handle);
+ error = 1;
+ }
+ } else
+ error = 1;
+ if (error) {
+ lt_dlfree(handle);
+ free_vars(name, dir, dlname, old_name, libdir, deplibs);
+ return 0;
+ }
+ if (handle != newhandle) {
+ unload_deplibs(handle);
+ }
+ } else {
+ /* not a libtool module */
+ handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
+ if (!handle) {
+ last_error = memory_error;
+ if (dir)
+ lt_dlfree(dir);
+ return 0;
+ }
+ handle->usage = 0;
+ /* non-libtool modules don't have dependencies */
+ handle->depcount = 0;
+ handle->deplibs = 0;
+ newhandle = handle;
+ if (tryall_dlopen(&newhandle, filename)
+ && (!dir
+ || (!find_file(basename, user_search_path,
+ 0, &newhandle)
+ && !find_file(basename,
+ getenv("LTDL_LIBRARY_PATH"),
+ 0, &newhandle)
+#ifdef LTDL_SHLIBPATH_VAR
+ && !find_file(basename,
+ getenv(LTDL_SHLIBPATH_VAR),
+ 0, &newhandle)
+#endif
+ ))) {
+ lt_dlfree(handle);
+ if (dir)
+ lt_dlfree(dir);
+ return 0;
+ }
+ }
+register_handle:
+ if (newhandle != handle) {
+ lt_dlfree(handle);
+ handle = newhandle;
+ }
+ if (!handle->usage) {
+ handle->usage = 1;
+ handle->name = name;
+ handle->next = handles;
+ handles = handle;
+ } else if (name)
+ lt_dlfree(name);
+ if (dir)
+ lt_dlfree(dir);
+ last_error = saved_error;
+ return handle;
+}
+
+lt_dlhandle
+lt_dlopenext (filename)
+ const char *filename;
+{
+ lt_dlhandle handle;
+ char *tmp;
+ int len;
+ const char *saved_error = last_error;
+
+ if (!filename)
+ return lt_dlopen(filename);
+ len = strlen(filename);
+ if (!len) {
+ last_error = file_not_found_error;
+ return 0;
+ }
+ /* try the normal file name */
+ handle = lt_dlopen(filename);
+ if (handle)
+ return handle;
+ /* try "filename.la" */
+ tmp = (char*) lt_dlmalloc(len+4);
+ if (!tmp) {
+ last_error = memory_error;
+ return 0;
+ }
+ strcpy(tmp, filename);
+ strcat(tmp, ".la");
+ handle = lt_dlopen(tmp);
+ if (handle) {
+ last_error = saved_error;
+ lt_dlfree(tmp);
+ return handle;
+ }
+#ifdef LTDL_SHLIB_EXT
+ /* try "filename.EXT" */
+ if (strlen(shlib_ext) > 3) {
+ lt_dlfree(tmp);
+ tmp = (char*) lt_dlmalloc(len + strlen(shlib_ext) + 1);
+ if (!tmp) {
+ last_error = memory_error;
+ return 0;
+ }
+ strcpy(tmp, filename);
+ } else
+ tmp[len] = '\0';
+ strcat(tmp, shlib_ext);
+ handle = lt_dlopen(tmp);
+ if (handle) {
+ last_error = saved_error;
+ lt_dlfree(tmp);
+ return handle;
+ }
+#endif
+ last_error = file_not_found_error;
+ lt_dlfree(tmp);
+ return 0;
+}
+
+int
+lt_dlclose (handle)
+ lt_dlhandle handle;
+{
+ lt_dlhandle cur, last;
+
+ /* check whether the handle is valid */
+ last = cur = handles;
+ while (cur && handle != cur) {
+ last = cur;
+ cur = cur->next;
+ }
+ if (!cur) {
+ last_error = invalid_handle_error;
+ return 1;
+ }
+ handle->usage--;
+ if (!handle->usage) {
+ int error;
+
+ if (handle != handles)
+ last->next = handle->next;
+ else
+ handles = handle->next;
+ error = handle->type->lib_close(handle);
+ error += unload_deplibs(handle);
+ if (handle->filename)
+ lt_dlfree(handle->filename);
+ if (handle->name)
+ lt_dlfree(handle->name);
+ lt_dlfree(handle);
+ return error;
+ }
+ return 0;
+}
+
+lt_ptr_t
+lt_dlsym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ int lensym;
+ char lsym[LTDL_SYMBOL_LENGTH];
+ char *sym;
+ lt_ptr_t address;
+
+ if (!handle) {
+ last_error = invalid_handle_error;
+ return 0;
+ }
+ if (!symbol) {
+ last_error = symbol_error;
+ return 0;
+ }
+ lensym = strlen(symbol);
+ if (handle->type->sym_prefix)
+ lensym += strlen(handle->type->sym_prefix);
+ if (handle->name)
+ lensym += strlen(handle->name);
+ if (lensym + LTDL_SYMBOL_OVERHEAD < LTDL_SYMBOL_LENGTH)
+ sym = lsym;
+ else
+ sym = (char*) lt_dlmalloc(lensym + LTDL_SYMBOL_OVERHEAD + 1);
+ if (!sym) {
+ last_error = buffer_overflow_error;
+ return 0;
+ }
+ if (handle->name) {
+ /* this is a libtool module */
+ if (handle->type->sym_prefix) {
+ strcpy(sym, handle->type->sym_prefix);
+ strcat(sym, handle->name);
+ } else
+ strcpy(sym, handle->name);
+ strcat(sym, "_LTX_");
+ strcat(sym, symbol);
+ /* try "modulename_LTX_symbol" */
+ address = handle->type->find_sym(handle, sym);
+ if (address) {
+ if (sym != lsym)
+ lt_dlfree(sym);
+ return address;
+ }
+ }
+ /* otherwise try "symbol" */
+ if (handle->type->sym_prefix) {
+ strcpy(sym, handle->type->sym_prefix);
+ strcat(sym, symbol);
+ } else
+ strcpy(sym, symbol);
+ address = handle->type->find_sym(handle, sym);
+ if (sym != lsym)
+ lt_dlfree(sym);
+ return address;
+}
+
+const char *
+lt_dlerror LTDL_PARAMS((void))
+{
+ const char *error = last_error;
+
+ last_error = 0;
+ return error;
+}
+
+int
+lt_dladdsearchdir (search_dir)
+ const char *search_dir;
+{
+ if (!search_dir || !strlen(search_dir))
+ return 0;
+ if (!user_search_path) {
+ user_search_path = strdup(search_dir);
+ if (!user_search_path) {
+ last_error = memory_error;
+ return 1;
+ }
+ } else {
+ char *new_search_path = (char*)
+ lt_dlmalloc(strlen(user_search_path) +
+ strlen(search_dir) + 2); /* ':' + '\0' == 2 */
+ if (!new_search_path) {
+ last_error = memory_error;
+ return 1;
+ }
+ strcpy(new_search_path, user_search_path);
+ strcat(new_search_path, ":");
+ strcat(new_search_path, search_dir);
+ lt_dlfree(user_search_path);
+ user_search_path = new_search_path;
+ }
+ return 0;
+}
+
+int
+lt_dlsetsearchpath (search_path)
+ const char *search_path;
+{
+ if (user_search_path)
+ lt_dlfree(user_search_path);
+ user_search_path = 0; /* reset the search path */
+ if (!search_path || !strlen(search_path))
+ return 0;
+ user_search_path = strdup(search_path);
+ if (!user_search_path)
+ return 1;
+ return 0;
+}
+
+const char *
+lt_dlgetsearchpath LTDL_PARAMS((void))
+{
+ return user_search_path;
+}
diff --git a/libltdl/ltdl.h b/libltdl/ltdl.h
new file mode 100644
index 00000000..bebbc6d2
--- /dev/null
+++ b/libltdl/ltdl.h
@@ -0,0 +1,91 @@
+/* ltdl.h -- generic dlopen functions
+ Copyright (C) 1998-1999 Free Software Foundation, Inc.
+ Originally by Thomas Tanner <tanner@gmx.de>
+ This file is part of GNU Libtool.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+As a special exception to the GNU Library General Public License,
+if you distribute this file as part of a program that uses GNU libtool
+to create libraries and programs, you may include it under the same
+distribution terms that you use for the rest of that program.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free
+Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Only include this header file once. */
+#ifndef _LTDL_H_
+#define _LTDL_H_ 1
+
+/* __BEGIN_DECLS should be used at the beginning of your declarations,
+ so that C++ compilers don't mangle their names. Use __END_DECLS at
+ the end of C declarations. */
+#undef __BEGIN_DECLS
+#undef __END_DECLS
+#ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+#else
+# define __BEGIN_DECLS /* empty */
+# define __END_DECLS /* empty */
+#endif
+
+/* LTDL_PARAMS is a macro used to wrap function prototypes, so that compilers
+ that don't understand ANSI C prototypes still work, and ANSI C
+ compilers can issue warnings about type mismatches. */
+#undef LTDL_PARAMS
+#undef lt_ptr_t
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus)
+# define LTDL_PARAMS(protos) protos
+# define lt_ptr_t void*
+#else
+# define LTDL_PARAMS(protos) ()
+# define lt_ptr_t char*
+#endif
+
+#include <stdlib.h>
+
+#ifdef _LTDL_COMPILE_
+typedef struct lt_dlhandle_t *lt_dlhandle;
+#else
+typedef lt_ptr_t lt_dlhandle;
+#endif
+
+typedef struct {
+ const char *name;
+ lt_ptr_t address;
+} lt_dlsymlist;
+
+__BEGIN_DECLS
+extern int lt_dlinit LTDL_PARAMS((void));
+extern int lt_dlpreload LTDL_PARAMS((const lt_dlsymlist *preloaded));
+extern int lt_dlpreload_default LTDL_PARAMS((const lt_dlsymlist *preloaded));
+extern int lt_dlexit LTDL_PARAMS((void));
+extern lt_dlhandle lt_dlopen LTDL_PARAMS((const char *filename));
+extern lt_dlhandle lt_dlopenext LTDL_PARAMS((const char *filename));
+extern int lt_dlclose LTDL_PARAMS((lt_dlhandle handle));
+extern lt_ptr_t lt_dlsym LTDL_PARAMS((lt_dlhandle handle, const char *name));
+extern const char *lt_dlerror LTDL_PARAMS((void));
+extern int lt_dladdsearchdir LTDL_PARAMS((const char *search_dir));
+extern int lt_dlsetsearchpath LTDL_PARAMS((const char *search_path));
+extern const char *lt_dlgetsearchpath LTDL_PARAMS((void));
+
+extern const lt_dlsymlist lt_preloaded_symbols[];
+#define LTDL_SET_PRELOADED_SYMBOLS() lt_dlpreload_default(lt_preloaded_symbols)
+
+extern lt_ptr_t (*lt_dlmalloc)LTDL_PARAMS((size_t size));
+extern void (*lt_dlfree)LTDL_PARAMS((lt_ptr_t ptr));
+
+__END_DECLS
+
+#endif /* !_LTDL_H_ */
diff --git a/libltdl/stamp-h.in b/libltdl/stamp-h.in
new file mode 100644
index 00000000..9788f702
--- /dev/null
+++ b/libltdl/stamp-h.in
@@ -0,0 +1 @@
+timestamp
diff --git a/ltconfig b/ltconfig
new file mode 100755
index 00000000..2347e694
--- /dev/null
+++ b/ltconfig
@@ -0,0 +1,1512 @@
+#! /bin/sh
+
+# ltconfig - Create a system-specific libtool.
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# A lot of this script is taken from autoconf-2.10.
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+echo=echo
+if test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then :
+else
+ # The Solaris and AIX default echo program unquotes backslashes.
+ # This makes it impossible to quote backslashes using
+ # echo "$something" | sed 's/\\/\\\\/g'
+ # So, we emulate echo with printf '%s\n'
+ echo="printf %s\\n"
+ if test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then :
+ else
+ # Oops. We have no working printf. Try to find a not-so-buggy echo.
+ echo=echo
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH /usr/ucb; do
+ if test -f $dir/echo && test "X`$dir/echo '\t'`" = 'X\t'; then
+ echo="$dir/echo"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ fi
+fi
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'
+
+# The name of this program.
+progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'`
+
+# Constants:
+PROGRAM=ltconfig
+PACKAGE=libtool
+VERSION=1.2
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5'
+ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5'
+rm="rm -f"
+
+help="Try \`$progname --help' for more information."
+
+# Global variables:
+can_build_shared=yes
+enable_shared=yes
+# All known linkers require a `.a' archive for static linking.
+enable_static=yes
+ltmain=
+silent=
+srcdir=
+ac_config_guess=
+ac_config_sub=
+host=
+nonopt=
+verify_host=yes
+with_gcc=no
+with_gnu_ld=no
+
+old_AR="$AR"
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+old_CPPFLAGS="$CPPFLAGS"
+old_LD="$LD"
+old_LN_S="$LN_S"
+old_NM="$NM"
+old_RANLIB="$RANLIB"
+
+# Parse the command line options.
+args=
+prev=
+for option
+do
+ case "$option" in
+ -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ eval "$prev=\$option"
+ prev=
+ continue
+ fi
+
+ case "$option" in
+ --help) cat <<EOM
+Usage: $progname [OPTION]... LTMAIN [HOST]
+
+Generate a system-specific libtool script.
+
+ --disable-shared do not build shared libraries
+ --disable-static do not build static libraries
+ --help display this help and exit
+ --no-verify do not verify that HOST is a valid host type
+ --quiet same as \`--silent'
+ --silent do not print informational messages
+ --srcdir=DIR find \`config.guess' in DIR
+ --version output version information and exit
+ --with-gcc assume that the GNU C compiler will be used
+ --with-gnu-ld assume that the C compiler uses the GNU linker
+
+LTMAIN is the \`ltmain.sh' shell script fragment that provides basic libtool
+functionality.
+
+HOST is the canonical host system name [default=guessed].
+EOM
+ exit 0
+ ;;
+
+ --disable-shared) enable_shared=no ;;
+
+ --disable-static) enable_static=no ;;
+
+ --quiet | --silent) silent=yes ;;
+
+ --srcdir) prev=srcdir ;;
+ --srcdir=*) srcdir="$optarg" ;;
+
+ --no-verify) verify_host=no ;;
+
+ --version) echo "$PROGRAM (GNU $PACKAGE) $VERSION"; exit 0 ;;
+
+ --with-gcc) with_gcc=yes ;;
+ --with-gnu-ld) with_gnu_ld=yes ;;
+
+ -*)
+ echo "$progname: unrecognized option \`$option'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ if test -z "$ltmain"; then
+ ltmain="$option"
+ elif test -z "$host"; then
+# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1
+# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then
+# echo "$progname: warning \`$option' is not a valid host type" 1>&2
+# fi
+ host="$option"
+ else
+ echo "$progname: too many arguments" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+done
+
+if test -z "$ltmain"; then
+ echo "$progname: you must specify a LTMAIN file" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+if test -f "$ltmain"; then :
+else
+ echo "$progname: \`$ltmain' does not exist" 1>&2
+ echo "$help" 1>&2
+ exit 1
+fi
+
+# Quote any args containing shell metacharacters.
+ltconfig_args=
+for arg
+do
+ case "$arg" in
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ltconfig_args="$ltconfig_args '$arg'" ;;
+ *) ltconfig_args="$ltconfig_args $arg" ;;
+ esac
+done
+
+# A relevant subset of AC_INIT.
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 5 compiler messages saved in config.log
+# 6 checking for... messages and results
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>>./config.log
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+if test -z "$srcdir"; then
+ # Assume the source directory is the same one as the path to ltmain.sh.
+ srcdir=`$echo "$ltmain" | $Xsed -e 's%/[^/]*$%%'`
+ test "$srcdir" = "$ltmain" && srcdir=.
+fi
+
+trap "$rm conftest*; exit 1" 1 2 15
+if test "$verify_host" = yes; then
+ # Check for config.guess and config.sub.
+ ac_aux_dir=
+ for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/config.guess; then
+ ac_aux_dir=$ac_dir
+ break
+ fi
+ done
+ if test -z "$ac_aux_dir"; then
+ echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+ ac_config_guess=$ac_aux_dir/config.guess
+ ac_config_sub=$ac_aux_dir/config.sub
+
+ # Make sure we can run config.sub.
+ if $ac_config_sub sun4 >/dev/null 2>&1; then :
+ else
+ echo "$progname: cannot run $ac_config_sub" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi
+
+ echo $ac_n "checking host system type""... $ac_c" 1>&6
+
+ host_alias=$host
+ case "$host_alias" in
+ "")
+ if host_alias=`$ac_config_guess`; then :
+ else
+ echo "$progname: cannot guess host type; you must specify one" 1>&2
+ echo "$help" 1>&2
+ exit 1
+ fi ;;
+ esac
+ host=`$ac_config_sub $host_alias`
+ echo "$ac_t$host" 1>&6
+
+ # Make sure the host verified.
+ test -z "$host" && exit 1
+
+elif test -z "$host"; then
+ echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2
+ echo "$help" 1>&2
+ exit 1
+else
+ host_alias=$host
+fi
+
+# Transform linux* to *-*-linux-gnu*, to support old configure scripts.
+case "$host_os" in
+linux-gnu*) ;;
+linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
+esac
+
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+
+case "$host_os" in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "${COLLECT_NAMES+set}" != set; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR cru $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+# Set a sane default for `AR'.
+test -z "$AR" && AR=ar
+
+# If RANLIB is not set, then run the test.
+if test "${RANLIB+set}" != "set"; then
+ result=no
+
+ echo $ac_n "checking for ranlib... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/ranlib; then
+ RANLIB="ranlib"
+ result="ranlib"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ echo "$ac_t$result" 1>&6
+fi
+
+if test -n "$RANLIB"; then
+ old_archive_cmds="$old_archive_cmds;\$RANLIB \$oldlib"
+ old_postinstall_cmds="\$RANLIB \$oldlib;$old_postinstall_cmds"
+fi
+
+# Check to see if we are using GCC.
+if test "$with_gcc" != yes || test -z "$CC"; then
+ # If CC is not set, then try to find GCC or a usable CC.
+ if test -z "$CC"; then
+ echo $ac_n "checking for gcc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ for dir in $PATH; do
+ IFS="$save_ifs"
+ test -z "$dir" && dir=.
+ if test -f $dir/gcc; then
+ CC="gcc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+ fi
+
+ # Not "gcc", so try "cc", rejecting "/usr/ucb/cc".
+ if test -z "$CC"; then
+ echo $ac_n "checking for cc... $ac_c" 1>&6
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}:"
+ cc_rejected=no
+ for dir in $PATH; do
+ test -z "$dir" && dir=.
+ if test -f $dir/cc; then
+ if test "$dir/cc" = "/usr/ucb/cc"; then
+ cc_rejected=yes
+ continue
+ fi
+ CC="cc"
+ break
+ fi
+ done
+ IFS="$save_ifs"
+ if test $cc_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same name, so the bogon will be chosen
+ # first if we set CC to just the name; use the full file name.
+ shift
+ set dummy "$dir/cc" "$@"
+ shift
+ CC="$@"
+ fi
+ fi
+
+ if test -n "$CC"; then
+ echo "$ac_t$CC" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$CC"; then
+ echo "$progname: error: no acceptable cc found in \$PATH" 1>&2
+ exit 1
+ fi
+ fi
+
+ # Now see if the compiler is really GCC.
+ with_gcc=no
+ echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6
+ echo "$progname:424: checking whether we are using GNU C" >&5
+
+ $rm conftest.c
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+ if { ac_try='${CC-cc} -E conftest.c'; { (eval echo $progname:432: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ with_gcc=yes
+ fi
+ $rm conftest.c
+ echo "$ac_t$with_gcc" 1>&6
+fi
+
+# Allow CC to be a program name with arguments.
+set dummy $CC
+compiler="$2"
+
+echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6
+pic_flag=
+special_shlib_compile_flags=
+wl=
+link_static_flag=
+no_builtin_flag=
+
+if test "$with_gcc" = yes; then
+ wl='-Wl,'
+ link_static_flag='-static'
+ no_builtin_flag=' -fno-builtin'
+
+ case "$host_os" in
+ aix3* | aix4* | irix5* | irix6* | osf3* | osf4*)
+ # PIC is the default for these OSes.
+ ;;
+ os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+ amigaos*)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ pic_flag='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ *)
+ pic_flag='-fPIC'
+ ;;
+ esac
+else
+ # PORTME Check for PIC flags for the system compiler.
+ case "$host_os" in
+ aix3* | aix4*)
+ # All AIX code is PIC.
+ link_static_flag='-bnso -bI:/lib/syscalls.exp'
+ ;;
+
+ hpux9* | hpux10*)
+ # Is there a better link_static_flag that works with the bundled CC?
+ wl='-Wl,'
+ link_static_flag="${wl}-a ${wl}archive"
+ pic_flag='+Z'
+ ;;
+
+ irix5* | irix6*)
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ # PIC (with -KPIC) is the default.
+ ;;
+
+ os2*)
+ # We can build DLLs from non-PIC.
+ ;;
+
+ osf3* | osf4*)
+ # All OSF/1 code is PIC.
+ wl='-Wl,'
+ link_static_flag='-non_shared'
+ ;;
+
+ sco3.2v5*)
+ pic_flag='-Kpic'
+ link_static_flag='-dn'
+ special_shlib_compile_flags='-belf'
+ ;;
+
+ solaris2*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ sunos4*)
+ pic_flag='-PIC'
+ link_static_flag='-Bstatic'
+ wl='-Qoption ld '
+ ;;
+
+ sysv4.2uw2*)
+ pic_flag='-KPIC'
+ link_static_flag='-Bstatic'
+ wl='-Wl,'
+ ;;
+
+ uts4*)
+ pic_flag='-pic'
+ link_static_flag='-Bstatic'
+ ;;
+
+ *)
+ can_build_shared=no
+ ;;
+ esac
+fi
+
+if test -n "$pic_flag"; then
+ echo "$ac_t$pic_flag" 1>&6
+
+ # Check to make sure the pic_flag actually works.
+ echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6
+ $rm conftest*
+ echo > conftest.c
+ save_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $pic_flag -DPIC"
+ echo "$progname:547: checking if $compiler PIC flag $pic_flag works" >&5
+ if { (eval echo $progname:548: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then
+ # Append any warnings to the config.log.
+ cat conftest.err 1>&5
+
+ # On HP-UX, both CC and GCC only warn that PIC is supported... then they
+ # create non-PIC objects. So, if there were any warnings, we assume that
+ # PIC is not supported.
+ if test -s conftest.err; then
+ echo "$ac_t"no 1>&6
+ can_build_shared=no
+ pic_flag=
+ else
+ echo "$ac_t"yes 1>&6
+ pic_flag=" $pic_flag"
+ fi
+ else
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ can_build_shared=no
+ pic_flag=
+ echo "$ac_t"no 1>&6
+ fi
+ CFLAGS="$save_CFLAGS"
+ $rm conftest*
+else
+ echo "$ac_t"none 1>&6
+fi
+
+# Check for any special shared library compilation flags.
+if test -n "$special_shlib_compile_flags"; then
+ echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2
+ if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then :
+ else
+ echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2
+ can_build_shared=no
+ fi
+fi
+
+echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6
+$rm conftest*
+echo 'main(){return(0);}' > conftest.c
+save_LDFLAGS="$LDFLAGS"
+LDFLAGS="$LDFLAGS $link_static_flag"
+echo "$progname:591: checking if $compiler static flag $link_static_flag works" >&5
+if { (eval echo $progname:592: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ echo "$ac_t$link_static_flag" 1>&6
+else
+ echo "$ac_t"none 1>&6
+ link_static_flag=
+fi
+LDFLAGS="$save_LDFLAGS"
+$rm conftest*
+
+if test -z "$LN_S"; then
+ # Check to see if we can use ln -s, or we need hard links.
+ echo $ac_n "checking whether ln -s works... $ac_c" 1>&6
+ $rm conftestdata
+ if ln -s X conftestdata 2>/dev/null; then
+ $rm conftestdata
+ LN_S="ln -s"
+ else
+ LN_S=ln
+ fi
+ if test "$LN_S" = "ln -s"; then
+ echo "$ac_t"yes 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+fi
+
+# Make sure LD is an absolute path.
+if test -z "$LD"; then
+ ac_prog=ld
+ if test "$with_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6
+ echo "$progname:624: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ /* | [A-Za-z]:\\*)
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we are not using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+ elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld... $ac_c" 1>&6
+ echo "$progname:642: checking for GNU ld" >&5
+ else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+ echo "$progname:645: checking for non-GNU ld" >&5
+ fi
+
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog"; then
+ LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ fi
+
+ if test -n "$LD"; then
+ echo "$ac_t$LD" 1>&6
+ else
+ echo "$ac_t"no 1>&6
+ fi
+
+ if test -z "$LD"; then
+ echo "$progname: error: no acceptable ld found in \$PATH" 1>&2
+ exit 1
+ fi
+fi
+
+# Check to see if it really is or is not GNU ld.
+echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6
+# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+echo "$ac_t$with_gnu_ld" 1>&6
+
+# See if the linker supports building shared libraries.
+echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6
+
+allow_undefined_flag=
+no_undefined_flag=
+archive_cmds=
+old_archive_from_new_cmds=
+export_dynamic_flag_spec=
+hardcode_libdir_flag_spec=
+hardcode_libdir_separator=
+hardcode_direct=no
+hardcode_minus_L=no
+hardcode_shlibpath_var=unsupported
+runpath_var=
+
+case "$host_os" in
+amigaos* | sunos4*)
+ # On these operating systems, we should treat GNU ld like the system ld.
+ gnu_ld_acts_native=yes
+ ;;
+*)
+ gnu_ld_acts_native=no
+ ;;
+esac
+
+ld_shlibs=yes
+if test "$with_gnu_ld" = yes && test "$gnu_ld_acts_native" != yes; then
+
+ # See if GNU ld supports shared libraries.
+ if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared ${wl}-soname $wl$soname -o $lib$libobjs'
+ runpath_var=LD_RUN_PATH
+ ld_shlibs=yes
+ else
+ ld_shlibs=no
+ fi
+
+ if test "$ld_shlibs" = yes; then
+ hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ fi
+else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case "$host_os" in
+ aix3*)
+ allow_undefined_flag=unsupported
+ archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '\''s/.* //'\'' > $lib.exp;$LD -o $objdir/$soname$libobjs -bE:$lib.exp -T512 -H512 -bM:SRE;$AR cru $lib $objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$with_gcc" = yes && test -z "$link_static_flag"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix4*)
+ allow_undefined_flag=unsupported
+ archive_cmds='$NM$libobjs | $global_symbol_pipe | sed '\''s/.* //'\'' > $lib.exp;$CC -o $objdir/$soname$libobjs ${wl}-bE:$lib.exp ${wl}-bM:SRE ${wl}-bnoentry;$AR cru $lib $objdir/$soname'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ ;;
+
+ amigaos*)
+ archive_cmds='$rm $objdir/a2ixlibrary.data;$echo "#define NAME $libname" > $objdir/a2ixlibrary.data;$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data;$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data;$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data;$AR cru $lib$libobjs;$RANLIB $lib;(cd $objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib$libobjs /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2*)
+ archive_cmds='$LD -Bshareable -o $lib$libobjs'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3, at last, uses gcc -shared to do shared libraries.
+ freebsd3*)
+ archive_cmds='$CC -shared -o $lib$libobjs'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ archive_cmds='$rm $objdir/$soname;$LD -b +s +b $install_libdir -o $objdir/$soname$libobjs;mv $objdir/$soname $lib'
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ archive_cmds='$LD -b +h $soname +s +b $install_libdir -o $lib$libobjs'
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ irix5* | irix6*)
+ archive_cmds='$LD -shared -o $lib -soname $soname -set_version $verstring$libobjs'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ ;;
+
+ netbsd*)
+ # Tested with NetBSD 1.2 ld
+ archive_cmds='$LD -Bshareable -o $lib$libobjs'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ openbsd*)
+ archive_cmds='$LD -Bshareable -o $lib$libobjs'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def;$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def;$echo DATA >> $objdir/$libname.def;$echo " SINGLE NONSHARED" >> $objdir/$libname.def;$echo EXPORTS >> $objdir/$libname.def;emxexp$libobjs >> $objdir/$libname.def;$CC -Zdll -Zcrtdll -o $lib$libobjs $objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def'
+ ;;
+
+ osf3* | osf4*)
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$LD -shared${allow_undefined_flag} -o $lib -soname $soname -set_version $verstring$libobjs$deplibs'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ sco3.2v5*)
+ archive_cmds='$LD -G -o $lib$libobjs'
+ hardcode_direct=yes
+ ;;
+
+ solaris2*)
+ no_undefined_flag=' -z text'
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib$libobjs'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+
+ # Solaris 2 before 2.5 hardcodes -L paths.
+ case "$host_os" in
+ solaris2.[0-4]*)
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ if test "$with_gcc" = yes; then
+ archive_cmds='$CC -shared -o $lib$libobjs'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib$libobjs'
+ fi
+
+ if test "$with_gnu_ld" = yes; then
+ export_dynamic_flag_spec='${wl}-export-dynamic'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib$libobjs'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=no
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ can_build_shared=no
+ ;;
+ esac
+fi
+echo "$ac_t$ld_shlibs" 1>&6
+
+if test -z "$NM"; then
+ echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6
+ case "$NM" in
+ /* | [A-Za-z]:\\*) ;; # Let the user override the test with a path.
+ *)
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in /usr/ucb /usr/ccs/bin $PATH /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -B"
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ NM="$ac_dir/nm -p"
+ else
+ NM="$ac_dir/nm"
+ fi
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$NM" && NM=nm
+ ;;
+ esac
+ echo "$ac_t$NM" 1>&6
+fi
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRSTU]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Transform the above into a raw symbol and a C symbol.
+symxfrm='\1 \1'
+
+# Define system-specific variables.
+case "$host_os" in
+aix*)
+ symcode='[BCDTU]'
+ ;;
+irix*)
+ # Cannot use undefined symbols on IRIX because inlined functions mess us up.
+ symcode='[BCDEGRST]'
+ ;;
+solaris2*)
+ symcode='[BDTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then
+ symcode='[ABCDGISTUW]'
+fi
+
+# Write the raw and C identifiers.
+global_symbol_pipe="sed -n -e 's/^.* $symcode $sympat$/$symxfrm/p'"
+
+# Check to see that the pipe works correctly.
+pipe_works=no
+$rm conftest*
+cat > conftest.c <<EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(){}
+#ifdef __cplusplus
+}
+#endif
+main(){nm_test_var='a';nm_test_func();return(0);}
+EOF
+
+echo "$progname:971: checking if global_symbol_pipe works" >&5
+if { (eval echo $progname:972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.o; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { echo "$progname:975: eval \"$NM conftest.o | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.o | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then
+
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ wcout=`wc "$nlist" 2>/dev/null`
+ count=`$echo "X$wcout" | $Xsed -e 's/^[ ]*\([0-9][0-9]*\).*$/\1/'`
+ (test "$count" -ge 0) 2>/dev/null || count=-1
+ else
+ rm -f "$nlist"T
+ count=-1
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if egrep ' nm_test_var$' "$nlist" >/dev/null; then
+ if egrep ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<EOF > conftest.c
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+EOF
+ # Now generate the symbol file.
+ sed 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> conftest.c
+
+ cat <<EOF >> conftest.c
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+ char *name;
+ __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{
+EOF
+ sed 's/^\(.*\) \(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$nlist" >> conftest.c
+ cat <<\EOF >> conftest.c
+ {0, (__ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif
+EOF
+ # Now try linking the two files.
+ mv conftest.o conftestm.o
+ save_LIBS="$LIBS"
+ save_CFLAGS="$CFLAGS"
+ LIBS='conftestm.o'
+ CFLAGS="$CFLAGS$no_builtin_flag"
+ if { (eval echo $progname:1033: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then
+ pipe_works=yes
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+ fi
+ LIBS="$save_LIBS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $global_symbol_pipe" >&5
+ fi
+else
+ echo "$progname: failed program was:" >&5
+ cat conftest.c >&5
+fi
+$rm conftest*
+
+# Do not use the global_symbol_pipe unless it works.
+echo "$ac_t$pipe_works" 1>&6
+test "$pipe_works" = yes || global_symbol_pipe=
+
+# Check hardcoding attributes.
+echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" || \
+ test -n "$runpath_var"; then
+
+ # We can hardcode non-existant directories.
+ if test "$hardcode_direct" != no && \
+ test "$hardcode_minus_L" != no && \
+ test "$hardcode_shlibpath_var" != no; then
+
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+elif test "$hardcode_direct" != yes && \
+ test "$hardcode_minus_L" != yes && \
+ test "$hardcode_shlibpath_var" != yes; then
+ # We cannot hardcode anything.
+ hardcode_action=unsupported
+else
+ # We can only hardcode existing directories.
+ hardcode_action=relink
+fi
+echo "$ac_t$hardcode_action" 1>&6
+test "$hardcode_action" = unsupported && can_build_shared=no
+
+
+reload_flag=
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6
+# PORTME Some linker may need a different reload flag.
+reload_flag='-r'
+echo "$ac_t$reload_flag"
+test -n "$reload_flag" && reload_flag=" $reload_flag"
+
+# PORTME Fill in your ld.so characteristics
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+version_type=none
+dynamic_linker="$host_os ld.so"
+
+echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6
+case "$host_os" in
+aix3* | aix4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so.$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}.so.$major'
+ ;;
+
+amigaos*)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done'
+ ;;
+
+freebsd2* | freebsd3*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so.$versuffix $libname.so'
+ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+gnu*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so.$versuffix'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+hpux9* | hpux10*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ dynamic_linker="$host_os dld.sl"
+ version_type=sunos
+ shlibpath_var=SHLIB_PATH
+ library_names_spec='${libname}${release}.sl.$versuffix ${libname}${release}.sl.$major $libname.sl'
+ soname_spec='${libname}${release}.sl.$major'
+ # HP-UX runs *really* slowly unless shared libraries are mode 555.
+ postinstall_cmds='chmod 555 $lib'
+ ;;
+
+irix5* | irix6*)
+ version_type=osf
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so.$versuffix $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux-gnu*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+ soname_spec='${libname}${release}.so.$major'
+ finish_cmds='PATH="$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+
+ if test -f /lib/ld.so.1; then
+ dynamic_linker='GNU ld.so'
+ else
+ # Only the GNU ld.so supports shared libraries on MkLinux.
+ case "$host_cpu" in
+ powerpc*) dynamic_linker=no ;;
+ *) dynamic_linker='Linux ld.so' ;;
+ esac
+ fi
+ ;;
+
+netbsd* | openbsd*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so.$versuffix'
+ finish_cmds='PATH="$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+os2*)
+ libname_spec='$name'
+ library_names_spec='$libname.dll $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4*)
+ version_type=osf
+ soname_spec='${libname}${release}.so'
+ library_names_spec='${libname}${release}.so.$versuffix $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sco3.2v5*)
+ version_type=osf
+ soname_spec='${libname}${release}.so.$major'
+ library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+solaris2*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+ soname_spec='${libname}${release}.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}.so.$versuffix'
+ finish_cmds='PATH="$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+sysv4.2uw2*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+ soname_spec='${libname}${release}.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major $libname.so'
+ soname_spec='${libname}${release}.so.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+echo "$ac_t$dynamic_linker"
+test "$dynamic_linker" = no && can_build_shared=no
+
+# Report the final consequences.
+echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6
+
+echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6
+test "$can_build_shared" = "no" && enable_shared=no
+
+# On AIX, shared libraries and static libraries use the same namespace, and
+# are all built from PIC.
+case "$host_os" in
+aix*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds;\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+esac
+
+echo "$ac_t$enable_shared" 1>&6
+
+# Make sure either enable_shared or enable_static is yes.
+test "$enable_shared" = yes || enable_static=yes
+
+echo "checking whether to build static libraries... $enable_static" 1>&6
+
+echo $ac_n "checking for objdir... $ac_c" 1>&6
+rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+echo "$ac_t$objdir" 1>&6
+
+# Copy echo and quote the copy, instead of the original, because it is
+# used later.
+ltecho="$echo"
+
+# Now quote all the things that may contain metacharacters.
+for var in ltecho old_CC old_CFLAGS old_CPPFLAGS old_LD old_NM old_RANLIB \
+ old_LN_S AR CC LD LN_S NM reload_flag reload_cmds wl pic_flag \
+ link_static_flag no_builtin_flag export_dynamic_flag_spec \
+ libname_spec library_names_spec soname_spec RANLIB \
+ old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \
+ old_postuninstall_cmds archive_cmds postinstall_cmds postuninstall_cmds \
+ allow_undefined_flag no_undefined_flag \
+ finish_cmds finish_eval global_symbol_pipe \
+ hardcode_libdir_flag_spec hardcode_libdir_separator; do
+
+ case "$var" in
+ reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \
+ old_postinstall_cmds | old_postuninstall_cmds | archive_cmds | \
+ postinstall_cmds | postuninstall_cmds | finish_cmds)
+ # Double-quote double-evaled strings.
+ eval "$var=\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\"\`"
+ ;;
+ *)
+ eval "$var=\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`"
+ ;;
+ esac
+done
+
+ofile=libtool
+trap "$rm $ofile; exit 1" 1 2 15
+echo creating $ofile
+$rm $ofile
+cat <<EOF > $ofile
+#! /bin/sh
+
+# libtool - Provide generalized library-building support services.
+# Generated automatically by $PROGRAM - GNU $PACKAGE $VERSION
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# This program was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# CC="$old_CC" CFLAGS="$old_CFLAGS" CPPFLAGS="$old_CPPFLAGS" \\
+# LD="$old_LD" NM="$old_NM" RANLIB="$old_RANLIB" LN_S="$old_LN_S" \\
+# $0$ltconfig_args
+#
+# Compiler and other test output produced by $progname, useful for
+# debugging $progname, is in ./config.log if it exists.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi
+
+# An echo program that does not interpret backslashes.
+echo="$ltecho"
+
+# The version of $progname that generated this script.
+LTCONFIG_VERSION="$VERSION"
+
+# Shell to use when invoking shell scripts.
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Whether or not to build libtool libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build old-style libraries.
+build_old_libs=$enable_static
+
+# The host system.
+host_alias="$host_alias"
+host="$host"
+
+# The archiver.
+AR="$AR"
+
+# The default C compiler.
+CC="$CC"
+
+# The linker used to build libraries.
+LD="$LD"
+
+# Whether we need hard or soft links.
+LN_S="$LN_S"
+
+# A BSD-compatible nm program.
+NM="$NM"
+
+# The name of the directory that contains temporary libtool files.
+objdir="$objdir"
+
+# How to create reloadable object files.
+reload_flag="$reload_flag"
+reload_cmds="$reload_cmds"
+
+# How to pass a linker flag through the compiler.
+wl="$wl"
+
+# Additional compiler flags for building library objects.
+pic_flag="$pic_flag"
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag="$link_static_flag"
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag="$no_builtin_flag"
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec="$export_dynamic_flag_spec"
+
+# Library versioning type.
+version_type=$version_type
+
+# Format of library name prefix.
+libname_spec="$libname_spec"
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec="$library_names_spec"
+
+# The coded name of the library, if different from the real name.
+soname_spec="$soname_spec"
+
+# Commands used to build and install an old-style archive.
+RANLIB="$RANLIB"
+old_archive_cmds="$old_archive_cmds"
+old_postinstall_cmds="$old_postinstall_cmds"
+old_postuninstall_cmds="$old_postuninstall_cmds"
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds="$old_archive_from_new_cmds"
+
+# Commands used to build and install a shared archive.
+archive_cmds="$archive_cmds"
+postinstall_cmds="$postinstall_cmds"
+postuninstall_cmds="$postuninstall_cmds"
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag="$allow_undefined_flag"
+
+# Flag that forces no undefined symbols.
+no_undefined_flag="$no_undefined_flag"
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds="$finish_cmds"
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval="$finish_eval"
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="$global_symbol_pipe"
+
+# This is the shared library runtime path variable.
+runpath_var=$runpath_var
+
+# This is the shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec="$hardcode_libdir_flag_spec"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator="$hardcode_libdir_separator"
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+EOF
+
+case "$host_os" in
+aix3*)
+ cat <<\EOF >> $ofile
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "${COLLECT_NAMES+set}" != set; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+
+EOF
+ ;;
+esac
+
+# Append the ltmain.sh script.
+cat "$ltmain" >> $ofile || (rm -f $ofile; exit 1)
+
+chmod +x $ofile
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/ltmain.sh b/ltmain.sh
new file mode 100644
index 00000000..e9350b3f
--- /dev/null
+++ b/ltmain.sh
@@ -0,0 +1,2453 @@
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1998 Free Software Foundation, Inc.
+# Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# 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 2 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.2
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+ echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ echo "$modename: not configured to build any kind of library" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+ arg="$1"
+ shift
+
+ case "$arg" in
+ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ execute_dlfiles)
+ eval "$prev=\"\$$prev \$arg\""
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
+ prev=
+ prevopt=
+ continue
+ fi
+
+ # Have we seen a non-optional argument yet?
+ case "$arg" in
+ --help)
+ show_help=yes
+ ;;
+
+ --version)
+ echo "$PROGRAM (GNU $PACKAGE) $VERSION"
+ exit 0
+ ;;
+
+ --dry-run | -n)
+ run=:
+ ;;
+
+ --features)
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+ exit 0
+ ;;
+
+ --finish) mode="finish" ;;
+
+ --mode) prevopt="--mode" prev=mode ;;
+ --mode=*) mode="$optarg" ;;
+
+ --quiet | --silent)
+ show=:
+ ;;
+
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
+ -*)
+ $echo "$modename: unrecognized option \`$arg'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ nonopt="$arg"
+ break
+ ;;
+ esac
+done
+
+if test -n "$prevopt"; then
+ $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+fi
+
+if test -z "$show_help"; then
+
+ # Infer the operation mode.
+ if test -z "$mode"; then
+ case "$nonopt" in
+ *cc | *++ | gcc* | *-gcc*)
+ mode=link
+ for arg
+ do
+ case "$arg" in
+ -c)
+ mode=compile
+ break
+ ;;
+ esac
+ done
+ ;;
+ *db | *dbx)
+ mode=execute
+ ;;
+ *install*|cp|mv)
+ mode=install
+ ;;
+ *rm)
+ mode=uninstall
+ ;;
+ *)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
+ # Just use the default operation mode.
+ if test -z "$mode"; then
+ if test -n "$nonopt"; then
+ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+ else
+ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+ fi
+ fi
+ ;;
+ esac
+ fi
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$modename --help --mode=$mode' for more information."
+
+ # These modes are in order of execution frequency so that they run quickly.
+ case "$mode" in
+ # libtool compile mode
+ compile)
+ modename="$modename: compile"
+ # Get the compilation command and the source file.
+ base_compile=
+ lastarg=
+ srcfile="$nonopt"
+ suppress_output=
+
+ for arg
+ do
+ # Accept any command-line options.
+ case "$arg" in
+ -o)
+ $echo "$modename: you cannot specify the output filename with \`-o'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ -static)
+ build_libtool_libs=no
+ build_old_libs=yes
+ continue
+ ;;
+ esac
+
+ # Accept the current argument as the source file.
+ lastarg="$srcfile"
+ srcfile="$arg"
+
+ # Aesthetically quote the previous argument.
+
+ # Backslashify any backslashes, double quotes, and dollar signs.
+ # These are the only characters that are still specially
+ # interpreted inside of double-quoted scrings.
+ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly in scan
+ # sets, so we specify it separately.
+ case "$lastarg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ lastarg="\"$lastarg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ done
+
+ # Get the name of the library object.
+ libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+
+ # Recognize several different file suffixes.
+ xform='[cCFSfms]'
+ case "$libobj" in
+ *.ada) xform=ada ;;
+ *.adb) xform=adb ;;
+ *.ads) xform=ads ;;
+ *.asm) xform=asm ;;
+ *.c++) xform=c++ ;;
+ *.cc) xform=cc ;;
+ *.cpp) xform=cpp ;;
+ *.cxx) xform=cxx ;;
+ *.f90) xform=f90 ;;
+ *.for) xform=for ;;
+ esac
+
+ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+ case "$libobj" in
+ *.lo) obj=`$echo "X$libobj" | $Xsed -e 's/\.lo$/.o/'` ;;
+ *)
+ $echo "$modename: cannot determine name of library object from \`$srcfile'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$base_compile"; then
+ $echo "$modename: you must specify a compilation command" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ $run $rm $obj $libobj
+ trap "$run $rm $obj $libobj; exit 1" 1 2 15
+ else
+ $run $rm $libobj
+ trap "$run $rm $libobj; exit 1" 1 2 15
+ fi
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ $show "$base_compile$pic_flag -DPIC $srcfile"
+ if $run eval "$base_compile\$pic_flag -DPIC \$srcfile"; then :
+ else
+ test -n "$obj" && $run $rm $obj
+ exit 1
+ fi
+
+ # If we have no pic_flag, then copy the object into place and finish.
+ if test -z "$pic_flag"; then
+ $show "$LN_S $obj $libobj"
+ $run $LN_S $obj $libobj
+ exit $?
+ fi
+
+ # Just move the object, then go on to compile the next one
+ $show "$mv $obj $libobj"
+ $run $mv $obj $libobj || exit 1
+
+ # Allow error messages only from the first compilation.
+ suppress_output=' >/dev/null 2>&1'
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ # Suppress compiler output if we already did a PIC compilation.
+ $show "$base_compile $srcfile$suppress_output"
+ if $run eval "$base_compile \$srcfile$suppress_output"; then :
+ else
+ $run $rm $obj $libobj
+ exit 1
+ fi
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we do not
+ # accidentally link it into a program.
+ if test "$build_libtool_libs" != yes; then
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > \$libobj" || exit $?
+ fi
+
+ exit 0
+ ;;
+
+ # libtool link mode
+ link)
+ modename="$modename: link"
+ CC="$nonopt"
+ allow_undefined=yes
+ compile_command="$CC"
+ finalize_command="$CC"
+
+ compile_shlibpath=
+ finalize_shlibpath=
+ deplibs=
+ dlfiles=
+ dlprefiles=
+ export_dynamic=no
+ hardcode_libdirs=
+ libobjs=
+ link_against_libtool_libs=
+ ltlibs=
+ objs=
+ prev=
+ prevarg=
+ release=
+ rpath=
+ perm_rpath=
+ temp_rpath=
+ vinfo=
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case "$arg" in
+ -all-static | -static)
+ if test "X$arg" = "X-all-static" && test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+ fi
+ build_libtool_libs=no
+ build_old_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ for arg
+ do
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ output)
+ compile_command="$compile_command @OUTPUT@"
+ finalize_command="$finalize_command @OUTPUT@"
+ ;;
+ esac
+
+ case "$prev" in
+ dlfiles|dlprefiles)
+ case "$arg" in
+ *.la | *.lo) ;; # We handle these cases below.
+ *)
+ dlprefiles="$dlprefiles $arg"
+ test "$prev" = dlfiles && dlfiles="$dlfiles $arg"
+ prev=
+ ;;
+ esac
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath)
+ rpath="$rpath $arg"
+ prev=
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi
+
+ prevarg="$arg"
+
+ case "$arg" in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ if test "$export_dynamic" != yes; then
+ export_dynamic=yes
+ if test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ else
+ arg=
+ fi
+
+ # Add the symbol object into the linking commands.
+ compile_command="$compile_command @SYMFILE@"
+ finalize_command="$finalize_command @SYMFILE@"
+ fi
+ ;;
+
+ -L*)
+ dir=`$echo "X$arg" | $Xsed -e 's%^-L\(.*\)$%\1%'`
+ case "$dir" in
+ /* | [A-Za-z]:\\*)
+ # Add the corresponding hardcode_libdir_flag, if it is not identical.
+ ;;
+ *)
+ $echo "$modename: \`-L$dir' cannot specify a relative directory" 1>&2
+ exit 1
+ ;;
+ esac
+ deplibs="$deplibs $arg"
+ ;;
+
+ -l*) deplibs="$deplibs $arg" ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -static)
+ # If we have no pic_flag, then this is the same as -all-static.
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+
+ *.o | *.a)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A library object.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test "$build_libtool_libs" = yes; then
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e 's/\.lo$/\.o/'`
+ prev=
+ fi
+ libobjs="$libobjs $arg"
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ dlname=
+ libdir=
+ library_names=
+ old_library=
+
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $arg | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+
+ # If there is no directory component, then add one.
+ case "$arg" in
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
+ esac
+
+ if test -z "$libdir"; then
+ $echo "$modename: \`$arg' contains no -rpath information" 1>&2
+ exit 1
+ fi
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+
+ if test -z "$linklib"; then
+ $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Find the relevant object directory and library name.
+ name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+ dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$arg"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test -z "$dlname"; then
+ # If there is no dlname, we need to preload.
+ prev=dlprefiles
+ else
+ # We should not create a dependency on this library, but we
+ # may need any libraries it requires.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ prev=
+ continue
+ fi
+ fi
+
+ # The library was specified with -dlpreopen.
+ if test "$prev" = dlprefiles; then
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ dlprefiles="$dlprefiles $dir/$old_library"
+ else
+ dlprefiles="$dlprefiles $dir/$linklib"
+ fi
+ prev=
+ fi
+
+ if test "$build_libtool_libs" = yes && test -n "$library_names"; then
+ link_against_libtool_libs="$link_against_libtool_libs $arg"
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
+
+ # This is the magic to use -rpath.
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ # Put the magic libdir with the hardcode flag.
+ hardcode_libdirs="$libdir"
+ libdir="@HARDCODE_LIBDIRS@"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ libdir=
+ fi
+ fi
+
+ if test -n "$libdir"; then
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ compile_command="$compile_command $flag"
+ finalize_command="$finalize_command $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ # Do the same for the permanent run path.
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+
+
+ case "$hardcode_action" in
+ immediate)
+ if test "$hardcode_direct" = no; then
+ compile_command="$compile_command $dir/$linklib"
+ elif test "$hardcode_minus_L" = no; then
+ compile_command="$compile_command -L$dir -l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ compile_shlibpath="$compile_shlibpath$dir:"
+ compile_command="$compile_command -l$name"
+ fi
+ ;;
+
+ relink)
+ # We need an absolute path.
+ case "$dir" in
+ /* | [A-Za-z]:\\*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2
+ exit 1
+ fi
+ dir="$absdir"
+ ;;
+ esac
+
+ if test "$hardcode_direct" = yes; then
+ compile_command="$compile_command $dir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ compile_command="$compile_command -L$dir -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ compile_shlibpath="$compile_shlibpath$dir:"
+ compile_command="$compile_command -l$name"
+ fi
+ ;;
+
+ *)
+ $echo "$modename: \`$hardcode_action' is an unknown hardcode action" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes; then
+ finalize_command="$finalize_command $libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ finalize_command="$finalize_command -L$libdir -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ finalize_shlibpath="$finalize_shlibpath$libdir:"
+ finalize_command="$finalize_command -l$name"
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ finalize_command="$finalize_command -L$libdir -l$name"
+ fi
+ else
+ # Transform directly to old archives if we don't build new libraries.
+ if test -n "$pic_flag" && test -z "$old_library"; then
+ $echo "$modename: cannot find static library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_command="$compile_command $dir/$linklib"
+ finalize_command="$finalize_command $dir/$linklib"
+ else
+ compile_command="$compile_command -L$dir -l$name"
+ finalize_command="$finalize_command -L$dir -l$name"
+ fi
+ fi
+
+ # Add in any libraries that this one depends upon.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+ esac
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+ done
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$vinfo" && test -n "$release"; then
+ $echo "$modename: you cannot specify both \`-version-info' and \`-release'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ oldlib=
+ oldobjs=
+ case "$output" in
+ "")
+ $echo "$modename: you must specify an output file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ */* | *\\*)
+ $echo "$modename: output file \`$output' must have no directory components" 1>&2
+ exit 1
+ ;;
+
+ *.a)
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ build_old_libs=yes
+ oldlib="$output"
+ $show "$rm $oldlib"
+ $run $rm $oldlib
+ ;;
+
+ *.la)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case "$output" in
+ lib*) ;;
+ *)
+ $echo "$modename: libtool library \`$arg' must begin with \`lib'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ name=`$echo "X$output" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval libname=\"$libname_spec\"
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+ current=0
+ revision=0
+ age=0
+
+ if test -n "$objs"; then
+ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+ exit 1
+ fi
+
+ # How the heck are we supposed to write a wrapper for a shared library?
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: libtool library \`$output' may not depend on uninstalled libraries:$link_against_libtool_libs" 1>&2
+ exit 1
+ fi
+
+ if test -n "$dlfiles$dlprefiles"; then
+ $echo "$modename: warning: \`-dlopen' is ignored while creating libtool libraries" 1>&2
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test -z "$rpath"; then
+ $echo "$modename: you must specify an installation directory with \`-rpath'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ set dummy $rpath
+ if test $# -gt 2; then
+ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+ fi
+ install_libdir="$2"
+
+ # Parse the version information argument.
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo
+ IFS="$save_ifs"
+
+ if test -n "$5"; then
+ $echo "$modename: too many parameters to \`-version-info'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ test -n "$2" && current="$2"
+ test -n "$3" && revision="$3"
+ test -n "$4" && age="$4"
+
+ # Check that each of the things are valid numbers.
+ case "$current" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$revision" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$age" in
+ 0 | [1-9] | [1-9][0-9]*) ;;
+ *)
+ $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test $age -gt $current; then
+ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ fi
+
+ # Calculate the version variables.
+ version_vars="version_type current age revision"
+ case "$version_type" in
+ none) ;;
+
+ linux)
+ version_vars="$version_vars major versuffix"
+ major=`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ version_vars="$version_vars versuffix verstring"
+ major=`expr $current - $age`
+ versuffix="$current.$age.$revision"
+ verstring="$versuffix"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test $loop != 0; do
+ iface=`expr $current - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ sunos)
+ version_vars="$version_vars major versuffix"
+ major="$current"
+ versuffix="$current.$revision"
+ ;;
+
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Create the output directory, or remove our outputs if we need to.
+ if test -d $objdir; then
+ $show "$rm $objdir/$output $objdir/$libname.* $objdir/${libname}${release}.*"
+ $run $rm $objdir/$output $objdir/$libname.* $objdir/${libname}${release}.*
+ else
+ $show "$mkdir $objdir"
+ $run $mkdir $objdir
+ status=$?
+ if test $status -eq 0 || test -d $objdir; then :
+ else
+ exit $status
+ fi
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ # Add libc to deplibs on all systems.
+ dependency_libs="$deplibs"
+ deplibs="$deplibs -lc"
+
+ if test "$build_libtool_libs" = yes; then
+ # Get the real and link names of the library.
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ lib="$objdir/$realname"
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Use standard objects if they are PIC.
+ test -z "$pic_flag" && libobjs=`$echo "X$libobjs " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+ # Do each of the archive commands.
+ eval cmds=\"$archive_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=';'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ $show "(cd $objdir && $LN_S $realname $linkname)"
+ $run eval '(cd $objdir && $LN_S $realname $linkname)' || exit $?
+ done
+
+ # If -export-dynamic was specified, set the dlname.
+ if test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+
+ # Now set the variables for building old libraries.
+ oldlib="$objdir/$libname.a"
+ ;;
+
+ *.lo | *.o)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into reloadable objects" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored while creating objects" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles"; then
+ $echo "$modename: warning: \`-dlopen' is ignored while creating objects" 1>&2
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored while creating objects" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored while creating objects" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored while creating objects" 1>&2
+ fi
+
+ case "$output" in
+ *.lo)
+ if test -n "$objs"; then
+ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+ exit 1
+ fi
+ libobj="$output"
+ obj=`$echo "X$output" | $Xsed -e 's/\.lo$/.o/'`
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $run $rm $obj $libobj
+
+ # Create the old-style object.
+ reload_objs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^ ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+ output="$obj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=';'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Exit if we aren't doing a library object file.
+ test -z "$libobj" && exit 0
+
+ if test "$build_libtool_libs" != yes; then
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > $libobj" || exit $?
+ exit 0
+ fi
+
+ if test -n "$pic_flag"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs"
+ output="$libobj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=';'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ else
+ # Just create a symlink.
+ $show "$LN_S $obj $libobj"
+ $run $LN_S $obj $libobj || exit 1
+ fi
+
+ exit 0
+ ;;
+
+ *)
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored while linking programs" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored while creating objects" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ # Put the magic libdir with the hardcode flag.
+ hardcode_libdirs="$libdir"
+ libdir="@HARDCODE_LIBDIRS@"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ libdir=
+ fi
+ fi
+
+ if test -n "$libdir"; then
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ compile_command="$compile_command $flag"
+ finalize_command="$finalize_command $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ fi
+
+ # Substitute the hardcoded libdirs into the compile commands.
+ if test -n "$hardcode_libdir_separator"; then
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@HARDCODE_LIBDIRS@%$hardcode_libdirs%g"`
+ fi
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$echo "X$compile_command " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'`
+ finalize_command=`$echo "X$finalize_command " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'`
+ fi
+
+ if test "$export_dynamic" = yes && test -n "$NM" && test -n "$global_symbol_pipe"; then
+ dlsyms="${output}S.c"
+ else
+ dlsyms=
+ fi
+
+ if test -n "$dlsyms"; then
+ # Add our own program objects to the preloaded list.
+ dlprefiles=`$echo "X$objs$dlprefiles " | $Xsed -e 's/\.lo /.o /g' -e 's/ $//'`
+
+ # Discover the nlist of each of the dlfiles.
+ nlist="$objdir/${output}.nm"
+
+ if test -d $objdir; then
+ $show "$rm $nlist ${nlist}T"
+ $run $rm "$nlist" "${nlist}T"
+ else
+ $show "$mkdir $objdir"
+ $run $mkdir $objdir
+ status=$?
+ if test $status -eq 0 || test -d $objdir; then :
+ else
+ exit $status
+ fi
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ # Parse the name list into a source file.
+ $show "creating $objdir/$dlsyms"
+ if test -z "$run"; then
+ # Make sure we at least have an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ wcout=`wc "$nlist" 2>/dev/null`
+ count=`echo "X$wcout" | $Xsed -e 's/^[ ]*\([0-9][0-9]*\).*$/\1/'`
+ (test "$count" -ge 0) 2>/dev/null || count=-1
+ else
+ $rm "$nlist"T
+ count=-1
+ fi
+
+ case "$dlsyms" in
+ "") ;;
+ *.c)
+ $echo > "$objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$output' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define dld_preloaded_symbol_count some_other_symbol
+#define dld_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test -f "$nlist"; then
+ sed -e 's/^.* \(.*\)$/extern char \1;/' < "$nlist" >> "$objdir/$dlsyms"
+ else
+ echo '/* NONE */' >> "$objdir/$dlsyms"
+ fi
+
+ $echo >> "$objdir/$dlsyms" "\
+
+#undef dld_preloaded_symbol_count
+#undef dld_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define __ptr_t void *
+#else
+# define __ptr_t char *
+#endif
+
+/* The number of symbols in dld_preloaded_symbols, -1 if unsorted. */
+int dld_preloaded_symbol_count = $count;
+
+/* The mapping between symbol names and symbols. */
+struct {
+ char *name;
+ __ptr_t address;
+}
+dld_preloaded_symbols[] =
+{\
+"
+
+ if test -f "$nlist"; then
+ sed 's/^\(.*\) \(.*\)$/ {"\1", (__ptr_t) \&\2},/' < "$nlist" >> "$objdir/$dlsyms"
+ fi
+
+ $echo >> "$objdir/$dlsyms" "\
+ {0, (__ptr_t) 0}
+};
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ ;;
+
+ *)
+ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+ exit 1
+ ;;
+ esac
+ fi
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $objdir && $CC -c$no_builtin_flag \"$dlsyms\")"
+ $run eval '(cd $objdir && $CC -c$no_builtin_flag "$dlsyms")' || exit $?
+
+ # Transform the symbol file into the correct name.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.o%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$objdir/${output}S.o%"`
+ elif test "$export_dynamic" != yes; then
+ test -n "$dlfiles$dlprefiles" && $echo "$modename: warning: \`-dlopen' and \`-dlpreopen' are ignored without \`-export-dynamic'" 1>&2
+ else
+ # We keep going just in case the user didn't refer to
+ # dld_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ $show "$compile_command"
+ $run eval "$compile_command"
+ exit $?
+ fi
+
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$objdir/$output"'%g'`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e 's%@OUTPUT@%'"$objdir/$output"'T%g'`
+
+ # Create the binary in the object directory, then wrap it.
+ if test -d $objdir; then :
+ else
+ $show "$mkdir $objdir"
+ $run $mkdir $objdir
+ status=$?
+ if test $status -eq 0 || test -d $objdir; then :
+ else
+ exit $status
+ fi
+ fi
+
+ if test -n "$shlibpath_var"; then
+ # We should set the shlibpath_var
+ rpath=
+ for dir in $temp_rpath; do
+ case "$dir" in
+ /* | [A-Za-z]:\\*)
+ # Absolute path.
+ rpath="$rpath$dir:"
+ ;;
+ *)
+ # Relative path: add a thisdir entry.
+ rpath="$rpath\$thisdir/$dir:"
+ ;;
+ esac
+ done
+ temp_rpath="$rpath"
+ fi
+
+ # Delete the old output file.
+ $run $rm $output
+
+ if test -n "$compile_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ if test -n "$runpath_var" && test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_command="$runpath_var=\"$rpath\$$runpath_var\" $compile_command"
+ finalize_command="$runpath_var=\"$rpath\$$runpath_var\" $finalize_command"
+ fi
+
+ case "$hardcode_action" in
+ relink)
+ # AGH! Flame the AIX and HP-UX people for me, will ya?
+ $echo "$modename: warning: using a buggy system linker" 1>&2
+ $echo "$modename: relinking will be required before \`$output' can be installed" 1>&2
+ ;;
+ esac
+
+ $show "$compile_command"
+ $run eval "$compile_command" || exit $?
+
+ # Now create the wrapper script.
+ $show "creating $output"
+
+ # Quote the finalize command for shipping.
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "$sed_quote_subst"`
+
+ # Quote $echo for shipping.
+ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+
+ # Only actually do things if our run command is non-null.
+ if test -z "$run"; then
+ $rm $output
+ trap "$rm $output; exit 1" 1 2 15
+
+ $echo > $output "\
+#! /bin/sh
+
+# $output - temporary wrapper script for $objdir/$output
+# Generated by ltmain.sh - GNU $PACKAGE $VERSION
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of \``pwd`'.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variables:
+ link_against_libtool_libs='$link_against_libtool_libs'
+ finalize_command=\"$finalize_command\"
+else
+ # When we are sourced in execute mode, \$file and \$echo are already set.
+ if test \"\$libtool_execute_magic\" = \"$magic\"; then :
+ else
+ echo=\"$qecho\"
+ file=\"\$0\"
+ fi\
+"
+ $echo >> $output "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ /* | [A-Za-z]:\\*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+ done
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+
+ progdir=\"\$thisdir/$objdir\"
+ program='$output'
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $echo >> $output "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/:*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ $echo >> $output "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+
+ # Export the path to the program.
+ PATH=\"\$progdir:\$PATH\"
+ export PATH
+
+ exec \$program \${1+\"\$@\"}
+
+ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"This script is just a wrapper for \$program.\" 1>&2
+ echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+ chmod +x $output
+ fi
+ exit 0
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ if test "$build_old_libs" = "yes"; then
+ # Transform .lo files to .o files.
+ oldobjs="$objs"`$echo "X$libobjs " | $Xsed -e 's/[^ ]*\.a //g' -e 's/\.lo /.o /g' -e 's/ $//g'`
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ eval cmds=\"$old_archive_from_new_cmds\"
+ else
+ eval cmds=\"$old_archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=';'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Now create the libtool archive.
+ case "$output" in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.a"
+
+ $show "creating $output"
+
+ # Only create the output if not a dry run.
+ if test -z "$run"; then
+ $echo > $output "\
+# $output - a libtool library file
+# Generated by ltmain.sh - GNU $PACKAGE $VERSION
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+ fi
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ $show "(cd $objdir && $LN_S ../$output $output)"
+ $run eval "(cd $objdir && $LN_S ../$output $output)" || exit 1
+ ;;
+ esac
+ exit 0
+ ;;
+
+ # libtool install mode
+ install)
+ modename="$modename: install"
+
+ # There may be an optional /bin/sh argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL"; then
+ # Aesthetically quote it.
+ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$arg "
+ arg="$1"
+ shift
+ else
+ install_prog=
+ arg="$nonopt"
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog$arg"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest="$arg"
+ continue
+ fi
+
+ case "$arg" in
+ -d) isdir=yes ;;
+ -f) prev="-f" ;;
+ -g) prev="-g" ;;
+ -m) prev="-m" ;;
+ -o) prev="-o" ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*) ;;
+
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest="$arg"
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog $arg"
+ done
+
+ if test -z "$install_prog"; then
+ $echo "$modename: you must specify an install program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prev' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ $echo "$modename: no file or destination specified" 1>&2
+ else
+ $echo "$modename: you must specify a destination" 1>&2
+ fi
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Strip any trailing slash from the destination.
+ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test -n "$isdir"; then
+ destdir="$dest"
+ destname=
+ else
+ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$destdir" = "X$dest" && destdir=.
+ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files
+ if test $# -gt 2; then
+ $echo "$modename: \`$dest' is not a directory" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ fi
+ case "$destdir" in
+ /* | [A-Za-z]:\\*) ;;
+ *)
+ for file in $files; do
+ case "$file" in
+ *.lo) ;;
+ *)
+ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case "$file" in
+ *.a)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ library_names=
+ old_library=
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+ test "X$dir" = "X$file/" && dir=
+ dir="$dir$objdir"
+
+ # See the names of the shared library.
+ set dummy $library_names
+ if test -n "$2"; then
+ realname="$2"
+ shift
+ shift
+
+ # Install the shared library and build the symlinks.
+ $show "$install_prog $dir/$realname $destdir/$realname"
+ $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+ test "X$dlname" = "X$realname" && dlname=
+
+ if test $# -gt 0; then
+ # Delete the old symlinks.
+ rmcmd="$rm"
+ for linkname
+ do
+ rmcmd="$rmcmd $destdir/$linkname"
+ done
+ $show "$rmcmd"
+ $run $rmcmd
+
+ # ... and create new ones.
+ for linkname
+ do
+ test "X$dlname" = "X$linkname" && dlname=
+ $show "(cd $destdir && $LN_S $realname $linkname)"
+ $run eval "(cd $destdir && $LN_S $realname $linkname)"
+ done
+ fi
+
+ if test -n "$dlname"; then
+ # Install the dynamically-loadable library.
+ $show "$install_prog $dir/$dlname $destdir/$dlname"
+ $run eval "$install_prog $dir/$dlname $destdir/$dlname" || exit $?
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ eval cmds=\"$postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=';'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Install the pseudo-library for information purposes.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ $show "$install_prog $file $destdir/$name"
+ $run eval "$install_prog $file $destdir/$name" || exit $?
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case "$destfile" in
+ *.lo)
+ staticdest=`$echo "X$destfile" | $Xsed -e 's/\.lo$/\.o/'`
+ ;;
+ *.o)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ if test -n "$destfile"; then
+ $show "$install_prog $file $destfile"
+ $run eval "$install_prog $file $destfile" || exit $?
+ fi
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ staticobj=`$echo "X$file" | $Xsed -e 's/\.lo$/\.o/'`
+
+ $show "$install_prog $staticobj $staticdest"
+ $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+ fi
+ exit 0
+ ;;
+
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then
+ link_against_libtool_libs=
+ finalize_command=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Check the variables that should have been set.
+ if test -z "$link_against_libtool_libs" || test -z "$finalize_command"; then
+ $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+ exit 1
+ fi
+
+ finalize=yes
+ for lib in $link_against_libtool_libs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ # If there is no directory component, then add one.
+ case "$lib" in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ fi
+ libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+ if test -z "$libdir"; then
+ $echo "$modename: warning: \`$lib' contains no -rpath information" 1>&2
+ elif test -f "$libfile"; then :
+ else
+ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+ finalize=no
+ fi
+ done
+
+ if test "$hardcode_action" = relink; then
+ if test "$finalize" = yes; then
+ $echo "$modename: warning: relinking \`$file' on behalf of your buggy system linker" 1>&2
+ $show "$finalize_command"
+ if $run eval "$finalize_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ continue
+ fi
+ file="$objdir/$file"T
+ else
+ $echo "$modename: warning: cannot relink \`$file' on behalf of your buggy system linker" 1>&2
+ fi
+ else
+ # Install the binary that we compiled earlier.
+ file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ $show "$install_prog$stripme $file $dest"
+ $run eval "$install_prog\$stripme \$file \$dest" || exit $?
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ $show "$install_prog $file $oldlib"
+ $run eval "$install_prog \$file \$oldlib" || exit $?
+
+ # Do each command in the postinstall commands.
+ eval cmds=\"$old_postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=';'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$future_libdirs"; then
+ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+ fi
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ test -n "$run" && current_libdirs=" -n$current_libdirs"
+ exec $SHELL $0 --finish$current_libdirs
+ exit 1
+ fi
+
+ exit 0
+ ;;
+
+ # libtool finish mode
+ finish)
+ modename="$modename: finish"
+ libdirs="$nonopt"
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ eval cmds=\"$finish_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=';'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $run eval "$cmds"
+ fi
+ done
+ fi
+
+ echo "------------------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ echo " $libdir"
+ done
+ echo
+ echo "To link against installed libraries in a given directory, LIBDIR,"
+ echo "you must use the \`-LLIBDIR' flag during linking."
+ echo
+ echo " You will also need to do one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ echo " - use the \`$flag' linker flag"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+ echo "See any operating system documentation about shared libraries for"
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ echo "------------------------------------------------------------------------------"
+ exit 0
+ ;;
+
+ # libtool execute mode
+ execute)
+ modename="$modename: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ $echo "$modename: you must specify a COMMAND" 1>&2
+ $echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test -f "$file"; then :
+ else
+ $echo "$modename: \`$file' is not a file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case "$file" in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case "$file" in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+ args="$args \"$file\""
+ done
+
+ if test -z "$run"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+
+ # Now actually exec the command.
+ eval "exec \$cmd$args"
+
+ $echo "$modename: cannot exec \$cmd$args"
+ exit 1
+ else
+ # Display what would be done.
+ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+ $echo "export $shlibpath_var"
+ $echo "$cmd$args"
+ exit 0
+ fi
+ ;;
+
+ # libtool uninstall mode
+ uninstall)
+ modename="$modename: uninstall"
+ rm="$nonopt"
+ files=
+
+ for arg
+ do
+ case "$arg" in
+ -*) rm="$rm $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ if test -z "$rm"; then
+ $echo "$modename: you must specify an RM program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ for file in $files; do
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ rmfiles="$file"
+
+ case "$name" in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if (sed -e '2q' $file | egrep '^# Generated by ltmain\.sh') >/dev/null 2>&1; then
+ . $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $dir/$n"
+ test "X$n" = "X$dlname" && dlname=
+ done
+ test -n "$dlname" && rmfiles="$rmfiles $dir/$dlname"
+ test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ eval cmds=\"$postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=';'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ eval cmds=\"$old_postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=';'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ # FIXME: should reinstall the best remaining shared library.
+ fi
+ ;;
+
+ *.lo)
+ if test "$build_old_libs" = yes; then
+ oldobj=`$echo "X$name" | $Xsed -e 's/\.lo$/\.o/'`
+ rmfiles="$rmfiles $dir/$oldobj"
+ fi
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+
+ *)
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+ esac
+ done
+ exit 0
+ ;;
+
+ "")
+ $echo "$modename: you must specify a MODE" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+-n, --dry-run display commands without modifying any files
+ --features display configuration information and exit
+ --finish same as \`--mode=finish'
+ --help display this help message and exit
+ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
+ --quiet same as \`--silent'
+ --silent don't print informational messages
+ --version print version information
+
+MODE must be one of the following:
+
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+ exit 0
+ ;;
+
+compile)
+ $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+execute)
+ $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+finish)
+ $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+install)
+ $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+link)
+ $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to dld_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -static do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only
+library objects (\`.lo' files) may be specified, and \`-rpath' is required.
+
+If OUTPUT-FILE ends in \`.a', then a standard library is created using \`ar'
+and \`ranlib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.o', then a reloadable object file is
+created, otherwise an executable program is created."
+ ;;
+
+uninstall)
+ $echo
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+*)
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/missing b/missing
new file mode 100755
index 00000000..e4b838ca
--- /dev/null
+++ b/missing
@@ -0,0 +1,134 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+# Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+# Franc,ois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# 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 2, 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+if test $# -eq 0; then
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+fi
+
+case "$1" in
+
+ -h|--h|--he|--hel|--help)
+ echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+ -h, --help display this help and exit
+ -v, --version output version information and exit
+
+Supported PROGRAM values:
+ aclocal touch file \`aclocal.m4'
+ autoconf touch file \`configure'
+ autoheader touch file \`config.h.in'
+ automake touch all \`Makefile.in' files
+ bison touch file \`y.tab.c'
+ makeinfo touch the output file
+ yacc touch file \`y.tab.c'"
+ ;;
+
+ -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+ echo "missing - GNU libit 0.0"
+ ;;
+
+ -*)
+ echo 1>&2 "$0: Unknown \`$1' option"
+ echo 1>&2 "Try \`$0 --help' for more information"
+ exit 1
+ ;;
+
+ aclocal)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. It should be needed only if
+ you modified \`acinclude.m4' or \`configure.in'. You might want
+ to install the \`Automake' and \`Perl' packages. Grab them from
+ any GNU archive site."
+ touch aclocal.m4
+ ;;
+
+ autoconf)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. It should be needed only if
+ you modified \`configure.in'. You might want to install the
+ \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
+ archive site."
+ touch configure
+ ;;
+
+ autoheader)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. It should be needed only if
+ you modified \`acconfig.h' or \`configure.in'. You might want
+ to install the \`Autoconf' and \`GNU m4' packages. Grab them
+ from any GNU archive site."
+ touch config.h.in
+ ;;
+
+ automake)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. It should be needed only if
+ you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'.
+ You might want to install the \`Automake' and \`Perl' packages.
+ Grab them from any GNU archive site."
+ find . -type f -name Makefile.am -print \
+ | sed 's/^\(.*\).am$/touch \1.in/' \
+ | sh
+ ;;
+
+ bison|yacc)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. It should be needed only if
+ your modified any \`.y' file. For being effective, your
+ modifications might require the \`Bison' package. Grab it from
+ any GNU archive site."
+ touch y.tab.c
+ ;;
+
+ makeinfo)
+ echo 1>&2 "\
+WARNING: \`$1' is missing on your system. It should be needed only if
+ you modified a \`.texi' or \`.texinfo' file, or any other file
+ indirectly affecting the aspect of the manual. The spurious
+ call might also be the consequence of using a buggy \`make' (AIX,
+ DU, IRIX). You might want to install the \`Texinfo' package or
+ the \`GNU make' package. Grab either from any GNU archive site."
+ file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+ if test -z "$file"; then
+ file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+ file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
+ fi
+ touch $file
+ ;;
+
+ *)
+ echo 1>&2 "\
+WARNING: \`$1' is needed, and you do not seem to have it handy on your
+ system. You might have modified some files without having the
+ proper tools for further handling them. Check the \`README' file,
+ it often tells you about the needed prerequirements for installing
+ this package. You may also peek at any GNU archive site, in case
+ some other package would contain this missing \`$1' program."
+ exit 1
+ ;;
+esac
+
+exit 0
diff --git a/mkinstalldirs b/mkinstalldirs
new file mode 100755
index 00000000..91f6d04e
--- /dev/null
+++ b/mkinstalldirs
@@ -0,0 +1,32 @@
+#!/bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d in ${1+"$@"} ; do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+ mkdir "$pathcomp" || errstatus=$?
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/modules/Makefile.am b/modules/Makefile.am
new file mode 100644
index 00000000..01ef5c23
--- /dev/null
+++ b/modules/Makefile.am
@@ -0,0 +1,9 @@
+noinst_PROGRAMS = test.so time.so
+
+test_so_SOURCES = test.c
+time_so_SOURCES = time.c
+
+EXTRA_DIST = test.m4 time.m4
+
+INCLUDES = -I$(srcdir)/../src -I$(srcdir)/../lib
+LDFLAGS = -shared
diff --git a/modules/Makefile.in b/modules/Makefile.in
new file mode 100644
index 00000000..06248f02
--- /dev/null
+++ b/modules/Makefile.in
@@ -0,0 +1,300 @@
+# Makefile.in generated automatically by automake 1.3b from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# This Makefile.in 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+PACKAGE = @PACKAGE@
+PERL = @PERL@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+STACKOVF = @STACKOVF@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+l = @l@
+
+noinst_PROGRAMS = test.so time.so
+
+test_so_SOURCES = test.c
+time_so_SOURCES = time.c
+
+EXTRA_DIST = test.m4 time.m4
+
+INCLUDES = -I$(srcdir)/../src -I$(srcdir)/../lib
+LDFLAGS = -shared
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(noinst_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I..
+CPPFLAGS = @CPPFLAGS@
+LIBS = @LIBS@
+test_so_OBJECTS = test.o
+test_so_LDADD = $(LDADD)
+test_so_DEPENDENCIES =
+test_so_LDFLAGS =
+time_so_OBJECTS = time.o
+time_so_LDADD = $(LDADD)
+time_so_DEPENDENCIES =
+time_so_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LINK = $(CC) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = README Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+DEP_FILES = .deps/test.P .deps/time.P
+SOURCES = $(test_so_SOURCES) $(time_so_SOURCES)
+OBJECTS = $(test_so_OBJECTS) $(time_so_OBJECTS)
+
+all: Makefile $(PROGRAMS)
+
+.SUFFIXES:
+.SUFFIXES: .S .c .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-noinstPROGRAMS:
+
+clean-noinstPROGRAMS:
+ -test -z "$(noinst_PROGRAMS)" || rm -f $(noinst_PROGRAMS)
+
+distclean-noinstPROGRAMS:
+
+maintainer-clean-noinstPROGRAMS:
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+test.so: $(test_so_OBJECTS) $(test_so_DEPENDENCIES)
+ @rm -f test.so
+ $(LINK) $(test_so_LDFLAGS) $(test_so_OBJECTS) $(test_so_LDADD) $(LIBS)
+
+time.so: $(time_so_OBJECTS) $(time_so_DEPENDENCIES)
+ @rm -f time.so
+ $(LINK) $(time_so_LDFLAGS) $(time_so_OBJECTS) $(time_so_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $(SOURCES) $(HEADERS) $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = modules
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu modules/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+
+maintainer-clean-depend:
+ -rm -rf .deps
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).P -c $<
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).p -c $<
+ @-sed -e 's/^\([^:]*\)\.o:/\1.lo \1.o:/' \
+ < .deps/$(*F).p > .deps/$(*F).P
+ @-rm -f .deps/$(*F).p
+info:
+dvi:
+check: all
+installcheck:
+install-exec:
+ @$(NORMAL_INSTALL)
+
+install-data:
+ @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+ @:
+
+uninstall:
+
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean: mostlyclean-noinstPROGRAMS mostlyclean-compile \
+ mostlyclean-tags mostlyclean-depend mostlyclean-generic
+
+clean: clean-noinstPROGRAMS clean-compile clean-tags clean-depend \
+ clean-generic mostlyclean
+
+distclean: distclean-noinstPROGRAMS distclean-compile distclean-tags \
+ distclean-depend distclean-generic clean
+ -rm -f config.status
+
+maintainer-clean: maintainer-clean-noinstPROGRAMS \
+ maintainer-clean-compile maintainer-clean-tags \
+ maintainer-clean-depend maintainer-clean-generic \
+ distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: mostlyclean-noinstPROGRAMS distclean-noinstPROGRAMS \
+clean-noinstPROGRAMS maintainer-clean-noinstPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info dvi \
+installcheck install-exec install-data install uninstall all \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/modules/README b/modules/README
new file mode 100644
index 00000000..93e7bbb1
--- /dev/null
+++ b/modules/README
@@ -0,0 +1,62 @@
+This directory contains demonstration modules for GNU m4.
+
+Nothing in this directory is built by default.
+
+Dynamic modules is a experimental feature of GNU m4, and might change or
+disappear altogether in future versions. Currently it has only been
+certified to work under Linux 2.0.
+
+Dynamic modules are only available if GNU m4 was configured with
+--with-modules and if the dlopen(3) interface is available in the
+operating system.
+
+Implementation details are in ../src/module.c
+
+A module is a compiled shared object, i.e., modules are written in C and
+then compiled. The compiled file can then be loaded into a running m4
+process by calling the builtin "loadmodule". This will give GNU m4
+access to any system feature with a C interface.
+
+A module extends GNU m4 by defining new builtins, It can define builtins
+with the same names as existing builtins, which will then be
+unavailable. A module cannot redefine internal functions of GNU m4,
+such as the input parser or argument handling.
+
+The infrastructure for writing and compiling modules is still a bit
+wanting, quasi non-existent.
+
+Each module should include the two header files ../src/m4.h and
+../src/builtin.h. These will include <ctype.h>, <stdio.h>,
+../lib/obstack.h and ../config.h.
+
+Each module *must* define the symbol "m4_macro_table" as a pointer to a
+table of "struct builtin" (defined in m4.h). The table ends with an
+entry with name == NULL. The builtins described in the table will be
+defined by GNU m4 as were they normal builtins.
+
+If a module defines the symbol "m4_init_module", it is supposed to be a
+function with a prototype of "void m4_init_module(struct obstack *obs)",
+and it will be called as soon as the module is loaded. Any non-finished
+object left on the obstack will be the expansion of the call of the
+builtin "loadmodule". The obstack pointer might be NULL (in the future).
+
+If a module defines the symbol "m4_finish_module", it is supposed to be
+a function with a prototype of "void m4_finish_module(void)", and it
+will be called just before GNU m4 exits. This will allow a module to
+clean up before exit. There is no way of communicating information to
+the user, as GNU m4 exits immeidately afterwards.
+
+No other symbols will be used by GNU m4. Other external symbols within
+the module are private and will not be accessible to GNU m4 or to other
+modules.
+
+Modules are allowed to call external functions already defined within
+the GNU m4 sources. Some of these have prototypes in builtin.h.
+
+
+A complete, though silly, example is found in test.c. A more
+interesting example is in time.c.
+
+To try the demos, compile with `make' and run them with the commands as:
+
+ M4MODPATH=`pwd` ../src/m4 time.m4
diff --git a/modules/TODO b/modules/TODO
new file mode 100644
index 00000000..c5d7ec4d
--- /dev/null
+++ b/modules/TODO
@@ -0,0 +1,3 @@
+The file src/m4.h will have to be split to have an installable m4defs.h
+suitable for modules. Modules should be compilable without have the m4
+source available.
diff --git a/modules/defs b/modules/defs
new file mode 100644
index 00000000..403eabbe
--- /dev/null
+++ b/modules/defs
@@ -0,0 +1,58 @@
+# -*- ksh -*-
+# Defines for GNU m4 testing environment.
+# Erick Branderhorst <Erick.Branderhorst@asml.nl>
+
+# Ensure $srcdir set correctly.
+test -f ${srcdir}/defs || {
+ echo "defs: installation error" 1>&2
+ exit 1
+}
+
+# If srcdir is relative, we need to modify it.
+case "$srcdir" in
+ /*)
+ ;;
+
+ .)
+ srcdir=".."
+ ;;
+
+ *)
+ srcdir="../$srcdir"
+ ;;
+esac
+
+rm -rf testSubDir > /dev/null 2>&1
+mkdir testSubDir
+cd testSubDir
+
+# Build appropriate environment in test directory. Eg create
+# configure.in, touch all necessary files, etc.
+
+# nothing yet
+
+# See how redirections should work. User can set VERBOSE to see all
+# output.
+test -z "$VERBOSE" && {
+ exec > /dev/null 2>&1
+}
+
+# User can set MAKE to choose which make to use. Must use GNU make.
+test -z "$MAKE" && MAKE=make
+
+echo "=== Running test $0"
+
+# See how GNU m4 should be run. No options as default.
+test -z "$M4" && M4="${SHELL-/bin/sh} ../../libtool --mode=execute ../../src/m4"
+
+# See how cmp should be run.
+test -z "$CMP" && CMP=cmp
+
+# Setting nls related vars. Override them in the test when needed.
+LANGUAGE=C
+export LANGUAGE
+LC_ALL=C
+export LC_ALL
+LANG=C
+export LANG
+
diff --git a/modules/modpath1.test b/modules/modpath1.test
new file mode 100755
index 00000000..2722ed43
--- /dev/null
+++ b/modules/modpath1.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# test.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+. ../../tests/config.sh
+
+# cannot perform test without --with-modules
+#test -z "$WITH_MODULES" && exit 77
+
+cat ${srcdir}/test.m4 >in
+
+cat <<'EOF' >ok
+Test module loaded.
+Test module called.
+Dumpdef:
+EOF
+
+cat <<'EOF' >okerr
+test: <test>
+EOF
+
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -M `cd $srcdir; pwd` -d in >out 2>err
+sed -e "s,^[^:]*[lt-]*m4[.ex]*:,m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/modules/modpath2.test b/modules/modpath2.test
new file mode 100755
index 00000000..06af519a
--- /dev/null
+++ b/modules/modpath2.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# test.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+. ../../tests/config.sh
+
+# cannot perform test without --with-modules
+#test -z "$WITH_MODULES" && exit 77
+
+cat ${srcdir}/test.m4 >in
+
+cat <<'EOF' >ok
+Test module loaded.
+Test module called.
+Dumpdef:
+EOF
+
+cat <<'EOF' >okerr
+test: <test>
+EOF
+
+LTDL_LIBRARY_PATH=`cd $srcdir; pwd` M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s,^[^:]*[lt-]*m4[.ex]*:,m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/modules/modpath3.test b/modules/modpath3.test
new file mode 100755
index 00000000..6064265b
--- /dev/null
+++ b/modules/modpath3.test
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+# test.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+. ../../tests/config.sh
+
+# cannot perform test without --with-modules
+#test -z "$WITH_MODULES" && exit 77
+
+
+
+cat <<'EOF' >in
+test
+Dumpdef: dumpdef(`test')
+EOF
+
+cat <<'EOF' >ok
+Test module called.
+Dumpdef:
+EOF
+
+cat <<'EOF' >okerr
+test: <test>
+EOF
+
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -m test -M `cd $srcdir; pwd` -d in >out 2>err
+sed -e "s,^[^:]*[lt-]*m4[.ex]*:,m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/modules/modpath4.test b/modules/modpath4.test
new file mode 100755
index 00000000..780cdbeb
--- /dev/null
+++ b/modules/modpath4.test
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# test.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+. ../../tests/config.sh
+
+cat ${srcdir}/test.m4 >in
+
+
+cat <<'EOF' >ok
+Test module loaded.
+Test module called.
+Dumpdef:
+EOF
+
+cat <<'EOF' >okerr
+test: <test>
+EOF
+
+
+M4MODPATH=`cd $srcdir; pwd` M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s,^[^:]*[lt-]*m4[.ex]*:,m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/modules/shadow.c b/modules/shadow.c
new file mode 100644
index 00000000..5955828b
--- /dev/null
+++ b/modules/shadow.c
@@ -0,0 +1,75 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1998 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <m4module.h> /* This is obligatory */
+
+#define LTDL_MODULE_NAME shadow
+
+module_init_t m4_init_module; /* initialisation function */
+module_finish_t m4_finish_module; /* cleanup function */
+
+/* declare builtins */
+M4BUILTIN(shadow);
+M4BUILTIN(test);
+#undef M4BUILTIN
+
+#define m4_macro_table shadow_LTX_m4_macro_table
+#define m4_init_module shadow_LTX_m4_init_module
+#define m4_finish_module shadow_LTX_m4_finish_module
+
+/* The table of builtins defined by this module - just one */
+
+builtin m4_macro_table[] =
+{
+ /* name GNUext macros blind function */
+ { "shadow", FALSE, FALSE, FALSE, shadow },
+ { "test", FALSE, FALSE, FALSE, test },
+ { 0, FALSE, FALSE, FALSE, 0 },
+};
+
+void
+m4_init_module(struct obstack *obs)
+{
+ char *s = "Shadow module loaded.";
+ if (obs != 0)
+ obstack_grow (obs, s, strlen(s));
+}
+
+void
+m4_finish_module(void)
+{
+ return;
+}
+
+/* The functions for builtins can be static */
+static void
+shadow (struct obstack *obs, int argc, token_data **argv)
+{
+ char *s = "Shadow::`shadow' called.";
+ obstack_grow (obs, s, strlen(s));
+}
+
+static void
+test (struct obstack *obs, int argc, token_data **argv)
+{
+ char *s = "Shadow::`test' called.";
+ obstack_grow (obs, s, strlen(s));
+}
+
+
+
diff --git a/modules/shadow.m4 b/modules/shadow.m4
new file mode 100644
index 00000000..b55adbcb
--- /dev/null
+++ b/modules/shadow.m4
@@ -0,0 +1,59 @@
+# no modules loaded yet
+test
+shadow
+
+# define our own macros for `test' and `shadow'
+define(`test', `local::`test'')
+define(`shadow', `local::`shadow'')
+test
+shadow
+
+# save our local `shadow' macro until the Shadow module is unloaded
+pushdef(`shadow')
+
+# module Shadow defines `shadow' and `test' macros
+loadmodule(`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
+loadmodule(`test')
+dumpdef(`test')
+dumpdef(`shadow')
+test
+shadow
+
+# Reloading Shadow shouldn't affect anything
+loadmodule(`shadow')
+dumpdef(`test')
+dumpdef(`shadow')
+test
+shadow
+
+# Unloading Test will not unshadow the test definition in Shadow without
+# some macro magic
+unloadmodule(`test')
+define(`test', defn(`Shadow::test'))
+undefine(`Shadow::test')
+dumpdef(`test')
+dumpdef(`shadow')
+test
+shadow
+
+# Unloading Shadow once has no effect (we loaded it twice)
+unloadmodule(`shadow')
+dumpdef(`test')
+dumpdef(`shadow')
+test
+shadow
+
+# Unloading Shadow again will revert to copying `test' and the locally
+# pushed `shadow' macro.
+unloadmodule(`shadow')
+test
+shadow
diff --git a/modules/shadow.test b/modules/shadow.test
new file mode 100755
index 00000000..c8952b59
--- /dev/null
+++ b/modules/shadow.test
@@ -0,0 +1,91 @@
+#!/bin/sh
+
+# shadow.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+. ../../tests/config.sh
+
+# cannot perform test without --with-modules
+# test -z "$WITH_MODULES" && exit 77
+
+cat ${srcdir}/shadow.m4 >in
+
+cat <<'EOF' >ok
+# no modules loaded yet
+test
+shadow
+
+# define our own macros for `test' and `shadow'
+
+
+local::test
+local::shadow
+
+# save our local `shadow' macro until the Shadow module is unloaded
+
+
+# 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 Test also defines a `test' macro
+Test module loaded.
+
+
+Test module called.
+Shadow::shadow called.
+
+# Reloading Shadow shouldn't affect anything
+
+
+
+Test module called.
+Shadow::shadow called.
+
+# Unloading Test will not unshadow the test definition in Shadow without
+# some macro magic
+
+
+
+
+
+Shadow::test called.
+Shadow::shadow called.
+
+# Unloading Shadow once has no effect (we loaded it twice)
+
+
+
+Shadow::test called.
+Shadow::shadow called.
+
+# Unloading Shadow again will revert to copying `test' and the locally
+# pushed `shadow' macro.
+
+test
+local::shadow
+EOF
+
+cat <<'EOF' >okerr
+test: <test>
+shadow: <shadow>
+test: <test>
+shadow: <shadow>
+test: <test>
+shadow: <shadow>
+test: <test>
+shadow: <shadow>
+test: <test>
+shadow: <shadow>
+EOF
+
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -M `cd $srcdir; pwd` -d in >out 2>err
+sed -e "s,^[^:]*[lt-]*m4[.ex]*:,m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/modules/stdlib.c b/modules/stdlib.c
new file mode 100644
index 00000000..6ba8556d
--- /dev/null
+++ b/modules/stdlib.c
@@ -0,0 +1,293 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1998 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <m4.h>
+#include <builtin.h>
+
+#include <pwd.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/utsname.h>
+#include <sys/types.h>
+
+DECLARE(m4_getcwd);
+DECLARE(m4_getlogin);
+DECLARE(m4_getpid);
+DECLARE(m4_getppid);
+DECLARE(m4_getuid);
+DECLARE(m4_getpwnam);
+DECLARE(m4_getpwuid);
+DECLARE(m4_hostname);
+DECLARE(m4_rand);
+DECLARE(m4_srand);
+DECLARE(m4_getenv);
+DECLARE(m4_setenv);
+DECLARE(m4_unsetenv);
+DECLARE(m4_uname);
+
+#undef DECLARE
+
+builtin m4_macro_table[] =
+{
+ /* name GNUext macros blind function */
+ { "getcwd", TRUE, FALSE, FALSE, m4_getcwd },
+ { "getenv", TRUE, FALSE, TRUE, m4_getenv },
+ { "setenv", TRUE, FALSE, TRUE, m4_setenv },
+ { "unsetenv", TRUE, FALSE, TRUE, m4_unsetenv },
+ { "getlogin", TRUE, FALSE, FALSE, m4_getlogin },
+ { "getpid", TRUE, FALSE, FALSE, m4_getpid },
+ { "getppid", TRUE, FALSE, FALSE, m4_getppid },
+ { "getpwnam", TRUE, FALSE, TRUE, m4_getpwnam },
+ { "getpwuid", TRUE, FALSE, TRUE, m4_getpwuid },
+ { "getuid", TRUE, FALSE, FALSE, m4_getuid },
+ { "hostname", TRUE, FALSE, FALSE, m4_hostname },
+ { "rand", TRUE, FALSE, FALSE, m4_rand },
+ { "srand", TRUE, FALSE, FALSE, m4_srand },
+ { "uname", TRUE, FALSE, FALSE, m4_uname },
+ { 0, FALSE, FALSE, FALSE, 0 },
+};
+
+
+
+static void
+m4_getcwd (struct obstack *obs, int argc, token_data **argv)
+{
+ char buf[1024];
+ char *bp;
+ int l;
+
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+
+ bp = getcwd(buf, sizeof buf);
+
+ if (bp != NULL) /* in case of error return null string */
+ shipout_string (obs, buf, 0 , FALSE);
+}
+
+static void
+m4_getenv (struct obstack *obs, int argc, token_data **argv)
+{
+ char *env;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ env = getenv(ARG(1));
+
+ if (env != NULL)
+ shipout_string (obs, env, 0, FALSE);
+}
+
+static void
+m4_setenv (struct obstack *obs, int argc, token_data **argv)
+{
+ char *env;
+ int overwrite = 1;
+
+ if (bad_argc (argv[0], argc, 3, 4))
+ return;
+
+ if (argc == 4)
+ if (!numeric_arg(argv[0], ARG(3), &overwrite))
+ return;
+
+ setenv(ARG(1), ARG(2), overwrite);
+}
+
+static void
+m4_unsetenv (struct obstack *obs, int argc, token_data **argv)
+{
+ char *env;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ unsetenv(ARG(1));
+}
+
+static void
+m4_getlogin (struct obstack *obs, int argc, token_data **argv)
+{
+ char *login;
+
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+
+ login = getlogin();
+
+ if (login != NULL)
+ shipout_string (obs, login, 0, FALSE);
+}
+
+static void
+m4_getpid (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+
+ shipout_int(obs, getpid());
+}
+
+static void
+m4_getppid (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+
+ shipout_int(obs, getppid());
+}
+
+static void
+m4_getpwnam (struct obstack *obs, int argc, token_data **argv)
+{
+ struct passwd *pw;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ pw = getpwnam(ARG(1));
+
+ if (pw != NULL)
+ {
+ shipout_string (obs, pw->pw_name, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, pw->pw_passwd, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_int(obs, pw->pw_uid);
+ obstack_1grow (obs, ',');
+ shipout_int(obs, pw->pw_gid);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, pw->pw_gecos, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, pw->pw_dir, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, pw->pw_shell, 0, TRUE);
+ }
+}
+
+static void
+m4_getpwuid (struct obstack *obs, int argc, token_data **argv)
+{
+ struct passwd *pw;
+ int uid;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ if (!numeric_arg(argv[0], ARG(1), &uid))
+ return;
+
+ pw = getpwuid(uid);
+
+ if (pw != NULL)
+ {
+ shipout_string (obs, pw->pw_name, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, pw->pw_passwd, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_int(obs, pw->pw_uid);
+ obstack_1grow (obs, ',');
+ shipout_int(obs, pw->pw_gid);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, pw->pw_gecos, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, pw->pw_dir, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, pw->pw_shell, 0, TRUE);
+ }
+}
+
+static void
+m4_hostname (struct obstack *obs, int argc, token_data **argv)
+{
+ char buf[1024];
+
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+
+ if (gethostname(buf, sizeof buf) < 0)
+ return;
+
+ shipout_string (obs, buf, 0, FALSE);
+}
+
+static void
+m4_rand (struct obstack *obs, int argc, token_data **argv)
+{
+ int i;
+
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+
+ shipout_int(obs, rand());
+}
+
+static void
+m4_srand (struct obstack *obs, int argc, token_data **argv)
+{
+ char buf[64];
+ int seed;
+
+ if (bad_argc (argv[0], argc, 1, 2))
+ return;
+
+ if (argc == 1)
+ seed = time(0L) * getpid();
+ else
+ {
+ if (!numeric_arg(argv[0], ARG(1), &seed))
+ return;
+ }
+
+ srand(seed);
+}
+
+static void
+m4_uname (struct obstack *obs, int argc, token_data **argv)
+{
+ struct utsname ut;
+
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+
+ if (uname(&ut) == 0)
+ {
+ shipout_string (obs, ut.sysname, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, ut.nodename, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, ut.release, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, ut.machine, 0, TRUE);
+ obstack_1grow (obs, ',');
+ shipout_string (obs, ut.domainname, 0, TRUE);
+ }
+}
+
+static void
+m4_getuid (struct obstack *obs, int argc, token_data **argv)
+{
+ int i;
+
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+
+ shipout_int(obs, getuid());
+}
diff --git a/modules/stdlib.m4 b/modules/stdlib.m4
new file mode 100644
index 00000000..a023643d
--- /dev/null
+++ b/modules/stdlib.m4
@@ -0,0 +1,41 @@
+loadmodule(`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/modules/test.c b/modules/test.c
new file mode 100644
index 00000000..1a8a8092
--- /dev/null
+++ b/modules/test.c
@@ -0,0 +1,58 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1998 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <m4.h> /* These are obligatory */
+#include <builtin.h>
+
+module_init_t m4_init_module; /* initialisation function */
+module_finish_t m4_finish_module; /* cleanup function */
+
+DECLARE(test); /* declare test as implementing
+ a builtin */
+
+#undef DECLARE
+
+/* The table of builtins defined by this module - just one */
+
+builtin m4_macro_table[] =
+{
+ /* name GNUext macros blind function */
+ { "test", FALSE, FALSE, FALSE, test },
+ { 0, FALSE, FALSE, FALSE, 0 },
+};
+
+void
+m4_init_module(struct obstack *obs)
+{
+ char *s = "Test module loaded.";
+ obstack_grow (obs, s, strlen(s));
+}
+
+void
+m4_finish_module(void)
+{
+ return;
+}
+
+/* The functions for builtins can be static */
+static void
+test (struct obstack *obs, int argc, token_data **argv)
+{
+ char *s = "Test module called";
+ obstack_grow (obs, s, strlen(s));
+}
diff --git a/modules/test.m4 b/modules/test.m4
new file mode 100644
index 00000000..f8486578
--- /dev/null
+++ b/modules/test.m4
@@ -0,0 +1,3 @@
+loadmodule(`test.so')
+test
+Dumpdef: dumpdef(`test')
diff --git a/modules/test.test b/modules/test.test
new file mode 100755
index 00000000..6f0c335f
--- /dev/null
+++ b/modules/test.test
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# test.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+. ../../tests/config.sh
+
+cat ${srcdir}/test.m4 >in
+
+
+cat <<'EOF' >ok
+Test module loaded.
+Test module called.
+Dumpdef:
+EOF
+
+cat <<'EOF' >okerr
+test: <test>
+EOF
+
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -M `cd $srcdir; pwd` -d in >out 2>err
+sed -e "s,^[^:]*[lt-]*m4[.ex]*:,m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/modules/time.c b/modules/time.c
new file mode 100644
index 00000000..5f98e8a7
--- /dev/null
+++ b/modules/time.c
@@ -0,0 +1,193 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1998 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <m4.h>
+#include <builtin.h>
+
+#include <time.h>
+
+DECLARE(m4_currenttime);
+DECLARE(m4_ctime);
+DECLARE(m4_gmtime);
+DECLARE(m4_localtime);
+DECLARE(m4_mktime);
+DECLARE(m4_strftime);
+
+#undef DECLARE
+
+builtin m4_macro_table[] =
+{
+ /* name GNUext macros blind function */
+ { "currenttime", TRUE, FALSE, FALSE, m4_currenttime },
+ { "ctime", TRUE, FALSE, FALSE, m4_ctime },
+ { "gmtime", TRUE, FALSE, TRUE, m4_gmtime },
+ { "localtime", TRUE, FALSE, TRUE, m4_localtime },
+ { "mktime", TRUE, FALSE, TRUE, m4_mktime },
+ { "strftime", TRUE, FALSE, TRUE, m4_strftime },
+ { 0, FALSE, FALSE, FALSE, 0 },
+};
+
+
+
+static void
+m4_currenttime (struct obstack *obs, int argc, token_data **argv)
+{
+ char buf[64];
+ time_t now;
+ int l;
+
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+
+ now = time(0L);
+ l = sprintf(buf, "%ld", now);
+
+ obstack_grow (obs, buf, l);
+}
+
+static void
+m4_ctime (struct obstack *obs, int argc, token_data **argv)
+{
+ char buf[64];
+ time_t t;
+ int l;
+
+ if (bad_argc (argv[0], argc, 1, 2))
+ return;
+
+ if (argc == 2)
+ numeric_arg(argv[0], ARG(1), (int *)&t);
+ else
+ t = time(0L);
+
+ obstack_grow (obs, ctime(&t), 24);
+}
+
+static void
+format_tm(struct obstack *obs, struct tm *tm)
+{
+ shipout_int(obs, tm->tm_sec);
+ obstack_1grow(obs, ',');
+
+ shipout_int(obs, tm->tm_min);
+ obstack_1grow(obs, ',');
+
+ shipout_int(obs, tm->tm_hour);
+ obstack_1grow(obs, ',');
+
+ shipout_int(obs, tm->tm_mday);
+ obstack_1grow(obs, ',');
+
+ shipout_int(obs, tm->tm_mon);
+ obstack_1grow(obs, ',');
+
+ shipout_int(obs, tm->tm_year);
+ obstack_1grow(obs, ',');
+
+ shipout_int(obs, tm->tm_wday);
+ obstack_1grow(obs, ',');
+
+ shipout_int(obs, tm->tm_yday);
+ obstack_1grow(obs, ',');
+
+ shipout_int(obs, tm->tm_isdst);
+}
+
+static void
+m4_gmtime (struct obstack *obs, int argc, token_data **argv)
+{
+ time_t t;
+ struct tm *tm;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ if (!numeric_arg (argv[0], ARG (1), (int *)&t))
+ return;
+
+ format_tm(obs, gmtime(&t));
+}
+
+static void
+m4_localtime (struct obstack *obs, int argc, token_data **argv)
+{
+ time_t t;
+ struct tm *tm;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ if (!numeric_arg (argv[0], ARG (1), (int *)&t))
+ return;
+
+ format_tm(obs, localtime(&t));
+}
+
+/*-------------------------------------------.
+| mktime(sec,min,hour,mday,month,year,isdst) |
+`-------------------------------------------*/
+
+static void
+m4_mktime (struct obstack *obs, int argc, token_data **argv)
+{
+ struct tm tm;
+ time_t t;
+
+ if (bad_argc (argv[0], argc, 7, 8))
+ return;
+
+ if (!numeric_arg (argv[0], ARG (1), &tm.tm_sec))
+ return;
+ if (!numeric_arg (argv[0], ARG (2), &tm.tm_min))
+ return;
+ if (!numeric_arg (argv[0], ARG (3), &tm.tm_hour))
+ return;
+ if (!numeric_arg (argv[0], ARG (4), &tm.tm_mday))
+ return;
+ if (!numeric_arg (argv[0], ARG (5), &tm.tm_mon))
+ return;
+ if (!numeric_arg (argv[0], ARG (6), &tm.tm_year))
+ return;
+ if (ARG(7) && !numeric_arg (argv[0], ARG (7), &tm.tm_isdst))
+ return;
+
+ t = mktime(&tm);
+
+ shipout_int(obs, t);
+}
+
+static void
+m4_strftime (struct obstack *obs, int argc, token_data **argv)
+{
+ struct tm *tm;
+ time_t t;
+ char *buf;
+ int l;
+
+ if (bad_argc (argv[0], argc, 3, 3))
+ return;
+
+ if (!numeric_arg (argv[0], ARG (2), (int *)&t))
+ return;
+
+ tm = localtime(&t);
+
+ buf = (char *) obstack_alloc(obs, 1024);
+ l = strftime(buf, 1024, ARG(1), tm);
+ obstack_grow(obs, buf, l);
+}
diff --git a/modules/time.m4 b/modules/time.m4
new file mode 100644
index 00000000..e87f6bdf
--- /dev/null
+++ b/modules/time.m4
@@ -0,0 +1,16 @@
+loadmodule(`time.so')
+
+`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/modules/time.test b/modules/time.test
new file mode 100755
index 00000000..a2155e69
--- /dev/null
+++ b/modules/time.test
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# test.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+. ../../tests/config.sh
+
+cat <<'EOF' >in
+ifelse(regexp(currenttime, `^[1-9][0-9]*$'), 0, NUMERIC, NON NUMERIC)
+
+define(`sometime', 1890962700)dnl someones 65th birthday, hopefully
+`ctime' = ctime(sometime) != ctime(eval(sometime+60*60*24))
+gmtime = gmtime(sometime)
+localtime = localtime(sometime)
+define(`q', `$1,$2,$3,$4,$5,$6,$9')dnl
+
+sometime
+eval(sometime+60*60*24)
+localtime(eval(sometime+60*60*24))
+q(localtime(eval(sometime+60*60*24)))
+mktime = mktime(q(localtime(eval(sometime+60*60*24))))
+
+%A %B %d, %Y = strftime(`%A %B %d, %Y', sometime)
+%X on %x = strftime(`%X on %x', sometime)
+EOF
+
+cat <<'EOF' >ok
+NUMERIC
+
+ctime = Mon Dec 3 04:25:00 2029 != Tue Dec 4 04:25:00 2029
+gmtime = 0,25,3,3,11,129,1,336,0
+localtime = 0,25,4,3,11,129,1,336,0
+
+1890962700
+1891049100
+0,25,4,4,11,129,2,337,0
+0,25,4,4,11,129,0
+mktime = 1891049100
+
+%A %B %d, %Y = Monday December 03, 2029
+%X on %x = 04:25:00 on 12/03/29
+EOF
+
+cat <<'EOF' >okerr
+EOF
+
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -m time -M `cd $srcdir; pwd` -d in >out 2>err
+sed -e "s,^[^:]*[lt-]*m4[.ex]*:,m4:," err >sederr && mv sederr err
+$CMP -s out ok && $CMP -s err okerr
diff --git a/modules/time2.m4 b/modules/time2.m4
new file mode 100644
index 00000000..286f8bfd
--- /dev/null
+++ b/modules/time2.m4
@@ -0,0 +1,14 @@
+`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/po/ChangeLog b/po/ChangeLog
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/po/ChangeLog
diff --git a/po/Makefile.in.in b/po/Makefile.in.in
new file mode 100644
index 00000000..85b34636
--- /dev/null
+++ b/po/Makefile.in.in
@@ -0,0 +1,254 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996 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 2, 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, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = $(prefix)/@DATADIRNAME@
+localedir = $(datadir)/locale
+gnulocaledir = $(prefix)/share/locale
+gettextsrcdir = $(prefix)/share/gettext/po
+subdir = po
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+
+CC = @CC@
+GENCAT = @GENCAT@
+GMSGFMT = PATH=../src:$$PATH @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = PATH=../src:$$PATH @XGETTEXT@
+MSGMERGE = PATH=../src:$$PATH msgmerge
+
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+
+INCLUDES = -I.. -I$(top_srcdir)/intl
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+SOURCES = cat-id-tbl.c
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(PACKAGE).pot \
+stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES)
+
+POTFILES = \
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+.SUFFIXES:
+.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat
+
+.c.o:
+ $(COMPILE) $<
+
+.po.pox:
+ $(MAKE) $(PACKAGE).pot
+ $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox
+
+.po.mo:
+ $(MSGFMT) -o $@ $<
+
+.po.gmo:
+ file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \
+ && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+ sed -f ../intl/po2msg.sed < $< > $*.msg \
+ && rm -f $@ && $(GENCAT) $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: cat-id-tbl.c $(CATALOGS)
+all-no:
+
+$(PACKAGE).pot: $(POTFILES)
+ $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \
+ --add-comments --keyword=_ --keyword=N_ \
+ --files-from=$(srcdir)/POTFILES.in
+ if [ ! -s $(PACKAGE).po ] \
+ || cmp -s $(PACKAGE).po $(srcdir)/$(PACKAGE).pot; then \
+ rm -f $(PACKAGE).po; \
+ else \
+ rm -f $(srcdir)/$(PACKAGE).pot \
+ && mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot; \
+ fi
+
+cat-id-tbl.c: stamp-cat-id
+stamp-cat-id: $(PACKAGE).pot
+ rm -f cat-id-tbl.tmp
+ sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \
+ | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp
+ if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \
+ rm cat-id-tbl.tmp; \
+ else \
+ echo cat-id-tbl.c changed; \
+ rm -f $(srcdir)/cat-id-tbl.c; \
+ mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \
+ fi
+ cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id
+
+
+install: install-exec install-data
+install-exec:
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(datadir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(datadir); \
+ fi
+ @catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ case "$$cat" in \
+ *.gmo) destdir=$(gnulocaledir);; \
+ *) destdir=$(localedir);; \
+ esac; \
+ lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \
+ dir=$$destdir/$$lang/LC_MESSAGES; \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $$dir; \
+ else \
+ $(top_srcdir)/mkinstalldirs $$dir; \
+ fi; \
+ if test -r $$cat; then \
+ $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ else \
+ $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \
+ fi; \
+ if test -r $$cat.m; then \
+ $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ if test -r $(srcdir)/$$cat.m ; then \
+ $(INSTALL_DATA) $(srcdir)/$$cat.m \
+ $$dir/$(PACKAGE)$(INSTOBJEXT).m; \
+ echo "installing $(srcdir)/$$cat as" \
+ "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \
+ else \
+ true; \
+ fi; \
+ fi; \
+ done
+ if test "$(PACKAGE)" = "gettext"; then \
+ if test -r $(MKINSTALLDIRS); then \
+ $(MKINSTALLDIRS) $(gettextsrcdir); \
+ else \
+ $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \
+ fi; \
+ cd $(srcdir) && \
+ $(INSTALL_DATA) Makefile.in.in $(gettextsrcdir)/Makefile.in.in; \
+ else \
+ : ; \
+ fi
+
+# Define this as empty until I found a useful application.
+installcheck:
+
+uninstall:
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+ rm -f $(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \
+ done
+ rm -f $(gettextsrcdir)/po-Makefile.in.in
+
+check: all
+
+cat-id-tbl.o: ../intl/libgettext.h
+
+dvi info tags TAGS ID:
+
+mostlyclean:
+ rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp
+ rm -fr *.o
+
+clean: mostlyclean
+
+distclean: clean
+ rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m
+
+maintainer-clean: distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: update-po $(DISTFILES)
+ dists="$(DISTFILES)"; \
+ for file in $$dists; do \
+ ln $(srcdir)/$$file $(distdir) 2> /dev/null \
+ || cp -p $(srcdir)/$$file $(distdir); \
+ done
+
+update-po: Makefile
+ $(MAKE) $(PACKAGE).pot
+ PATH=`pwd`/../src:$$PATH; \
+ cd $(srcdir); \
+ catalogs='$(CATALOGS)'; \
+ for cat in $$catalogs; do \
+ lang=`echo $$cat | sed 's/$(CATOBJEXT)$$//'`; \
+ mv $$lang.po $$lang.old.po; \
+ echo "$$lang:"; \
+ if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \
+ rm -f $$lang.old.po; \
+ else \
+ echo "msgmerge for $$cat failed!"; \
+ rm -f $$lang.po; \
+ mv $$lang.old.po $$lang.po; \
+ fi; \
+ done
+
+POTFILES: POTFILES.in
+ ( if test 'x$(srcdir)' != 'x.'; then \
+ posrcprefix='$(top_srcdir)/'; \
+ else \
+ posrcprefix="../"; \
+ fi; \
+ sed -e '/^#/d' -e '/^[ ]*$$/d' \
+ -e "s@.*@ $$posrcprefix& \\\\@" \
+ -e '$$s/\(.*\) \\/\1/' < $(srcdir)/POTFILES.in > POTFILES )
+
+Makefile: Makefile.in.in ../config.status POTFILES
+ cd .. \
+ && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \
+ $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644
index 00000000..2b770796
--- /dev/null
+++ b/po/POTFILES.in
@@ -0,0 +1 @@
+src/m4.c \ No newline at end of file
diff --git a/po/cat-id-tbl.c b/po/cat-id-tbl.c
new file mode 100644
index 00000000..45dec044
--- /dev/null
+++ b/po/cat-id-tbl.c
@@ -0,0 +1,72 @@
+/* Automatically generated by po2tbl.sed from m4.pot. */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libgettext.h"
+
+const struct _msg_ent _msg_tbl[] = {
+ {"", 1},
+ {"ERROR: Stack overflow. (Infinite define recursion?)", 2},
+ {"Try `%s --help' for more information.\n", 3},
+ {"Usage: %s [OPTION]... [FILE]...\n", 4},
+ {"\
+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\
+ -e, --interactive unbuffer output, ignore interrupts\n\
+ -E, --fatal-warnings stop execution after first warning\n\
+ -Q, --quiet, --silent suppress some warnings for builtins\n\
+ -P, --prefix-builtins force a `m4_' prefix to all builtins\n", 5},
+ {" -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n", 6},
+ {"\
+\n\
+Preprocessor features:\n\
+ -I, --include=DIRECTORY search this directory second for includes\n\
+ -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n\
+ -U, --undefine=NAME delete builtin NAME\n\
+ -s, --synclines generate `#line NO \"FILE\"' lines\n", 7},
+ {"\
+\n\
+Limits control:\n\
+ -G, --traditional suppress all GNU extensions\n\
+ -H, --hashsize=PRIME set symbol lookup hash table size\n\
+ -L, --nesting-limit=NUMBER change artificial nesting limit\n", 8},
+ {"\
+\n\
+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", 9},
+ {"\
+\n\
+Debugging:\n\
+ -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n\
+ -t, --trace=NAME trace NAME when it will be defined\n\
+ -l, --arglength=NUM restrict macro tracing size\n\
+ -o, --error-output=FILE redirect debug and trace output\n", 10},
+ {"\
+\n\
+FLAGS is any of:\n\
+ t trace for all macro calls, not only traceon'ed\n\
+ a show actual arguments\n\
+ e show expansion\n\
+ q quote values as necessary, with a or e flag\n\
+ c show before collect, after collect and after call\n\
+ x add a unique macro call id, useful with c flag\n\
+ f say current input file name\n\
+ l say current input line number\n\
+ p show results of path searches\n\
+ i show changes in input files\n\
+ V shorthand for all of the above flags\n", 11},
+ {"\
+\n\
+If no FILE or if FILE is `-', standard input is read.\n", 12},
+ {"Bad debug flags: `%s'", 13},
+ {"INTERNAL ERROR: Bad code in deferred arguments", 14},
+};
+
+int _msg_tbl_length = 14;
diff --git a/po/cs.gmo b/po/cs.gmo
new file mode 100644
index 00000000..69918181
--- /dev/null
+++ b/po/cs.gmo
Binary files differ
diff --git a/po/cs.po b/po/cs.po
new file mode 100644
index 00000000..5e355a64
--- /dev/null
+++ b/po/cs.po
@@ -0,0 +1,725 @@
+# Czech translation of the GNU m4.
+# Copyright (C) 1998 Free Software Foundation, Inc.
+# Jiøí Pavlovskư <pavlovsk@ff.cuni.cz>, 1998.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: m4 1.4n\n"
+"POT-Creation-Date: 2000-01-10 05:27+0100\n"
+"PO-Revision-Date: 1998-12-07 22:02+01:00\n"
+"Last-Translator: Jiøí Pavlovskư <pavlovsk@ff.cuni.cz>\n"
+"Language-Team: Czech <cs@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: lib/getopt.c:677
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr ""
+
+#: lib/getopt.c:702
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr ""
+
+#: lib/getopt.c:707
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr ""
+
+#: lib/getopt.c:725 lib/getopt.c:898
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr ""
+
+#. --option
+#: lib/getopt.c:754
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr ""
+
+#. +option or -option
+#: lib/getopt.c:758
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr ""
+
+#. 1003.2 specifies the format of this message.
+#: lib/getopt.c:784
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr ""
+
+#: lib/getopt.c:787
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr ""
+
+#. 1003.2 specifies the format of this message.
+#: lib/getopt.c:817 lib/getopt.c:947
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr ""
+
+#: lib/getopt.c:864
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr ""
+
+#: lib/getopt.c:882
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr ""
+
+#: lib/obstack.c:471
+msgid "memory exhausted"
+msgstr ""
+
+#: lib/regex.c:1019
+msgid "Success"
+msgstr ""
+
+#: lib/regex.c:1022
+msgid "No match"
+msgstr ""
+
+# , c-format
+#: lib/regex.c:1025
+#, fuzzy
+msgid "Invalid regular expression"
+msgstr "©patnư regulární vưraz `%s': %s"
+
+#: lib/regex.c:1028
+msgid "Invalid collation character"
+msgstr ""
+
+#: lib/regex.c:1031
+msgid "Invalid character class name"
+msgstr ""
+
+#: lib/regex.c:1034
+msgid "Trailing backslash"
+msgstr ""
+
+#: lib/regex.c:1037
+msgid "Invalid back reference"
+msgstr ""
+
+#: lib/regex.c:1040
+msgid "Unmatched [ or [^"
+msgstr ""
+
+#: lib/regex.c:1043
+msgid "Unmatched ( or \\("
+msgstr ""
+
+#: lib/regex.c:1046
+msgid "Unmatched \\{"
+msgstr ""
+
+#: lib/regex.c:1049
+msgid "Invalid content of \\{\\}"
+msgstr ""
+
+#: lib/regex.c:1052
+msgid "Invalid range end"
+msgstr ""
+
+#: lib/regex.c:1055 lib/xmalloc.c:82
+msgid "Memory exhausted"
+msgstr ""
+
+# , c-format
+#: lib/regex.c:1058
+#, fuzzy
+msgid "Invalid preceding regular expression"
+msgstr "Chyba pøi porovnávání regulárního vưrazu `%s'"
+
+#: lib/regex.c:1061
+#, fuzzy
+msgid "Premature end of regular expression"
+msgstr "Pøedèasnư konec zmrazeného souboru"
+
+# , c-format
+#: lib/regex.c:1064
+#, fuzzy
+msgid "Regular expression too big"
+msgstr "©patnư regulární vưraz `%s': %s"
+
+#: lib/regex.c:1067
+msgid "Unmatched ) or \\)"
+msgstr ""
+
+# , c-format
+#: lib/regex.c:5564
+#, fuzzy
+msgid "No previous regular expression"
+msgstr "Chyba pøi porovnávání regulárního vưrazu `%s'"
+
+# , c-format
+#: src/builtin.c:349
+#, c-format
+msgid "Warning: Too few arguments to built-in `%s'"
+msgstr "Varování: pøíli¹ málo argumentù pro vestav́né makro `%s'"
+
+# , c-format
+#: src/builtin.c:355
+#, c-format
+msgid "Warning: Excess arguments to built-in `%s' ignored"
+msgstr ""
+"Varování: pøíli¹ mnoho argumentù pro vestav́né makro `%s' - budou ignorovány"
+
+# , c-format
+#: src/builtin.c:383
+#, c-format
+msgid "Non-numeric argument to built-in `%s'"
+msgstr "Neèíselnư argument pro vestav́né makro `%s'"
+
+#: src/builtin.c:494
+msgid "INTERNAL ERROR: Bad token data type in define_macro ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư typ tokenu v define_macro ()"
+
+# , c-format
+#: src/builtin.c:681 src/builtin.c:780 src/builtin.c:1423 src/builtin.c:1447
+#, c-format
+msgid "Undefined name %s"
+msgstr "Jméno %s není definováno"
+
+#: src/builtin.c:721
+msgid "INTERNAL ERROR: Builtin not found in builtin table!"
+msgstr "VNITØNÍ CHYBA: Vestav́né makro nenalezeno v tabulce vestav́nưch maker!"
+
+#: src/builtin.c:729
+msgid "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư typ tokenu v m4_dumpdef ()"
+
+# , c-format
+#: src/builtin.c:804
+#, fuzzy, c-format
+msgid "Undefined name `%s'"
+msgstr "Jméno %s není definováno"
+
+#: src/builtin.c:842
+msgid "INTERNAL ERROR: Bad symbol type in m4_defn ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư typ symbolu v m4_defn ()"
+
+# , c-format
+#: src/builtin.c:908
+#, c-format
+msgid "Cannot open pipe to command `%s'"
+msgstr "Rouru do pøíkazu `%s' nelze otevøít"
+
+# , c-format
+#: src/builtin.c:948
+#, c-format
+msgid "Radix in eval out of range (radix = %d)"
+msgstr "Základ v makru eval je mimo rozsah (základ = %d)"
+
+#: src/builtin.c:957
+msgid "Negative width to eval"
+msgstr "Záporná ¹íøka v makru eval"
+
+# , c-format
+#: src/builtin.c:1063
+#, c-format
+msgid "Non-numeric argument to %s"
+msgstr "Neèíselnư argument pro %s"
+
+# , c-format
+#: src/builtin.c:1075
+#, c-format
+msgid "Cannot undivert %s"
+msgstr "Chyba pøi volání makra undivert pro %s"
+
+# , c-format
+#: src/builtin.c:1223
+#, c-format
+msgid "Undefined syntax code %c"
+msgstr "Syntaktickư kód %c není definován"
+
+# , c-format
+#: src/builtin.c:1274 src/freeze.c:211
+#, c-format
+msgid "Cannot open %s"
+msgstr "%s nelze otevøít"
+
+# , c-format
+#: src/builtin.c:1483
+#, c-format
+msgid "Debugmode: bad debug flags: `%s'"
+msgstr "Ladící mód: ¹patné ladící volby: `%s'"
+
+# , c-format
+#: src/builtin.c:1519
+#, c-format
+msgid "Cannot set error file: %s"
+msgstr "Chybovư soubor %s nelze pou¾ít"
+
+#: src/builtin.c:1740
+msgid "WARNING: \\0 will disappear, use \\& instead in replacements"
+msgstr "VAROVÁNÍ: \\0 zmizí, pøi nahrazování pou¾ijte \\&"
+
+# , c-format
+#: src/builtin.c:1801 src/builtin.c:1861 src/input.c:1014
+#, c-format
+msgid "Bad regular expression `%s': %s"
+msgstr "©patnư regulární vưraz `%s': %s"
+
+# , c-format
+#: src/builtin.c:1812 src/builtin.c:1885
+#, c-format
+msgid "Error matching regular expression `%s'"
+msgstr "Chyba pøi porovnávání regulárního vưrazu `%s'"
+
+#: src/debug.c:380
+msgid "INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"
+msgstr ""
+"VNITØNÍ CHYBA: vestav́né makro nenalezeno v tabulce vestav́nưch maker\n"
+"(trace_pre ())!"
+
+#: src/debug.c:388
+msgid "INTERNAL ERROR: Bad token data type (trace_pre ())"
+msgstr "VNITØNÍ CHYBA: ¹patnư typ tokenu (trace_pre ())"
+
+# , c-format
+#: src/eval.c:309
+#, c-format
+msgid "Bad expression in eval (missing right parenthesis): %s"
+msgstr "©patnư vưraz v makru eval (chybí pravá závorka): %s"
+
+# , c-format
+#: src/eval.c:315
+#, c-format
+msgid "Bad expression in eval: %s"
+msgstr "©patnư vưraz v makru eval: %s"
+
+# , c-format
+#: src/eval.c:320
+#, c-format
+msgid "Bad expression in eval (bad input): %s"
+msgstr "©patnư vưraz v makru eval (¹patnư vstup): %s"
+
+# , c-format
+#: src/eval.c:325
+#, c-format
+msgid "Bad expression in eval (excess input): %s"
+msgstr "©patnư vưraz v makru eval (nadbyteènư vstup): %s"
+
+# , c-format
+#: src/eval.c:330
+#, c-format
+msgid "Divide by zero in eval: %s"
+msgstr "D́lení nulou v makru eval: %s"
+
+# , c-format
+#: src/eval.c:335
+#, c-format
+msgid "Modulo by zero in eval: %s"
+msgstr "Modulo nulou v makru eval: %s"
+
+#: src/eval.c:340
+msgid "INTERNAL ERROR: Bad error code in evaluate ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư chybovư kód v evaluate ()"
+
+#: src/eval.c:594
+msgid "INTERNAL ERROR: Bad comparison operator in cmp_term ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư operátor porovnání v cmp_term ()"
+
+#: src/eval.c:639
+msgid "INTERNAL ERROR: Bad shift operator in shift_term ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư operátor posunu v shift_term ()"
+
+#: src/eval.c:738
+msgid "INTERNAL ERROR: Bad operator in mult_term ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư operátor v mult_term ()"
+
+#: src/freeze.c:119
+msgid "INTERNAL ERROR: Built-in not found in builtin table!"
+msgstr "VNITØNÍ CHYBA: Vestav́né makro nenalezeno v tabulce vestav́nưch maker!"
+
+#: src/freeze.c:132
+msgid "INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư typ tokenu ve freeze_one_symbol ()"
+
+#: src/freeze.c:163
+msgid "Expecting line feed in frozen file"
+msgstr "Ve zmrazeném souboru oèekáván LF"
+
+# , c-format
+#: src/freeze.c:165
+#, c-format
+msgid "Expecting character `%c' in frozen file"
+msgstr "Ve zmrazeném souboru oèekáván znak `%c'"
+
+#: src/freeze.c:222
+msgid "Ill-formated frozen file"
+msgstr "©patnư formát zmrazeného souboru"
+
+#: src/freeze.c:277 src/freeze.c:293
+msgid "Premature end of frozen file"
+msgstr "Pøedèasnư konec zmrazeného souboru"
+
+# , c-format
+#: src/freeze.c:327
+#, c-format
+msgid "`%s' from frozen file not found in builtin table!"
+msgstr "`%s' ze zmrazeného souboru nenalezeno v tabulce vestav́nưch maker!"
+
+# , c-format
+#: src/input.c:318
+#, c-format
+msgid "Input reverted to %s, line %d"
+msgstr "Vstup èten z %s, øádku %d"
+
+# , c-format
+#: src/input.c:346
+#, c-format
+msgid "Input read from %s"
+msgstr "Vstup èten z %s"
+
+#: src/input.c:506
+msgid "INTERNAL ERROR: Recursive push_string!"
+msgstr "VNITØNÍ CHYBA: rekurzivní push_string!"
+
+#: src/input.c:623
+msgid "INTERNAL ERROR: Bad call to init_macro_token ()"
+msgstr "VNITØNÍ CHYBA: ¹patné volání init_macro_token ()"
+
+#: src/input.c:663
+msgid "INTERNAL ERROR: Input stack botch in next_char ()"
+msgstr "VNITØNÍ CHYBA: chyba vstupního zásobníku v next_char ()"
+
+#: src/input.c:700
+msgid "INTERNAL ERROR: Input stack botch in peek_input ()"
+msgstr "VNITØNÍ CHYBA: chyba vstupního zásobníku v peek_input ()"
+
+#: src/input.c:805
+msgid "NONE"
+msgstr "®ÁDNƯ"
+
+#: src/input.c:1199 src/input.c:1226
+msgid "ERROR: EOF in string"
+msgstr "CHYBA: EOF v øet́zci"
+
+#: src/m4.c:119
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr "CHYBA: Pøeteèení zásobníku. (nekoneèná rekurze makra define?)"
+
+# , c-format
+#: src/m4.c:146
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Více informací získáte pøíkazem `%s --help'.\n"
+
+# , c-format
+#: src/m4.c:150
+#, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr "Pou¾ití: %s [PØEPÍNAÈ]... [SOUBOR]...\n"
+
+#: src/m4.c:151
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+"Povinné èi volitelné argumenty pro dlouhé pøepínaèe jsou povinné respektive\n"
+"volitelné i pro odpovídající pøepínaèe krátké.\n"
+"\n"
+"Chování programu:\n"
+" --help vypí¹e tuto nápov́du a skonèí\n"
+" --version vypí¹e oznaèení verze a skonèí\n"
+" -e, --interactive nebufferovanư vưstup, ignoruje pøeru¹ení\n"
+" -E, --fatal-warnings skonèí po prvním varování\n"
+" -Q, --quiet, --silent potlaèí ńkterá varování tưkající se\n"
+" vestav́nưch maker\n"
+" -P, --prefix-builtins v¹echna vestav́ná makra budou mít prefix "
+"`m4_'\n"
+
+#: src/m4.c:164
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr ""
+" -W, --word-regexp=REGVƯR syntaxe jmen maker bude urèena pomocí REGVƯR\n"
+
+#: src/m4.c:169
+msgid ""
+"\n"
+"Dynamic loading features:\n"
+" -m, --module-directory=DIRECTORY add DIRECTORY to the module search path\n"
+" -M, --load-module=MODULE load dynamic MODULE from M4MODPATH\n"
+msgstr ""
+
+#: src/m4.c:176
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+"\n"
+"Nastavení preprocesoru:\n"
+" -I, --include=ADRESÁØ ADRESÁØ bude druhư v poøadí pøi hledání\n"
+" vlo¾enưch souborù\n"
+" -D, --define=MAKRO[=HODNOTA] definuje MAKRO mající HODNOTU, mù¾e bưt\n"
+" i prázdné\n"
+" -U, --undefine=MAKRO sma¾e vestav́né MAKRO\n"
+" -s, --synclines vlo¾í øádky tvaru `#line ÈÍSLO \"SOUBOR\"'\n"
+
+#: src/m4.c:184
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+"\n"
+"Nastavení limitù:\n"
+" -G, --traditional vypne roz¹íøení GNU\n"
+" -H, --hashsize=PRVOÈÍSLO velikost hash tabulky pro vyhledávání "
+"symbolù\n"
+" -L, --nesting-limit=ÈÍSLO nastaví limit pro vnoøená volání maker\n"
+
+#: src/m4.c:191
+msgid ""
+"\n"
+"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"
+msgstr ""
+"\n"
+"Zmrazené soubory:\n"
+" -F, --freeze-state=SOUBOR pøi ukonèení ulo¾í zmrazenư stav do SOUBORU\n"
+" -R, --reload-state=SOUBOR pøi startu naète zmrazenư stav ze SOUBORU\n"
+
+#: src/m4.c:197
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+"\n"
+"Lad́ní:\n"
+" -d, --debug=[VOLBY] nastaví úrovẹ lad́ní (pokud nejsou VOLBY\n"
+" zadány, pak implicitń `aeq')\n"
+" -t, --trace=MAKRO sleduje MAKRO, kdy¾ je definováno\n"
+" -l, --arglength=POÈET reguluje poèet vưstupních informací\n"
+" ze sledování maker\n"
+" -o, --error-output=SOUBOR pøesḿruje vưstup lad́ní a sledování do "
+"SOUBORU\n"
+
+#: src/m4.c:205
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+"\n"
+"VOLBOU mù¾e bưt cokoliv z:\n"
+" t sleduje v¹echna makra, nejenom ta urèená pomocí traceon\n"
+" a vypí¹e aktuální argumenty\n"
+" e vypí¹e expanzi\n"
+" q dle potøeby uzavøe hodnoty mezi apostrofy, s volbami a nebo e\n"
+" c vypí¹e hodnoty pøed a po vyhodnocení argumentù a po volání makra\n"
+" x bude vypisovat jedineèné ID volání makra, u¾iteèné s volbou c\n"
+" f bude vypisovat jméno vstupního souboru\n"
+" l bude vypisovat èíslo vstupního øádku\n"
+" p vypí¹e informace o nalezení zadaného souboru\n"
+" i vypí¹e informace o ka¾dé zḿń vstupního souboru\n"
+" V zkratka pro v¹echny vư¹e uvedené volby\n"
+
+#: src/m4.c:220
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+"\n"
+"Jestli¾e SOUBOR není zadán, nebo je SOUBOR `-', pak je èten standardní "
+"vstup.\n"
+
+#: src/m4.c:225
+msgid ""
+"\n"
+"Report bugs to <bug-m4@gnu.org>.\n"
+msgstr ""
+"\n"
+"Chyby v programu oznamujte na adrese <bug-m4@gnu.org> (anglicky).\n"
+"Pøipomínky k pøekladu zasílejte na adresu <cs@li.org> (èesky).\n"
+
+# , c-format
+#: src/m4.c:414
+#, c-format
+msgid "Bad debug flags: `%s'"
+msgstr "©patné ladící volby: `%s'"
+
+#: src/m4.c:436
+#, c-format
+msgid "ERROR: failed to add search directory `%s'"
+msgstr ""
+
+#: src/m4.c:440
+#, c-format
+msgid "ERROR: failed to add search directory `%s': %s"
+msgstr ""
+
+#: src/m4.c:460
+msgid " (options:"
+msgstr " (pøelo¾eno s volbami:"
+
+#: src/m4.c:542
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr "VNITØNÍ CHYBA: ¹patnư kód v odlo¾enưch argumentech"
+
+#: src/macro.c:97
+msgid "INTERNAL ERROR: Bad token type in expand_token ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư typ tokenu v expand_token ()"
+
+#: src/macro.c:163
+msgid "ERROR: EOF in argument list"
+msgstr "CHYBA: EOF v seznamu argumentù"
+
+#: src/macro.c:182
+msgid "INTERNAL ERROR: Bad token type in expand_argument ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư typ tokenu v expand_argument ()"
+
+#: src/macro.c:259
+msgid "INTERNAL ERROR: Bad symbol type in call_macro ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư typ symbolu v call_macro ()"
+
+# , c-format
+#: src/macro.c:288
+#, c-format
+msgid "ERROR: Recursion limit of %d exceeded, use -L<N> to change it"
+msgstr "CHYBA: pøekroèen limit pro rekurzi (%d), zṃ́te jej pomocí -L<N>"
+
+# , c-format
+#: src/module.c:123
+#, fuzzy, c-format
+msgid "ERROR: failed to initialise modules: %s"
+msgstr "CHYBA: modul `%s' nelze nalézt: %s"
+
+# , c-format
+#: src/module.c:221
+#, fuzzy, c-format
+msgid "ERROR: cannot find module: `%s'"
+msgstr "CHYBA: modul `%s' nelze nalézt"
+
+# , c-format
+#: src/module.c:224
+#, fuzzy, c-format
+msgid "ERROR: cannot find module: `%s': %s"
+msgstr "CHYBA: modul `%s' nelze nalézt: %s"
+
+# , c-format
+#: src/module.c:274
+#, fuzzy
+msgid "ERROR: cannot close modules"
+msgstr "CHYBA: modul `%s' nelze nalézt"
+
+# , c-format
+#: src/module.c:277
+#, fuzzy, c-format
+msgid "ERROR: cannot cannot close modules: %s"
+msgstr "CHYBA: modul `%s' nelze nalézt: %s"
+
+# , c-format
+#: src/module.c:284
+#, fuzzy, c-format
+msgid "ERROR: cannot close module: `%s'"
+msgstr "CHYBA: modul `%s' nelze nalézt"
+
+# , c-format
+#: src/module.c:288
+#, fuzzy, c-format
+msgid "ERROR: cannot cannot close module: `%s': %s"
+msgstr "CHYBA: modul `%s' nelze nalézt: %s"
+
+#: src/output.c:262
+msgid "ERROR: Cannot create temporary file for diversion"
+msgstr "CHYBA: doèasnư soubor pro ulo¾ení odlo¾eného vưstupu nelze vytvoøit"
+
+#: src/output.c:272
+msgid "ERROR: Cannot flush diversion to temporary file"
+msgstr "CHYBA: odlo¾enư vưstup nelze zapsat do doèasného souboru"
+
+#: src/output.c:356
+msgid "ERROR: Copying inserted file"
+msgstr "CHYBA: pøi zapisování vlo¾eného souboru"
+
+#: src/output.c:537
+msgid "ERROR: Reading inserted file"
+msgstr "CHYBA: pøi ètení vlo¾eného souboru"
+
+#: src/output.c:636
+msgid "Cannot stat diversion"
+msgstr "Chyba pøi volání funkce stat pro soubor obsahující odlo¾enư vưstup"
+
+#: src/output.c:639
+msgid "Diversion too large"
+msgstr ""
+
+# , c-format
+#: src/path.c:157
+#, c-format
+msgid "Path search for `%s' found `%s'"
+msgstr "Hledán soubor `%s', nalezen soubor `%s'"
+
+#. sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+#. if the stack limit has not been reached.
+#: src/stackovf.c:175
+msgid "VMEM limit exceeded?\n"
+msgstr "Pøekroèen VMEM limit?\n"
+
+#: src/stackovf.c:197
+msgid ""
+"Memory bounds violation detected (SIGSEGV). Either a stack overflow\n"
+"occurred, or there is a bug in "
+msgstr ""
+"Neoprávńnư pøístup do paḿti (SIGSEGV). Jedná se buï o pøeteèení "
+"zásobníku,\n"
+"nebo o chybu "
+
+#: src/stackovf.c:202
+msgid ". Check for possible infinite recursion.\n"
+msgstr ". Prov́øte, zda se nejedná o nekoneènou rekurzi.\n"
+
+#: src/symtab.c:190
+msgid "INTERNAL ERROR: Illegal mode to symbol_lookup ()"
+msgstr "VNITØNÍ CHYBA: ¹patnư mód pro symbol_lookup ()"
+
+# , c-format
+#: src/symtab.c:243
+#, c-format
+msgid "Name `%s' is unknown\n"
+msgstr "Jméno `%s' není známo\n"
+
+# , c-format
+#~ msgid "Undefined macro `%s'"
+#~ msgstr "Makro `%s' není definováno"
+
+# , c-format
+#~ msgid "Module search for `%s' found `%s'"
+#~ msgstr "Hledán modul `%s', nalezen modul `%s'"
diff --git a/po/de.gmo b/po/de.gmo
new file mode 100644
index 00000000..d61f7983
--- /dev/null
+++ b/po/de.gmo
Binary files differ
diff --git a/po/de.po b/po/de.po
new file mode 100644
index 00000000..f6c51f48
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,507 @@
+# German translation for the GNU m4 messages
+# Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+# Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995
+# Martin von Löwis <martin@mira.isdn.cs.tu-berlin.de>, 1996
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: m4 1.4.3\n"
+"POT-Creation-Date: 1998-08-03 17:14+0200\n"
+"PO-Revision-Date: 1996-09-30 10:38 GMT+0100\n"
+"Last-Translator: Martin von Löwis <martin@mira.isdn.cs.tu-berlin.de>\n"
+"Language-Team: German <de@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: src/builtin.c:272
+#, c-format
+msgid "Warning: Too few arguments to built-in `%s'"
+msgstr "Warnung: Zu wenig Argumente für eingebaute Funktion `%s'"
+
+#: src/builtin.c:278
+#, c-format
+msgid "Warning: Excess arguments to built-in `%s' ignored"
+msgstr ""
+"Warnung: Überschüssige Argumente für eingebaute Funktion `%s' ignoriert"
+
+#: src/builtin.c:298
+#, c-format
+msgid "Non-numeric argument to built-in `%s'"
+msgstr "Nicht-numerisches Argument in eingebauter Funktion `%s'"
+
+#: src/builtin.c:438
+msgid "INTERNAL ERROR: Bad token data type in define_macro ()"
+msgstr "INTERNER FEHLER: Falscher Datentyp des Tokens in define_macro ()"
+
+#: src/builtin.c:608 src/builtin.c:671 src/builtin.c:1188 src/builtin.c:1212
+#, c-format
+msgid "Undefined name %s"
+msgstr "Name %s nicht definiert"
+
+#: src/builtin.c:636
+msgid "INTERNAL ERROR: Builtin not found in builtin table!"
+msgstr "INTERNER FEHLER: Eingebaute Funktion nicht in Tabelle gefunden!"
+
+#: src/builtin.c:644
+msgid "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"
+msgstr "INTERNER FEHLER: Falscher Datentyp des Tokens in m4_dumpdef ()"
+
+#: src/builtin.c:695
+#, c-format
+msgid "Undefined macro `%s'"
+msgstr "Makro `%s' nicht definiert"
+
+#: src/builtin.c:735
+msgid "INTERNAL ERROR: Bad symbol type in m4_defn ()"
+msgstr "INTERNER FEHLER: Falscher Symboltyp in m4_defn ()"
+
+#: src/builtin.c:772
+#, c-format
+msgid "Cannot open pipe to command `%s'"
+msgstr "Kann keine `pipe' für Kommando `%s' öffnen"
+
+#: src/builtin.c:811
+#, c-format
+msgid "Radix in eval out of range (radix = %d)"
+msgstr "Basis in `eval' nicht in den Grenzen (Basis = %d)"
+
+#: src/builtin.c:820
+msgid "Negative width to eval"
+msgstr "Negative Breite in `eval'"
+
+#: src/builtin.c:925
+#, c-format
+msgid "Non-numeric argument to %s"
+msgstr "Nicht-numerisches Argument in %s"
+
+#: src/builtin.c:937
+#, c-format
+msgid "Cannot undivert %s"
+msgstr "Kann Umleitung %s nicht aufheben"
+
+#: src/builtin.c:1043 src/freeze.c:207
+#, c-format
+msgid "Cannot open %s"
+msgstr "Kann %s nicht öffnen"
+
+#: src/builtin.c:1248
+#, c-format
+msgid "Debugmode: bad debug flags: `%s'"
+msgstr "Debug Modus: falsche Debug Flags: `%s'"
+
+#: src/builtin.c:1284
+#, c-format
+msgid "Cannot set error file: %s"
+msgstr "Kann Fehlerdatei nicht vorbereiten: %s"
+
+#: src/builtin.c:1501
+msgid "WARNING: \\0 will disappear, use \\& instead in replacements"
+msgstr "WARNUNG: \\0 wird wegfallen, benutze \\& stattdessen"
+
+#: src/builtin.c:1562 src/builtin.c:1622 src/input.c:637
+#, c-format
+msgid "Bad regular expression `%s': %s"
+msgstr "Falscher regulärer Ausdruck `%s': %s"
+
+#: src/builtin.c:1573 src/builtin.c:1646
+#, c-format
+msgid "Error matching regular expression `%s'"
+msgstr "Fehler beim Erkennen des regulären Ausdrucks `%s'"
+
+#: src/debug.c:379
+msgid "INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"
+msgstr ""
+"INTERNER FEHLER: Eingebaute Funktion nicht in Tabelle gefunden! (trace_pre "
+"())"
+
+#: src/debug.c:387
+msgid "INTERNAL ERROR: Bad token data type (trace_pre ())"
+msgstr "INTERNER FEHLER: Falscher Datentyp des Tokens (trace_pre ())"
+
+#: src/eval.c:277
+#, c-format
+msgid "Bad expression in eval (missing right parenthesis): %s"
+msgstr "Falscher Ausdruck in `eval' (fehlende rechte Klammer): %s"
+
+#: src/eval.c:283
+#, c-format
+msgid "Bad expression in eval: %s"
+msgstr "Falscher Ausdruck in `eval': %s"
+
+#: src/eval.c:288
+#, c-format
+msgid "Bad expression in eval (bad input): %s"
+msgstr "Falscher Ausdruck in `eval' (falsche Eingabe): %s"
+
+#: src/eval.c:293
+#, c-format
+msgid "Bad expression in eval (excess input): %s"
+msgstr "Falscher Ausdruck in `eval' (zu große Eingabe): %s"
+
+#: src/eval.c:298
+#, c-format
+msgid "Divide by zero in eval: %s"
+msgstr "Division durch Null in `eval': %s"
+
+#: src/eval.c:303
+#, c-format
+msgid "Modulo by zero in eval: %s"
+msgstr "Modulo Null in `eval': %s"
+
+#: src/eval.c:308
+msgid "INTERNAL ERROR: Bad error code in evaluate ()"
+msgstr "INTERNER FEHLER: Falscher Fehlerkode in evaluate ()"
+
+#: src/eval.c:547
+msgid "INTERNAL ERROR: Bad comparison operator in cmp_term ()"
+msgstr "INTERNER FEHLER: Falscher Vergleichsoperator in cmp_term ()"
+
+#: src/eval.c:590
+msgid "INTERNAL ERROR: Bad shift operator in shift_term ()"
+msgstr "INTERNER FEHLER: Falscher Shift-Operator in shift_term ()"
+
+#: src/eval.c:674
+msgid "INTERNAL ERROR: Bad operator in mult_term ()"
+msgstr "INTERNER FEHLER: Falscher Operator in mult_term ()"
+
+#: src/freeze.c:115
+msgid "INTERNAL ERROR: Built-in not found in builtin table!"
+msgstr "INTERNER FEHLER: Eingebaute Funktion nicht in Tabelle gefunden!"
+
+#: src/freeze.c:128
+msgid "INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"
+msgstr "INTERNER FEHLER: Falscher Datentyp des Tokens in freeze_one_symbol ()"
+
+#: src/freeze.c:159
+msgid "Expecting line feed in frozen file"
+msgstr "Erwarte Zeilenumbruch in eingefrorener Datei"
+
+#: src/freeze.c:161
+#, c-format
+msgid "Expecting character `%c' in frozen file"
+msgstr "Erwarte Zeichen `%c' in eingefrorener Datei"
+
+#: src/freeze.c:218
+msgid "Ill-formated frozen file"
+msgstr "Fehlerhafte eingefrorene Datei"
+
+#: src/freeze.c:273 src/freeze.c:289
+msgid "Premature end of frozen file"
+msgstr "Vorzeitiges Ende der eingefrorenen Datei"
+
+#: src/freeze.c:323
+#, c-format
+msgid "`%s' from frozen file not found in builtin table!"
+msgstr ""
+"`%s' aus eingefrorener Datei nicht in Tabelle der eingebauten Funktionen "
+"gefunden!"
+
+#: src/input.c:174
+#, c-format
+msgid "Input read from %s"
+msgstr "Eingabe gelesen von %s"
+
+#: src/input.c:231
+msgid "INTERNAL ERROR: Recursive push_string!"
+msgstr "INTERNER FEHLER: Rekursives push_string!"
+
+#: src/input.c:311
+#, c-format
+msgid "Input reverted to %s, line %d"
+msgstr "Eingabe zurückgenommen zu %s, Zeile %d"
+
+#: src/input.c:325
+msgid "INTERNAL ERROR: Input stack botch in pop_input ()"
+msgstr ""
+"INTERNER FEHLER: Kellerspeicher der Eingabe durcheinander in pop_input ()"
+
+#: src/input.c:364
+msgid "INTERNAL ERROR: Bad call to init_macro_token ()"
+msgstr "INTERNER FEHLER: Falscher Aufruf von init_macro_token ()"
+
+#: src/input.c:413
+msgid "INTERNAL ERROR: Input stack botch in peek_input ()"
+msgstr ""
+"INTERNER FEHLER: Kellerspeicher der Eingabe durcheinander in peek_input ()"
+
+#: src/input.c:470
+msgid "INTERNAL ERROR: Input stack botch in next_char ()"
+msgstr ""
+"INTERNER FEHLER: Kellerspeicher der Eingabe durcheinander in next_char ()"
+
+# This is the name of the input file when there is no current input file.
+# Is this ever printed in a message?
+#: src/input.c:550
+msgid "NONE"
+msgstr "NONE"
+
+#: src/input.c:777
+msgid "ERROR: EOF in string"
+msgstr "FEHLER: Dateiende in Zeichenkette"
+
+#: src/m4.c:106
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr "FEHLER: Keller voll. (Unendliche `define' Rekursion?)"
+
+#: src/m4.c:133
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "`%s --help' zeigt weitere Informationen.\n"
+
+#: src/m4.c:137
+#, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr "Aufruf: %s [OPTION]... [DATEI]...\n"
+
+#: src/m4.c:138
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+"Notwendige bzw. optionale Argumente für Optionen der Langform sind auch \n"
+"für die Kurform notwendig bzw. optional.\n"
+"\n"
+"Operationsmodi:\n"
+" --help zeige diese Hilfe an und beende\n"
+" --version zeige Versionsinformation an und beende\n"
+" -e, --interactive keine Ausgabepufferung, ignoriere Interrupts\n"
+" -E, --fatal-warnings beende Ausführung nach erster Warnung\n"
+" -Q, --quiet, --silent unterdrücke Warnungen bei eingebauten "
+"Funktionen\n"
+" -P, --prefix-builtins erzwinge `m4_' Präfix für eingebaute "
+"Funktionen\n"
+
+#: src/m4.c:151
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr " -W, --word-regexp=REGEXP benutze REGEXP für Makronamensyntax\n"
+
+#: src/m4.c:155
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+"\n"
+"Präprozessoreigenschaften:\n"
+" -I, --include=VERZEICHNIS durchsuche VERZEICHNIS als zweites bei "
+"`include'\n"
+" -D, --define=NAME[=WERT] füge NAME mit WERT (oder leer) ein\n"
+" -U, --undefine=NAME lösche eingebaute Funktion NAME\n"
+" -s, --synclines erzeuge `#line NR \"DATEI\"' Zeilen\n"
+
+#: src/m4.c:163
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+"\n"
+"Setze Grenzen:\n"
+" -G, --traditional schalte alle GNU Erweiterungen aus\n"
+" -H, --hashsize=PRIMZAHL setze Größe der Symbol-Hashtabelle\n"
+" -L, --nesting-limit=NUMMER setze künstliche Grenze für "
+"Schachtelungstiefe\n"
+
+#: src/m4.c:170
+msgid ""
+"\n"
+"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"
+msgstr ""
+"\n"
+"Eingefrorene Dateien:\n"
+" -F, --freeze-state=DATEI erzeuge am Ende eine eingefrorene Form in "
+"DATEI\n"
+" -R, --reload-state=DATEI lade zu Beginn Zustand von eingefrorener "
+"DATEI\n"
+
+#: src/m4.c:176
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] setze Debuglevel (keine FLAGS bedeutet "
+"`aeq')\\\n"
+" -t, --trace=NAME verfolge NAME, wenn er definiert wird\n"
+" -l, --arglength=NUMMER beschränke Größe bei Macroverfolgung\n"
+" -o, --error-output=DATEI leite Debug- und Verfolgungsausgaben nach "
+"DATEI\n"
+
+#: src/m4.c:184
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+"\n"
+"FLAGS ist Kombination aus folgendem:\n"
+" t verfolge alle Makroaufrufe, nicht nur die von `traceon'\n"
+" a zeige aktuelle Argumente\n"
+" e zeige Ausdehnung\n"
+" q setze Werte in Anführungszeichen, wenn nötig, mit a- oder e-Flag\n"
+" c zeige vor und nach `collect' und nach Aufruf an\n"
+" x zeige für jeden Aufruf eindeutige Nummer an, hilfreich bei -c\n"
+" f gebe Namen der aktuellen Eingabedatei aus\n"
+" l gebe aktuelle Zeilennummer der Eingabezeile aus\n"
+" p gebe Ergebnis der Pfadsuche aus\n"
+" i gebe Veränderungen der Eingabedatei aus\n"
+" V Kurzform für alle Flags oben zusammen\n"
+
+#: src/m4.c:199
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+"\n"
+"Ohne DATEI oder wenn DATEI `-' ist, wird die Standardeingabe gelesen\n"
+
+#: src/m4.c:358
+#, c-format
+msgid "Bad debug flags: `%s'"
+msgstr "Falsche Debug Flags: `%s'"
+
+#: src/m4.c:437
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr "INTERNER FEHLER: Falscher Kode in zurückgestellten Argumenten"
+
+#: src/macro.c:92
+msgid "INTERNAL ERROR: Bad token type in expand_token ()"
+msgstr "INTERNER FEHLER: Falscher Datentyp des Tokens in expands_token ()"
+
+#: src/macro.c:158
+msgid "ERROR: EOF in argument list"
+msgstr "FEHLER: Dateiende in Argumentliste"
+
+#: src/macro.c:176
+msgid "INTERNAL ERROR: Bad token type in expand_argument ()"
+msgstr "INTERNER FEHLER: Falscher Typ des Tokens in expand_argument ()"
+
+#: src/macro.c:253
+msgid "INTERNAL ERROR: Bad symbol type in call_macro ()"
+msgstr "INTERNER FEHLER: Falsche Symboltyp in call_macro ()"
+
+#: src/macro.c:282
+#, c-format
+msgid "ERROR: Recursion limit of %d exceeded, use -L<N> to change it"
+msgstr ""
+"FEHLER: Grenze der Rekursion von %d überschritten, benutze -L<N> zur Änderung"
+
+#: src/output.c:198
+msgid "ERROR: Cannot create temporary file for diversion"
+msgstr "FEHLER: Kann keine temporäre Datei für Umleitung erzeugen"
+
+#: src/output.c:208
+msgid "ERROR: Cannot flush diversion to temporary file"
+msgstr "FEHLER: Kann Umleitung nicht in temporäre Datei ausgeben"
+
+#: src/output.c:292
+msgid "ERROR: Copying inserted file"
+msgstr "FEHLER: Während Kopieren einer eingefügten Datei"
+
+#: src/output.c:473
+msgid "ERROR: Reading inserted file"
+msgstr "FEHLER: Während Lesen einer eingefügten Datei"
+
+#: src/output.c:572
+msgid "Cannot stat diversion"
+msgstr "Kann `stat' nicht auf Umleitung anwenden"
+
+#: src/path.c:131
+#, c-format
+msgid "Path search for `%s' found `%s'"
+msgstr "Pfad für Suche nach `%s' hat `%s' gefunden"
+
+#. sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+#. if the stack limit has not been reached.
+#: src/stackovf.c:168
+msgid "VMEM limit exceeded?\n"
+msgstr "VMEM Beschränkung überschritten?\n"
+
+#: src/stackovf.c:190
+msgid ""
+"Memory bounds violation detected (SIGSEGV). Either a stack overflow\n"
+"occurred, or there is a bug in "
+msgstr ""
+"Verletzung der Speichergrenzen festgestellt (SIGSEGV). Entweder ist ein\n"
+"Stacküberlauf aufgetreten, oder es gibt einen Fehler in "
+
+#: src/stackovf.c:195
+msgid ". Check for possible infinite recursion.\n"
+msgstr ". Untersuche auf mögliche unendliche Rekursion.\n"
+
+#: src/symtab.c:190
+msgid "INTERNAL ERROR: Illegal mode to symbol_lookup ()"
+msgstr "INTERNER FEHLER: Illegaler Modus bei symbol_lookup ()"
+
+#: src/symtab.c:243
+#, c-format
+msgid "Name `%s' is unknown\n"
+msgstr "Name `%s' ist unbekannt\n"
+
+#~ msgid "Bad regular expression: `%s': %s"
+#~ msgstr "Falscher regulärer Ausdruck: `%s': %s"
+
+#~ msgid "%s: option `%s' is ambiguous\n"
+#~ msgstr "%s: Option `%s' ist mehrdeutig\n"
+
+#~ msgid "%s: option `--%s' doesn't allow an argument\n"
+#~ msgstr "%s: Option `--%s' erlaubt kein Argument\n"
+
+#~ msgid "%s: option `%c%s' doesn't allow an argument\n"
+#~ msgstr "%s: Option `%c%s' erlaubt kein Argument\n"
+
+#~ msgid "%s: option `%s' requires an argument\n"
+#~ msgstr "%s: Option `%s' verlangt ein Argument\n"
+
+#~ msgid "%s: unrecognized option `--%s'\n"
+#~ msgstr "%s: nicht erkannte Option `--%s'\n"
+
+#~ msgid "%s: unrecognized option `%c%s'\n"
+#~ msgstr "%s: nicht erkannte Option `%c%s'\n"
+
+#~ msgid "%s: illegal option -- %c\n"
+#~ msgstr "%s: illegale Option -- %c\n"
+
+#~ msgid "%s: invalid option -- %c\n"
+#~ msgstr "%s: ungültige Options -- %c\n"
+
+#~ msgid "%s: option requires an argument -- %c\n"
+#~ msgstr "%s: Option verlangt ein Argument -- %c\n"
+
+# Der aktuelle Ausdruck ist NULL und vorher gab es auch noch keinen.
+#~ msgid "No previous regular expression"
+#~ msgstr "Regulärer Ausdruck fehlt"
+
+#~ msgid "Memory exhausted"
+#~ msgstr "Speicher voll"
diff --git a/po/el.gmo b/po/el.gmo
new file mode 100644
index 00000000..479d0010
--- /dev/null
+++ b/po/el.gmo
Binary files differ
diff --git a/po/el.po b/po/el.po
new file mode 100644
index 00000000..4dd6ed1d
--- /dev/null
+++ b/po/el.po
@@ -0,0 +1,690 @@
+# Greek messages for GNU m4.
+# Copyright (C) 1999 Free Software Foundation, Inc.
+# Simos Xenitellis <S.Xenitellis@rhbnc.ac.uk>, 1999.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU m4 1.4n\n"
+"POT-Creation-Date: 2000-01-10 05:27+0100\n"
+"PO-Revision-Date: 1999-06-24 00:25+0000\n"
+"Last-Translator: Simos Xenitellis <S.Xenitellis@rhbnc.ac.uk>\n"
+"Language-Team: Greek <nls@tux.hellug.gr>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=iso-8859-7\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: lib/getopt.c:677
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr ""
+
+#: lib/getopt.c:702
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr ""
+
+#: lib/getopt.c:707
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr ""
+
+#: lib/getopt.c:725 lib/getopt.c:898
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr ""
+
+#. --option
+#: lib/getopt.c:754
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr ""
+
+#. +option or -option
+#: lib/getopt.c:758
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr ""
+
+#. 1003.2 specifies the format of this message.
+#: lib/getopt.c:784
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr ""
+
+#: lib/getopt.c:787
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr ""
+
+#. 1003.2 specifies the format of this message.
+#: lib/getopt.c:817 lib/getopt.c:947
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr ""
+
+#: lib/getopt.c:864
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr ""
+
+#: lib/getopt.c:882
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr ""
+
+#: lib/obstack.c:471
+msgid "memory exhausted"
+msgstr ""
+
+#: lib/regex.c:1019
+msgid "Success"
+msgstr ""
+
+#: lib/regex.c:1022
+msgid "No match"
+msgstr ""
+
+#: lib/regex.c:1025
+#, fuzzy
+msgid "Invalid regular expression"
+msgstr "ËÜèị̈ êáíïíéễ Ưêöñáóç `%s': %s"
+
+#: lib/regex.c:1028
+msgid "Invalid collation character"
+msgstr ""
+
+#: lib/regex.c:1031
+msgid "Invalid character class name"
+msgstr ""
+
+#: lib/regex.c:1034
+msgid "Trailing backslash"
+msgstr ""
+
+#: lib/regex.c:1037
+msgid "Invalid back reference"
+msgstr ""
+
+#: lib/regex.c:1040
+msgid "Unmatched [ or [^"
+msgstr ""
+
+#: lib/regex.c:1043
+msgid "Unmatched ( or \\("
+msgstr ""
+
+#: lib/regex.c:1046
+msgid "Unmatched \\{"
+msgstr ""
+
+#: lib/regex.c:1049
+msgid "Invalid content of \\{\\}"
+msgstr ""
+
+#: lib/regex.c:1052
+msgid "Invalid range end"
+msgstr ""
+
+#: lib/regex.c:1055 lib/xmalloc.c:82
+msgid "Memory exhausted"
+msgstr ""
+
+#: lib/regex.c:1058
+#, fuzzy
+msgid "Invalid preceding regular expression"
+msgstr "ÓöÜë́á óôï ôáßñéáó́á óôçí êáíïíéễ Ưêöñáóç `%s'"
+
+#: lib/regex.c:1061
+#, fuzzy
+msgid "Premature end of regular expression"
+msgstr "Đñüùñï ôƯëị̈ đáăù́Ưíïơ áñ÷åßïơ"
+
+#: lib/regex.c:1064
+#, fuzzy
+msgid "Regular expression too big"
+msgstr "ËÜèị̈ êáíïíéễ Ưêöñáóç `%s': %s"
+
+#: lib/regex.c:1067
+msgid "Unmatched ) or \\)"
+msgstr ""
+
+#: lib/regex.c:5564
+#, fuzzy
+msgid "No previous regular expression"
+msgstr "ÓöÜë́á óôï ôáßñéáó́á óôçí êáíïíéễ Ưêöñáóç `%s'"
+
+#: src/builtin.c:349
+#, c-format
+msgid "Warning: Too few arguments to built-in `%s'"
+msgstr "Đñïåéäïđïßçóç: Đïëư ëßăá ïñßó́áôá óôï åóùäḯḉƯíï `%s'"
+
+#: src/builtin.c:355
+#, c-format
+msgid "Warning: Excess arguments to built-in `%s' ignored"
+msgstr "Đñïåéäïđïßçóç: ÅđéđëƯïí ïñßó́áôá óôï åóùäḯḉƯíï `%s' áăíï̃èçêáí"
+
+#: src/builtin.c:383
+#, c-format
+msgid "Non-numeric argument to built-in `%s'"
+msgstr "̀ç-áñè́çôéêü üñéó́á óôï åóùäḯḉƯíï `%s'"
+
+#: src/builtin.c:494
+msgid "INTERNAL ERROR: Bad token data type in define_macro ()"
+msgstr ""
+"ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ ôưđị̈ äåäḯƯíïơ áíôéêåé́Ưíïơ óôï define_macro ()"
+
+#: src/builtin.c:681 src/builtin.c:780 src/builtin.c:1423 src/builtin.c:1447
+#, c-format
+msgid "Undefined name %s"
+msgstr "̀ç ïñéó́Ưíï üíḯá %s"
+
+#: src/builtin.c:721
+msgid "INTERNAL ERROR: Builtin not found in builtin table!"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ÅóùäḯḉƯíï äå âñƯèçêå óôï đßíáêá åóùäḯḉƯíùí!"
+
+#: src/builtin.c:729
+msgid "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ ôưđị̈ äåäḯƯíïơ áíôéêåé́Ưíïơ óôï m4_dumpdef ()"
+
+#: src/builtin.c:804
+#, fuzzy, c-format
+msgid "Undefined name `%s'"
+msgstr "̀ç ïñéó́Ưíï üíḯá %s"
+
+#: src/builtin.c:842
+msgid "INTERNAL ERROR: Bad symbol type in m4_defn ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ ôưđị̈ óớâüëïơ óôï m4_defn ()"
+
+#: src/builtin.c:908
+#, c-format
+msgid "Cannot open pipe to command `%s'"
+msgstr "Áäơíá́ßá áíïßắáôị̈ óùë̃íùóç̣ óôçí åíôïë̃ `%s'"
+
+#: src/builtin.c:948
+#, c-format
+msgid "Radix in eval out of range (radix = %d)"
+msgstr "Ç âÜóç óôçí áđïôß́çóç åßíáé åêôụ̈ ïñßïơ (âÜóç = %d)"
+
+#: src/builtin.c:957
+msgid "Negative width to eval"
+msgstr "Áñíçôéêü đëÜôị̈ óôçí áđïôß́çóç"
+
+#: src/builtin.c:1063
+#, c-format
+msgid "Non-numeric argument to %s"
+msgstr "̀ç áñéè́çôéêü üñéó́á óôï %s"
+
+#: src/builtin.c:1075
+#, c-format
+msgid "Cannot undivert %s"
+msgstr "Áäơíá́ßá åđáíáöïñỤ̈ ôïơ %s"
+
+#: src/builtin.c:1223
+#, c-format
+msgid "Undefined syntax code %c"
+msgstr "̀ç ïñéó́Ưíị̈ ê₫äéêạ́ óưíôáîç̣ %c"
+
+#: src/builtin.c:1274 src/freeze.c:211
+#, c-format
+msgid "Cannot open %s"
+msgstr "Áäơíá́ßá áíïßắáôị̈ ôïơ %s"
+
+#: src/builtin.c:1483
+#, c-format
+msgid "Debugmode: bad debug flags: `%s'"
+msgstr "ÊáôÜóôáóç áđïóöáë́Üôùóç̣: ëÜèị̈ óḉáßạ̊ áđïóöáë́Üôùóç̣: `%s'"
+
+#: src/builtin.c:1519
+#, c-format
+msgid "Cannot set error file: %s"
+msgstr "Áäơíá́ßá ñưè́éóç̣ ôïơ áñ÷åßïơ óöáë́Üôùí: %s"
+
+#: src/builtin.c:1740
+msgid "WARNING: \\0 will disappear, use \\& instead in replacements"
+msgstr ""
+"ĐÑÏÅÉÄÏĐÏÉÇÓÇ: Ôï \\0 èá åîáöáíéóôåß, êÜíåôå ÷ñ̃óç ôïơ \\& áíôßèåôá óôẹ́ "
+"áíôéêáôáóôÜóåẹ́"
+
+#: src/builtin.c:1801 src/builtin.c:1861 src/input.c:1014
+#, c-format
+msgid "Bad regular expression `%s': %s"
+msgstr "ËÜèị̈ êáíïíéễ Ưêöñáóç `%s': %s"
+
+#: src/builtin.c:1812 src/builtin.c:1885
+#, c-format
+msgid "Error matching regular expression `%s'"
+msgstr "ÓöÜë́á óôï ôáßñéáó́á óôçí êáíïíéễ Ưêöñáóç `%s'"
+
+#: src/debug.c:380
+msgid "INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"
+msgstr ""
+"ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ÅóùäḯḉƯíï äåí âñƯèçêå óôï đßíáêá åóùäḯḉƯíùí! "
+"(trace_pre ())"
+
+#: src/debug.c:388
+msgid "INTERNAL ERROR: Bad token data type (trace_pre ())"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ ôưđị̈ äåäḯƯíïơ áíôéêåé́Ưíïơ (trace_pre ())"
+
+#: src/eval.c:309
+#, c-format
+msgid "Bad expression in eval (missing right parenthesis): %s"
+msgstr "ËÜèị̈ Ưêöñáóç óôçí áđïôß́çóç (ëåßđåé äåîéÜ đáñƯíèåóç): %s"
+
+#: src/eval.c:315
+#, c-format
+msgid "Bad expression in eval: %s"
+msgstr "ËÜèị̈ Ưêöñáóç óôçí áđïôß́çóç: %s"
+
+#: src/eval.c:320
+#, c-format
+msgid "Bad expression in eval (bad input): %s"
+msgstr "ËÜèị̈ Ưêöñáóç óôçí áđïôß́çóç (ëÜèị̈ åßóïäị̈): %s"
+
+#: src/eval.c:325
+#, c-format
+msgid "Bad expression in eval (excess input): %s"
+msgstr "ËÜèị̈ Ưêöñáóç óôçí áđïôß́çóç (ơđåñâïëéễ åßóïäị̈): %s"
+
+#: src/eval.c:330
+#, c-format
+msgid "Divide by zero in eval: %s"
+msgstr "Äéáßñåóç ́å ́çäƯí óôçí áđïôß́çóç: %s"
+
+#: src/eval.c:335
+#, c-format
+msgid "Modulo by zero in eval: %s"
+msgstr "Ơđüëïéđï ́å ́çäƯí óôçí áđïôß́çóç: %s"
+
+#: src/eval.c:340
+msgid "INTERNAL ERROR: Bad error code in evaluate ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ ê₫äéêạ́ óöÜë́áôị̈ óôçí evaluate ()"
+
+#: src/eval.c:594
+msgid "INTERNAL ERROR: Bad comparison operator in cmp_term ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ ôåëåóộ̃ óưăêñéóç̣ óôï cmp_term ()"
+
+#: src/eval.c:639
+msgid "INTERNAL ERROR: Bad shift operator in shift_term ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ ôåëåóộ̃ ïëßóèçóç̣ óôï shift_term ()"
+
+#: src/eval.c:738
+msgid "INTERNAL ERROR: Bad operator in mult_term ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ ôåëåóộ̃ óôï mult_term ()"
+
+#: src/freeze.c:119
+msgid "INTERNAL ERROR: Built-in not found in builtin table!"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ÅóùäḯḉƯíï äå âñƯèçêå óôï đßíáêá åóùäḯḉƯíùí!"
+
+#: src/freeze.c:132
+msgid "INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"
+msgstr ""
+"ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ ôưđị̈ äåäḯƯíïơ áíôéêåé́Ưíïơ óôï freeze_one_symbol ()"
+
+#: src/freeze.c:163
+msgid "Expecting line feed in frozen file"
+msgstr "Áíá́åíüôáí `line feed' óôï đáăù́Ưíï áñ÷åßï"
+
+#: src/freeze.c:165
+#, c-format
+msgid "Expecting character `%c' in frozen file"
+msgstr "Áíá́åíüôáí ÷áñáêỗñạ́ `%c' óôï đáăù́Ưíï áñ÷åßï"
+
+#: src/freeze.c:222
+msgid "Ill-formated frozen file"
+msgstr "Êáêü-́ïñöïđïéḉƯíï đáăù́Ưíï áñ÷åßï"
+
+#: src/freeze.c:277 src/freeze.c:293
+msgid "Premature end of frozen file"
+msgstr "Đñüùñï ôƯëị̈ đáăù́Ưíïơ áñ÷åßïơ"
+
+#: src/freeze.c:327
+#, c-format
+msgid "`%s' from frozen file not found in builtin table!"
+msgstr "ôï `%s' áđü đáăù́Ưíï áñ÷åßï äå âñƯèçêå óôïí đßíáêá åóùäḯḉƯíùí"
+
+#: src/input.c:318
+#, c-format
+msgid "Input reverted to %s, line %d"
+msgstr "Ç åßóïäị̈ åđáíáöƯñèçêå óôï %s, ăñá́́̃ %d"
+
+#: src/input.c:346
+#, c-format
+msgid "Input read from %s"
+msgstr "Ç åßóïäị̈ áíáăí₫óôçêå áđü ôï %s"
+
+#: src/input.c:506
+msgid "INTERNAL ERROR: Recursive push_string!"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: Áíáäñḯéêü push_string!"
+
+#: src/input.c:623
+msgid "INTERNAL ERROR: Bad call to init_macro_token ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: Êáễ êë̃óç óôï init_macro_token ()"
+
+#: src/input.c:663
+msgid "INTERNAL ERROR: Input stack botch in next_char ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: Áëëïßùóç óôïßâạ́ åéóüäïơ óôï next_char ()"
+
+#: src/input.c:700
+msgid "INTERNAL ERROR: Input stack botch in peek_input ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: Áëëïßùóç óôïßâạ́ åéóüäïơ óôï peek_input ()"
+
+#: src/input.c:805
+msgid "NONE"
+msgstr "ÊÁÍÅÍÁ"
+
+#: src/input.c:1199 src/input.c:1226
+msgid "ERROR: EOF in string"
+msgstr "ÓÖÁË̀Á: EOF óôï áëöáñéè́çôéêü"
+
+#: src/m4.c:119
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr "ÓÖÁË̀Á: Ơđåñ÷åßëçóç óôïßâạ́. (Áíáäñḯ̃ áđåßñïơ âÜèïợ;)"
+
+#: src/m4.c:146
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Äïêé́Üóôå `%s --help' ăéá đåñéóóüôåñç âï̃èåéá.\n"
+
+#: src/m4.c:150
+#, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr "×ñ̃óç: %s [ÅĐÉËÏĂÇ]... [ÁÑ×ÅÉÏ]...\n"
+
+#: src/m4.c:151
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+"Ơđï÷ñåùôéêÜ ̃ đñïáéñåôéêÜ ïñßó́áôá óå ́áêñỰ åđéëïăỰ åßíáé ơđï÷ñåùôéêÜ ̃ "
+"đñïáéñåôéêÜ\n"
+"êáé ăéá ôç̣ óưíôḯạ̊ åđéëïăỰ åđßóåẹ́.\n"
+"\n"
+"ÊáôáóôÜóåẹ́ ëåéôïơñăßạ́:\n"
+" --help ǻöÜíéóç áơộ̃ ôç̣ âï̃èåéạ́ êáé Ưîïäị̈\n"
+" --version ǻöÜíéóç đëçñïöïñé₫í Ưêäïóç̣ êáé Ưîïäị̈\n"
+" -e, --interactive Ưîïäị̈ ÷ùñß̣ åíôá́éåơỗ, áăíüçóç äéáêïđ₫í\n"
+" -E, --fatal-warnings äéáêïđ̃ åêôƯëåóç̣ ́åôÜ áđü ôç đñ₫ôç "
+"đñïåéäïđïßçóç\n"
+" -Q, --quiet, --silent áđüêñơøç ́åñéê₫í đñïåéäïđïé̃óåùí óôá "
+"åóùäḯḉƯíá\n"
+" -P, --prefix-builtins åđéâïë̃ đñïèỨáôị̈ `m4_' óå üëá ôá "
+"åóùäḯḉƯíá\n"
+
+#: src/m4.c:164
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr ""
+" -W --word-regexp=ÊÁÍÅÊÖ ÷ñ̃óç ÊÁÍïíéệ̃ ¸ÊÖñáóç̣ óôï óơíôáêôéêü ôç̣ "
+"́áêñïåíôïẹ̈̃\n"
+
+#: src/m4.c:169
+msgid ""
+"\n"
+"Dynamic loading features:\n"
+" -m, --module-directory=DIRECTORY add DIRECTORY to the module search path\n"
+" -M, --load-module=MODULE load dynamic MODULE from M4MODPATH\n"
+msgstr ""
+
+#: src/m4.c:176
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+"\n"
+"×áñáêôçñéóôéêÜ đñïåđåîåñăáóỗ:\n"
+" -I, --include=ÊÁÔÁËÏĂÏÓ øÜîé́ï ́åôÜ êáé óôï êáôÜëïăï áơôü ăéá "
+"đåñéëá́âáíǘåíá\n"
+" -D, --define=ÏÍÏ̀Á[=ÔÉ̀Ç] åéóáăùẵ Ïͼ́áôị̈ ́å ÔÉ̀Ç, ̃ êåíü\n"
+" -U, --undefine=ÏÍÏ̀Á äéáăñáö̃ åóùäḯḉƯíïơ Ïͼ̀Áôị̈\n"
+" -s, --synclines äḉéïơñăßá ăñá́́₫í `#line ÁÑÉÈ̀ÏÓ "
+"\"ÁÑ×ÅÉÏ\"'\n"
+
+#: src/m4.c:184
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+"\n"
+"¸ëåă÷ị̈ đåñéïñéó́₫í:\n"
+" -G, --traditional áđüêñơøç üëùí ôùí åđåêôÜóåùí GNU\n"
+" -H, --hashsize=ĐÑÙÔÏÓ ïñéó́ụ̈ ́åăƯèïợ đßíáêá áíáæ̃ôçóç̣ óớâüëïơ\n"
+" -L, --nesting-limit=ÁÑÉÈ̀ÏÓ áëëáẵ ôå÷íçôïư ïñßïơ öùëéáó́₫í\n"
+
+#: src/m4.c:191
+msgid ""
+"\n"
+"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"
+msgstr ""
+"\n"
+"Áñ÷åßá đáăù́Ưíç̣ êáôÜóôáóç̣:\n"
+" -F, --freeze-state=ARXEIO äḉéïơñăßá đáăù́Ưíç̣ êáôÜóôáóç̣ óôï ÁÑ×ÅÉÏ "
+"óôï ôƯëị̈\n"
+" -R, --reload-state=ARXEIO öüñôù́á îáíÜ đáăù́Ưíç̣ êáôÜóôáóç̣ áđü ÁÑ×ÅÉÏ "
+"óôçí åêêßíçóç\n"
+
+#: src/m4.c:197
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+"\n"
+"Åêóöáë́Üôùóç:\n"
+" -d, --debug=[ÓÇ̀ÁÉÅÓ] ïñéó́ụ̈ åđéđƯäïơ åêóöáë́Üôùóç̣ (÷ùñß̣ ÓÇ̀ÁÉÅÓ "
+"ơđïíïåß `aeq')\n"
+" -t, --trace=ONOMA áíß÷íåơóç Ïͼ̀Áôị̈ üôáí áơôü èá ïñéóôåß\n"
+" -l, --arglength=ÁÑÉÈ̀ đåñéïñéó́ụ̈ ́åăƯèïợ áíß÷íåơóç̣ ́áêñïåíôïẹ̈̃\n"
+" -o, --error-output=ÁÑ×ÅÉÏ åđáíáêáôåưèơíóç åîüäïơ åêóöáë́Üôùóç̣ êáé "
+"áíß÷íåơóç̣\n"
+
+#: src/m4.c:205
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+"\n"
+"ÓÇ̀ÁÉÅÓ ́đïñåß íá åßíáé ïđïéä̃đïôå áđü:\n"
+" t áíß÷íåơóç üëùí ôùí êë̃óåùí ôùí ́áêñïåíôïë₫í, ü÷é ́üíï áơôỰ đïơ Ư÷ïơí "
+"ïñéóôåß\n"
+" a ǻöÜíéóç đñáắáôéê₫í ïñéó́Üôùí\n"
+" e ǻöÜíéóç áíÜđôơîç̣\n"
+" q đáñÜèåóå ôé́Ự üđụ̀ ÷ñåéÜæåôáé, ́å ôẹ́ óḉáßạ̊ a ̃ e\n"
+" c ǻöÜíéóç đñéí ôç óơëëïẵ, ́åôÜ ôç óơëëïẵ êáé ́åôÜ ôç êë̃óç\n"
+" x đñüóèåóç ́ïíáäéệ̃ ôáơôüôçôạ́ êë̃óç̣ ́áêñïåíôïẹ̈̃, ÷ñ̃óé́ï ́å ôç "
+"óḉáßá c\n"
+" f ǻöÜíéóç ôñƯ÷ïíôị̈ ïíǘáôị̈ áñ÷åßïơ åéóüäïơ\n"
+" l ǻöÜíéóç áñéè́ü ôñå÷ïưóç̣ ăñạ́́́̃ åéóüäïơ\n"
+" p ǻöÜíéóç áđïôåëåó́Üôùí áđü Ưñåơíạ̊ óôï ́ïíïđÜôé\n"
+" i ǻöÜíéóç áëëáă₫í óôá áñ÷åßá åéóüäïơ\n"
+" V óơíôḯïăñáößá ăéá üëạ̊ ôẹ́ đáñáđÜíù óḉáßạ̊\n"
+
+#: src/m4.c:220
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+"\n"
+"×ùñß̣ ÁÑ×ÅÉÏ, ̃ üôáí ôï áñ÷åßï åßíáé ôï -, áíÜăíùóç áđü ôçí êáíïíéễ "
+"åßóïäï.\n"
+
+#: src/m4.c:225
+msgid ""
+"\n"
+"Report bugs to <bug-m4@gnu.org>.\n"
+msgstr ""
+"\n"
+"ÁíáöƯñáôå óöÜë́áôá óôï <bug-m4@gnu.org>.\n"
+
+#: src/m4.c:414
+#, c-format
+msgid "Bad debug flags: `%s'"
+msgstr "ËÜèị̈ óḉáßạ̊ åêóöáë́Üôùóç̣: `%s'"
+
+#: src/m4.c:436
+#, c-format
+msgid "ERROR: failed to add search directory `%s'"
+msgstr ""
+
+#: src/m4.c:440
+#, c-format
+msgid "ERROR: failed to add search directory `%s': %s"
+msgstr ""
+
+#: src/m4.c:460
+msgid " (options:"
+msgstr " (åđéëïăỰ:"
+
+#: src/m4.c:542
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ êùäéêụ̈ óôá áíáöåñǘåíá ïñßó́áôá"
+
+#: src/macro.c:97
+msgid "INTERNAL ERROR: Bad token type in expand_token ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ åßäị̈ áíôéêåé́Ưíïơ óôï expand_token ()"
+
+#: src/macro.c:163
+msgid "ERROR: EOF in argument list"
+msgstr "ÓÖÁË̀Á: EOF óôç ëßóôá ïñéó́Üôùí"
+
+#: src/macro.c:182
+msgid "INTERNAL ERROR: Bad token type in expand_argument ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ åßäị̈ áíôéêåé́Ưíïơ óôï expand_argument ()"
+
+#: src/macro.c:259
+msgid "INTERNAL ERROR: Bad symbol type in call_macro ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: ËÜèị̈ åßäị̈ óớâüëïơ óôï call_macro ()"
+
+#: src/macro.c:288
+#, c-format
+msgid "ERROR: Recursion limit of %d exceeded, use -L<N> to change it"
+msgstr ""
+"ÓÖÁË̀Á: Ôï üñéï áíáäñị̈́̃ %d îåđåñÜóôçêå, êÜíôå ÷ñ̃óç ôïơ -L<N> ăéá íá ôï "
+"áëëÜîåôå"
+
+#: src/module.c:123
+#, fuzzy, c-format
+msgid "ERROR: failed to initialise modules: %s"
+msgstr "ÓÖÁË̀Á: áäơíá́ßá åưñåóç̣ Üñèñùóç̣ `%s': %s"
+
+#: src/module.c:221
+#, fuzzy, c-format
+msgid "ERROR: cannot find module: `%s'"
+msgstr "ÓÖÁË̀Á: áäơíá́ßá åưñåóç̣ Üñèñùóç̣ `%s'"
+
+#: src/module.c:224
+#, fuzzy, c-format
+msgid "ERROR: cannot find module: `%s': %s"
+msgstr "ÓÖÁË̀Á: áäơíá́ßá åưñåóç̣ Üñèñùóç̣ `%s': %s"
+
+#: src/module.c:274
+#, fuzzy
+msgid "ERROR: cannot close modules"
+msgstr "ÓÖÁË̀Á: áäơíá́ßá åưñåóç̣ Üñèñùóç̣ `%s'"
+
+#: src/module.c:277
+#, fuzzy, c-format
+msgid "ERROR: cannot cannot close modules: %s"
+msgstr "ÓÖÁË̀Á: áäơíá́ßá åưñåóç̣ Üñèñùóç̣ `%s': %s"
+
+#: src/module.c:284
+#, fuzzy, c-format
+msgid "ERROR: cannot close module: `%s'"
+msgstr "ÓÖÁË̀Á: áäơíá́ßá åưñåóç̣ Üñèñùóç̣ `%s'"
+
+#: src/module.c:288
+#, fuzzy, c-format
+msgid "ERROR: cannot cannot close module: `%s': %s"
+msgstr "ÓÖÁË̀Á: áäơíá́ßá åưñåóç̣ Üñèñùóç̣ `%s': %s"
+
+#: src/output.c:262
+msgid "ERROR: Cannot create temporary file for diversion"
+msgstr "ÓÖÁË̀Á: Áäơíá́ßá äḉéïơñăßạ́ đñïóùñéíïư áñ÷åßïơ ăéá áëëáẵ"
+
+#: src/output.c:272
+msgid "ERROR: Cannot flush diversion to temporary file"
+msgstr "ÓÖÁË̀Á: Áäơíá́ßá áđïóôïẹ̈̃ áëëáặ̃ óôï đñïóùñéíü áñ÷åßï"
+
+#: src/output.c:356
+msgid "ERROR: Copying inserted file"
+msgstr "ÓÖÁË̀Á: Áíôéăñáẵ åéóåñ÷ḯƯíïơ áñ÷åßïơ"
+
+#: src/output.c:537
+msgid "ERROR: Reading inserted file"
+msgstr "ÓÖÁË̀Á: ÁíÜăíùóç åéóåñ÷ḯƯíïơ áñ÷åßïơ"
+
+#: src/output.c:636
+msgid "Cannot stat diversion"
+msgstr "Áäơíá́ßá đñïóđƯëáóç̣ ôïơ áñ÷åßïơ ôç̣ áëëáặ̃"
+
+#: src/output.c:639
+msgid "Diversion too large"
+msgstr ""
+
+#: src/path.c:157
+#, c-format
+msgid "Path search for `%s' found `%s'"
+msgstr "Ï Ưëåă÷ị̈ ́ïíïđáôéïư ăéá ôï `%s' âñ̃êå `%s'"
+
+#. sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+#. if the stack limit has not been reached.
+#: src/stackovf.c:175
+msgid "VMEM limit exceeded?\n"
+msgstr "Ôï üñéï ôç̣ åéêïíéễ ́í̃́ç̣ åîáíôë̃èçêå;\n"
+
+#: src/stackovf.c:197
+msgid ""
+"Memory bounds violation detected (SIGSEGV). Either a stack overflow\n"
+"occurred, or there is a bug in "
+msgstr ""
+"Åíôïđßóôçêå đáñÜâáóç ôùí ïñßùí ́í̃́ç̣ (SIGSEGV). Åßôå Ưăéíå ơđƯñâáóç "
+"óôïßâạ́\n"
+"åßôå ơđÜñ÷åé óöÜë́á đñïăñǗ́áôị̈ óôï "
+
+#: src/stackovf.c:202
+msgid ". Check for possible infinite recursion.\n"
+msgstr ". ÅëƯăîáôå ăéá đéèáí̃ åđ'Üđåéñï áíáäñḯ̃.\n"
+
+#: src/symtab.c:190
+msgid "INTERNAL ERROR: Illegal mode to symbol_lookup ()"
+msgstr "ÅÓÙÔÅÑÉÊÏ ÓÖÁË̀Á: Áíôéêáíïíéễ êáôÜóôáóç óôï symbol_lookup ()"
+
+#: src/symtab.c:243
+#, c-format
+msgid "Name `%s' is unknown\n"
+msgstr "Ôï üíḯá `%s' åßíáé Üăíùóôï\n"
+
+#~ msgid "Undefined macro `%s'"
+#~ msgstr "̀ç ïñéó́Ưíç ́áêñïåíôïë̃ `%s'"
+
+#~ msgid "Module search for `%s' found `%s'"
+#~ msgstr "Ç Ưñåơíá Üñèñùóç̣ ăéá `%s' âñ̃êå `%s'"
diff --git a/po/fr.gmo b/po/fr.gmo
new file mode 100644
index 00000000..8707d3ea
--- /dev/null
+++ b/po/fr.gmo
Binary files differ
diff --git a/po/fr.po b/po/fr.po
new file mode 100644
index 00000000..85b66092
--- /dev/null
+++ b/po/fr.po
@@ -0,0 +1,468 @@
+# French messages for GNU m4.
+# Copyright (C) 1998 Free Software Foundation, Inc.
+# Erick Branderhorst <Erick.Branderhorst@asml.nl>, 1998,
+# created this file based on fr.msg, which was created by:
+# Franc,ois Pinard <pinard@iro.umontreal.ca> 199(4-7).
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: m4 1.4d\n"
+"POT-Creation-Date: 1998-05-25 12:26+0200\n"
+"PO-Revision-Date: 1998-05-23 11:53+02:00\n"
+"Last-Translator: Erick Branderhorst <Erick.Branderhorst@asml.nl>\n"
+"Language-Team: dutch <nl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: src/builtin.c:272
+#, c-format
+msgid "Warning: Too few arguments to built-in `%s'"
+msgstr "Attention: Trop peu d'arguments pour «%s» prédéfini"
+
+#: src/builtin.c:278
+#, c-format
+msgid "Warning: Excess arguments to built-in `%s' ignored"
+msgstr "Attention: Les arguments superflus pour «%s» prédéfini sont ignorés"
+
+#: src/builtin.c:298
+#, c-format
+msgid "Non-numeric argument to built-in `%s'"
+msgstr "Argument non-numérique pour «%s» prédéfini"
+
+#: src/builtin.c:438
+msgid "INTERNAL ERROR: Bad token data type in define_macro ()"
+msgstr "ERREUR INTERNE: Mauvais type de lexème dans define_macro ()"
+
+#: src/builtin.c:608 src/builtin.c:671 src/builtin.c:1188 src/builtin.c:1212
+#, c-format
+msgid "Undefined name %s"
+msgstr "Nom «%s» non-défini"
+
+#: src/builtin.c:636
+msgid "INTERNAL ERROR: Builtin not found in builtin table!"
+msgstr "ERREUR INTERNE: Prédéfini introuvable dans la table des prédéfinis!"
+
+#: src/builtin.c:644
+msgid "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"
+msgstr "ERREUR INTERNE: Mauvais type de données pour lexème dans m4_dumpdef ()"
+
+#: src/builtin.c:695
+#, c-format
+msgid "Undefined macro `%s'"
+msgstr "Macro «%s» non-défini"
+
+#: src/builtin.c:735
+msgid "INTERNAL ERROR: Bad symbol type in m4_defn ()"
+msgstr "ERREUR INTERNE: Mauvais type de symbole dans m4_defn ()"
+
+#: src/builtin.c:772
+#, c-format
+msgid "Cannot open pipe to command `%s'"
+msgstr "Incapable d'ouvrir un «pipe» pour la commande «%s»"
+
+#: src/builtin.c:811
+#, c-format
+msgid "Radix in eval out of range (radix = %d)"
+msgstr "Base hors intervalle dans «eval» (base = %d)"
+
+#: src/builtin.c:820
+msgid "Negative width to eval"
+msgstr "Largeur négative dans «eval»"
+
+#: src/builtin.c:925
+#, c-format
+msgid "Non-numeric argument to %s"
+msgstr "Argument non-numérique pour %s"
+
+#: src/builtin.c:937
+#, c-format
+msgid "Cannot undivert %s"
+msgstr "Incapble de ramener la diversion %s"
+
+#: src/builtin.c:1043 src/freeze.c:207
+#, c-format
+msgid "Cannot open %s"
+msgstr "Incapable d'ouvrir %s"
+
+#: src/builtin.c:1248
+#, c-format
+msgid "Debugmode: bad debug flags: `%s'"
+msgstr "Debugmode: mauvais indicateurs de mise-au-point: «%s»"
+
+#: src/builtin.c:1284
+#, c-format
+msgid "Cannot set error file: %s"
+msgstr "Incapable de préparer le fichier d'erreurs: %s"
+
+#: src/builtin.c:1501
+msgid "WARNING: \\0 will disappear, use \\& instead in replacements"
+msgstr ""
+"ATTENTION: \\\\0 disparaîtra, utiliser \\\\& plutôt pour les remplacements"
+
+#: src/builtin.c:1562 src/builtin.c:1622 src/input.c:637
+#, c-format
+msgid "Bad regular expression `%s': %s"
+msgstr "Mauvaise expression régulière «%s»: %s"
+
+#: src/builtin.c:1573 src/builtin.c:1646
+#, c-format
+msgid "Error matching regular expression `%s'"
+msgstr "Erreur d'appariement pour l'expressio régulière «%s»"
+
+#: src/debug.c:379
+msgid "INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"
+msgstr ""
+"ERREUR INTERNE: Prédéfini introuvable dans la table des prédéfinis! "
+"(trace_pre ())"
+
+#: src/debug.c:387
+msgid "INTERNAL ERROR: Bad token data type (trace_pre ())"
+msgstr "ERREUR INTERNE: Mauvais type de donnée pour de lexème (trace_pre ())"
+
+#: src/eval.c:277
+#, c-format
+msgid "Bad expression in eval (missing right parenthesis): %s"
+msgstr "Mauvaise expression dans «eval» (parenthèse droite manquante): %s"
+
+#: src/eval.c:283
+#, c-format
+msgid "Bad expression in eval: %s"
+msgstr "Mauvaise expression dans «eval»: %s"
+
+#: src/eval.c:288
+#, c-format
+msgid "Bad expression in eval (bad input): %s"
+msgstr "Mauvaise expression dans «eval» (mauvaise entrée): %s"
+
+#: src/eval.c:293
+#, c-format
+msgid "Bad expression in eval (excess input): %s"
+msgstr "Mauvaise expression dans «eval» (entrée superflue): %s"
+
+#: src/eval.c:298
+#, c-format
+msgid "Divide by zero in eval: %s"
+msgstr "Division par zéro dans «eval»: %s"
+
+#: src/eval.c:303
+#, c-format
+msgid "Modulo by zero in eval: %s"
+msgstr "Module par zéro dans «eval»: %s"
+
+#: src/eval.c:308
+msgid "INTERNAL ERROR: Bad error code in evaluate ()"
+msgstr "ERREUR INTERNE: Mauvais code d'erreur dans evaluate ()"
+
+#: src/eval.c:547
+msgid "INTERNAL ERROR: Bad comparison operator in cmp_term ()"
+msgstr "ERREUR INTERNE: Mauvais opérateur de comparaison dans cmp_term ()"
+
+#: src/eval.c:590
+msgid "INTERNAL ERROR: Bad shift operator in shift_term ()"
+msgstr "ERREUR INTERNE: Mauvais opérateur de décalage dans shift_term ()"
+
+#: src/eval.c:674
+msgid "INTERNAL ERROR: Bad operator in mult_term ()"
+msgstr "ERREUR INTERNE: Mauvais opérateur dans mult_term ()"
+
+#: src/freeze.c:115
+msgid "INTERNAL ERROR: Built-in not found in builtin table!"
+msgstr "ERREUR INTERNE: Prédéfini introuvable dans la table des prédéfinis!"
+
+#: src/freeze.c:128
+msgid "INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"
+msgstr ""
+"ERREUR INTERNE: Mauvais type de donnée pour lexème dans freeze_one_symbol ()"
+
+#: src/freeze.c:159
+msgid "Expecting line feed in frozen file"
+msgstr "Fin-de-ligne attendue du fichier figé"
+
+#: src/freeze.c:161
+#, c-format
+msgid "Expecting character `%c' in frozen file"
+msgstr "Caractère «%c» attendu du fichier figé"
+
+#: src/freeze.c:218
+msgid "Ill-formated frozen file"
+msgstr "Fichier figé difforme"
+
+#: src/freeze.c:273 src/freeze.c:289
+msgid "Premature end of frozen file"
+msgstr "Fin prématurée de fichier figé"
+
+#: src/freeze.c:323
+#, c-format
+msgid "`%s' from frozen file not found in builtin table!"
+msgstr ""
+"«%s» dans le fichier figé est introuvable dans la table des prédéfinis!"
+
+#: src/input.c:174
+#, c-format
+msgid "Input read from %s"
+msgstr "Entrée lue de %s"
+
+#: src/input.c:231
+msgid "INTERNAL ERROR: Recursive push_string!"
+msgstr "ERREUR INTERNE: Utilisation récursive de push_string!"
+
+#: src/input.c:311
+#, c-format
+msgid "Input reverted to %s, line %d"
+msgstr "Entrée reprise de %s, ligne %d"
+
+#: src/input.c:325
+msgid "INTERNAL ERROR: Input stack botch in pop_input ()"
+msgstr "ERREUR INTERNE: Pile d'entrée douteuse dans pop_input ()"
+
+#: src/input.c:364
+msgid "INTERNAL ERROR: Bad call to init_macro_token ()"
+msgstr "ERREUR INTERNE: Mauvais appel à init_macro_token ()"
+
+#: src/input.c:413
+msgid "INTERNAL ERROR: Input stack botch in peek_input ()"
+msgstr "ERREUR INTERNE: Pile d'entrée douteuse dans peek_input ()"
+
+#: src/input.c:470
+msgid "INTERNAL ERROR: Input stack botch in next_char ()"
+msgstr "ERREUR INTERNE: Pile d'entrée douteuse dans next_char ()"
+
+#: src/input.c:550
+msgid "NONE"
+msgstr "AUCUN"
+
+#: src/input.c:777
+msgid "ERROR: EOF in string"
+msgstr "ERREUR: Fin-de-fichier dans la chaîne"
+
+#: src/m4.c:106
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr "ERREUR INTERNE: Mauvais type de lexème dans expand_token ()"
+
+#: src/m4.c:133
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Pour plus d'information, essayez «%s --help».\\n\n"
+
+#: src/m4.c:137
+#, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr "Usage: %s [OPTION]... [FICHIER]...\\n\n"
+
+#: src/m4.c:138
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+"Les arguments obligatoires ou optionnels pour la forme longue des\n"
+"options sont aussi obligatoires ou optionnels pour les formes courtes\n"
+"qui leur correspondent.\n"
+"\n"
+"Modes d'opération:\n"
+" --help fournir ce message d'aide, puis terminer\n"
+" --version identifier le programme, puis terminer\n"
+" -e, --interactive ne pas tamponner, ignorer les interruptions\n"
+" -E, --fatal-warnings terminer l'exécution après le moindre "
+"message\n"
+" -Q, --quiet, --silent inhiber certains diagnostics prédéfinis\n"
+" -P, --prefix-builtins préfixer tous les prédéfinis par «m4_»\n"
+
+#: src/m4.c:151
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr ""
+" -W, --word-regexp=REGEXP utiliser REGEXP pour les noms de macro\n"
+
+#: src/m4.c:155
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+"\n"
+"Capacités de préprocesseur:\n"
+" -I, --include=REPERTOIRE ensuite fouiller ce répertoire d'inclusions\n"
+" -D, --define=NOM[=VALEUR] définir NOM comme ayant VALEUR (ou vide)\n"
+" -U, --undefine=NOM éliminer le NOM prédéfini\n"
+" -s, --synclines engendrer des lignes «#line NNN "
+"\\\"FICHIER\\\"»\n"
+
+#: src/m4.c:163
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+"\n"
+"Contrôle des limites:\n"
+" -G, --traditional inhiber toutes les extensions GNU\n"
+" -H, --hashsize=PREMIER choisir la grandeur de la table de symboles\n"
+" -L, --nesting-limit=NOMBRE modifier la limite artificielle "
+"d'imbrication\n"
+
+#: src/m4.c:170
+msgid ""
+"\n"
+"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"
+msgstr ""
+"\n"
+"Fichiers d'état figé:\n"
+" -F, --freeze-state=FICHIER produire un FICHIER figé à la fin\n"
+" -R, --reload-state=FICHIER recharger un FICHIER figé au départ\n"
+
+#: src/m4.c:176
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+"\n"
+"Mise-au-point:\n"
+" -d, --debug=[INDICS] niveau de mise-au-point (implicitement "
+"«aeq»)\n"
+" -t, --trace=NOM tracer NOM lorsqu'il sera défini\n"
+" -l, --arglength=NOMBRE restreindre la grandeur de trace des macros\n"
+" -o, --error-output=FICHIER rediriger la sortie de trace et "
+"mise-au-point\n"
+
+#: src/m4.c:184
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+"\n"
+"INDICS est une combinaison de:\n"
+" t tracer tous les appels de macro, pas uniquement les «traceon»\n"
+" a afficher les arguments véritables\n"
+" e afficher le résultat de l'expension\n"
+" q mettre entre guillemets lorsque necessaire, avec indics «a» ou «e»\n"
+" c afficher avant et après la collecte, puis après l'appel\n"
+" x ajouter une identification unique, utile avec l'indicateur «c»\n"
+" f donner le nom courant du fichier d'entrée\n"
+" l donner le numéro de la ligne d'entrée\n"
+" p afficher les résultats des fouilles de chemin\n"
+" i afficher les modifications dans les fichiers d'entrée\n"
+" V abbréviation commode pour toutes les options précédentes à la fois\n"
+
+#: src/m4.c:199
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+"\n"
+"Si aucun FICHIER ou si FICHIER vaut «-», lit l'entrée standard.\n"
+
+#: src/m4.c:355
+#, c-format
+msgid "Bad debug flags: `%s'"
+msgstr "Mauvais indicateurs de mise-au-point: «%s»"
+
+#: src/m4.c:434
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr "ERREUR INTERNE: Mauvais code dans les arguments différés"
+
+#: src/macro.c:92
+msgid "INTERNAL ERROR: Bad token type in expand_token ()"
+msgstr "ERREUR: Débordement de pile. (Récursion hors contrôle sur «define»?)"
+
+#: src/macro.c:158
+msgid "ERROR: EOF in argument list"
+msgstr "ERREUR: Fin-de-fichier dans la liste d'arguments"
+
+#: src/macro.c:176
+msgid "INTERNAL ERROR: Bad token type in expand_argument ()"
+msgstr ""
+"ERREUR INTERNE: Mauvais type de données pour lexème dans expand_argument ()"
+
+#: src/macro.c:253
+msgid "INTERNAL ERROR: Bad symbol type in call_macro ()"
+msgstr "ERREUR INTERNE: Mauvais type de symbole dans call_macro ()"
+
+#: src/macro.c:282
+#, c-format
+msgid "ERROR: Recursion limit of %d exceeded, use -L<N> to change it"
+msgstr "ERREUR: Limite de récursion %d dépassée, la changer par -L<N>"
+
+#: src/output.c:198
+msgid "ERROR: Cannot create temporary file for diversion"
+msgstr "ERREUR: Incapable de créer un fichier temporaire pour la diversion"
+
+#: src/output.c:208
+msgid "ERROR: Cannot flush diversion to temporary file"
+msgstr "ERREUR: Incapable de vider la diversion sur un fichier temporaire"
+
+#: src/output.c:292
+msgid "ERROR: Copying inserted file"
+msgstr "ERREUR: Pendant la copie du fichier inséré"
+
+#: src/output.c:473
+msgid "ERROR: Reading inserted file"
+msgstr "ERREUR: Pendant la lecture d'un fichier inséré"
+
+#: src/output.c:572
+msgid "Cannot stat diversion"
+msgstr "Incapable d'opérer «stat» pour la diversion"
+
+#: src/path.c:131
+#, c-format
+msgid "Path search for `%s' found `%s'"
+msgstr "La fouille du chemin pour «%s» trouve «%s»"
+
+#. sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+#. if the stack limit has not been reached.
+#: src/stackovf.c:168
+msgid "VMEM limit exceeded?\n"
+msgstr "Limit VMEM outrepassée?\n"
+
+#: src/stackovf.c:190
+msgid ""
+"Memory bounds violation detected (SIGSEGV). Either a stack overflow\n"
+"occurred, or there is a bug in "
+msgstr ""
+"Les violations de mémoire sont détectées (SIGSEGV). Ou bien la pile a\n"
+"débordé, ou bien il y a un problème dans "
+
+#: src/stackovf.c:195
+msgid ". Check for possible infinite recursion.\n"
+msgstr ". Vérifier une récursion hors contrôle.\n"
+
+#: src/symtab.c:190
+msgid "INTERNAL ERROR: Illegal mode to symbol_lookup ()"
+msgstr "ERREUR INTERNE: Mode illégal dans symbol_lookup ()"
+
+#: src/symtab.c:243
+#, c-format
+msgid "Name `%s' is unknown\n"
+msgstr "Le nom «%s» est inconnu\n"
+
+#~ msgid "Bad regular expression: `%s': %s"
+#~ msgstr "Mauvaise expression régulière: «%s»: %s"
diff --git a/po/it.gmo b/po/it.gmo
new file mode 100644
index 00000000..106f8cc8
--- /dev/null
+++ b/po/it.gmo
Binary files differ
diff --git a/po/it.po b/po/it.po
new file mode 100644
index 00000000..cbc04699
--- /dev/null
+++ b/po/it.po
@@ -0,0 +1,406 @@
+msgid ""
+msgstr ""
+"POT-Creation-Date: 1998-08-03 17:14+0200\n"
+"Version: \n"
+"Date: 1995-06-30 21:00:12+0200\n"
+"From: Ulrich Drepper <drepper@myware>\n"
+"Xgettext-Options: --default-domain=m4 --output-dir=. --add-comments "
+"--keyword=_\n"
+"Files: ../src/builtin.c ../src/debug.c ../src/eval.c ../src/freeze.c\n"
+"Files: ../src/input.c ../src/m4.c ../src/macro.c ../src/output.c\n"
+"Files: ../src/path.c ../src/stackovf.c ../src/symtab.c ../lib/getopt.c\n"
+"Files: ../lib/regex.c ../lib/xmalloc.c\n"
+"Update on Fri Jun 30 21:00:27 MET 1995 \n"
+
+#: src/builtin.c:272
+#, c-format
+msgid "Warning: Too few arguments to built-in `%s'"
+msgstr "Attenzione: Troppo pochi argomenti per la funzione predefinita `%s'"
+
+#: src/builtin.c:278
+#, c-format
+msgid "Warning: Excess arguments to built-in `%s' ignored"
+msgstr ""
+"Attenzione: Gli argumenti in eccesso alla funzione predefinita `%s' sono "
+"ignorati"
+
+#: src/builtin.c:298
+#, c-format
+msgid "Non-numeric argument to built-in `%s'"
+msgstr "Argumento non numerico a funzione predefinita `%s'"
+
+#: src/builtin.c:438
+msgid "INTERNAL ERROR: Bad token data type in define_macro ()"
+msgstr "ERRORE INTERNO: Tipo dato `token' errato in define_macro ()"
+
+#: src/builtin.c:608 src/builtin.c:671 src/builtin.c:1188 src/builtin.c:1212
+#, c-format
+msgid "Undefined name %s"
+msgstr "Nome `%s' non definito"
+
+#: src/builtin.c:636
+msgid "INTERNAL ERROR: Builtin not found in builtin table!"
+msgstr ""
+
+#: src/builtin.c:644
+msgid "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"
+msgstr ""
+
+#: src/builtin.c:695
+#, c-format
+msgid "Undefined macro `%s'"
+msgstr "Macro `%s' non definita"
+
+#: src/builtin.c:735
+msgid "INTERNAL ERROR: Bad symbol type in m4_defn ()"
+msgstr "ERRORE INTERNO: Tipo simbolo errato in m4_defn ()"
+
+#: src/builtin.c:772
+#, c-format
+msgid "Cannot open pipe to command `%s'"
+msgstr "Impossibile aprire una `pipe' per il comando `%s'"
+
+#: src/builtin.c:811
+#, c-format
+msgid "Radix in eval out of range (radix = %d)"
+msgstr "Base fuori intervallo in `eval' (base = %d)"
+
+#: src/builtin.c:820
+msgid "Negative width to eval"
+msgstr "Larghezza negativa in `eval'"
+
+#: src/builtin.c:925
+#, c-format
+msgid "Non-numeric argument to %s"
+msgstr "Argumento non numerico a %s"
+
+#: src/builtin.c:937
+#, c-format
+msgid "Cannot undivert %s"
+msgstr "Impossibile ripristinare la deviazione %s"
+
+#: src/builtin.c:1043 src/freeze.c:207
+#, c-format
+msgid "Cannot open %s"
+msgstr "Impossibile aprire %s"
+
+#: src/builtin.c:1248
+#, c-format
+msgid "Debugmode: bad debug flags: `%s'"
+msgstr "Modalità di debug: indicatori di debug errati: `%s'"
+
+#: src/builtin.c:1284
+#, c-format
+msgid "Cannot set error file: %s"
+msgstr "Impossibile aprire l' archivio di errore: %s"
+
+#: src/builtin.c:1501
+msgid "WARNING: \\0 will disappear, use \\& instead in replacements"
+msgstr ""
+
+#: src/builtin.c:1562 src/builtin.c:1622 src/input.c:637
+#, c-format
+msgid "Bad regular expression `%s': %s"
+msgstr "Espressione regolare errata `%s': %s"
+
+#: src/builtin.c:1573 src/builtin.c:1646
+#, c-format
+msgid "Error matching regular expression `%s'"
+msgstr "Errore nel confronto dell' espressione regolare `%s'"
+
+#: src/debug.c:379
+msgid "INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"
+msgstr ""
+
+#: src/debug.c:387
+msgid "INTERNAL ERROR: Bad token data type (trace_pre ())"
+msgstr ""
+
+#: src/eval.c:277
+#, c-format
+msgid "Bad expression in eval (missing right parenthesis): %s"
+msgstr "Espressione errata in `eval' (manca la parentesi destra): %s"
+
+#: src/eval.c:283
+#, c-format
+msgid "Bad expression in eval: %s"
+msgstr "Espressione errata in `eval': %s"
+
+#: src/eval.c:288
+#, c-format
+msgid "Bad expression in eval (bad input): %s"
+msgstr "Espressione errata in `eval' (testo errato): %s"
+
+#: src/eval.c:293
+#, c-format
+msgid "Bad expression in eval (excess input): %s"
+msgstr "Espressione errata in `eval' (testo in eccesso): %s"
+
+#: src/eval.c:298
+#, c-format
+msgid "Divide by zero in eval: %s"
+msgstr "Divisione per zero in `eval': %s"
+
+#: src/eval.c:303
+#, c-format
+msgid "Modulo by zero in eval: %s"
+msgstr "Modulo zero in `eval': %s"
+
+#: src/eval.c:308
+msgid "INTERNAL ERROR: Bad error code in evaluate ()"
+msgstr "ERRORE INTERNO: Code di errore errato in evaluate ()"
+
+#: src/eval.c:547
+msgid "INTERNAL ERROR: Bad comparison operator in cmp_term ()"
+msgstr ""
+
+#: src/eval.c:590
+msgid "INTERNAL ERROR: Bad shift operator in shift_term ()"
+msgstr ""
+
+#: src/eval.c:674
+msgid "INTERNAL ERROR: Bad operator in mult_term ()"
+msgstr "ERRORE INTERNO: Operatore errato in mult_term ()"
+
+#: src/freeze.c:115
+msgid "INTERNAL ERROR: Built-in not found in builtin table!"
+msgstr ""
+
+#: src/freeze.c:128
+msgid "INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"
+msgstr ""
+
+#: src/freeze.c:159
+msgid "Expecting line feed in frozen file"
+msgstr "Atteso il carattere di fine linea in archivio congelato"
+
+#: src/freeze.c:161
+#, c-format
+msgid "Expecting character `%c' in frozen file"
+msgstr "Atteso il carattere `%c' in archivio congelato"
+
+#: src/freeze.c:218
+msgid "Ill-formated frozen file"
+msgstr "Archivio congelato malformato"
+
+#: src/freeze.c:273 src/freeze.c:289
+msgid "Premature end of frozen file"
+msgstr "Fine prematura dell' archivio congelato"
+
+#: src/freeze.c:323
+#, c-format
+msgid "`%s' from frozen file not found in builtin table!"
+msgstr ""
+
+#: src/input.c:174
+#, c-format
+msgid "Input read from %s"
+msgstr "Errore di lettura da %s"
+
+#: src/input.c:231
+msgid "INTERNAL ERROR: Recursive push_string!"
+msgstr "ERRORE INTERNO: Utilizzo ricorsivo di push_string!"
+
+#: src/input.c:311
+#, c-format
+msgid "Input reverted to %s, line %d"
+msgstr "Ingresso ripristinato su %s, linea %d"
+
+#: src/input.c:325
+msgid "INTERNAL ERROR: Input stack botch in pop_input ()"
+msgstr "ERRORE INTERNO: Stack di ingresso corrotto in pop_input ()"
+
+#: src/input.c:364
+msgid "INTERNAL ERROR: Bad call to init_macro_token ()"
+msgstr "ERRORE INTERNO: Chiamata errata a init_macro_token ()"
+
+#: src/input.c:413
+msgid "INTERNAL ERROR: Input stack botch in peek_input ()"
+msgstr "ERRORE INTERNO: Stack di ingresso corrotto in peek_input ()"
+
+#: src/input.c:470
+msgid "INTERNAL ERROR: Input stack botch in next_char ()"
+msgstr "ERRORE INTERNO: Stack di ingresso corrotto in next_char ()"
+
+#: src/input.c:550
+msgid "NONE"
+msgstr "NESSUNO"
+
+#: src/input.c:777
+msgid "ERROR: EOF in string"
+msgstr "ERRORE: Fine prematura di una stringa"
+
+#: src/m4.c:106
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr "ERRORE: Stack overflow. (Ricorsione infinita in `define'?)"
+
+#: src/m4.c:133
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Per ulteriori informazioni provare `%s --help'.\n"
+
+#: src/m4.c:137
+#, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr "Usage: %s [OPZIONE]... [ARCHIVIO]...\n"
+
+#: src/m4.c:138
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+
+#: src/m4.c:151
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr ""
+
+#: src/m4.c:155
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+
+#: src/m4.c:163
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+
+#: src/m4.c:170
+msgid ""
+"\n"
+"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"
+msgstr ""
+
+#: src/m4.c:176
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+
+#: src/m4.c:184
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+
+#: src/m4.c:199
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+
+#: src/m4.c:358
+#, c-format
+msgid "Bad debug flags: `%s'"
+msgstr "Indicatori di debug errati: `%s'"
+
+#: src/m4.c:437
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr "ERRORE INTERNO: Codice errato in argomenti differiti"
+
+#: src/macro.c:92
+msgid "INTERNAL ERROR: Bad token type in expand_token ()"
+msgstr "ERRORE INTERNO: Tipo `token' errato in expand_token ()"
+
+#: src/macro.c:158
+msgid "ERROR: EOF in argument list"
+msgstr "ERRORE: Fine prematura della lista di argomenti"
+
+#: src/macro.c:176
+msgid "INTERNAL ERROR: Bad token type in expand_argument ()"
+msgstr ""
+
+#: src/macro.c:253
+msgid "INTERNAL ERROR: Bad symbol type in call_macro ()"
+msgstr "ERRORE INTERNO: Tipo simbolo errato in call_macro ()"
+
+#: src/macro.c:282
+#, c-format
+msgid "ERROR: Recursion limit of %d exceeded, use -L<N> to change it"
+msgstr ""
+
+#: src/output.c:198
+msgid "ERROR: Cannot create temporary file for diversion"
+msgstr "ERRORE: Impossibile creare un archivio temporaneo per la deviazione"
+
+#: src/output.c:208
+msgid "ERROR: Cannot flush diversion to temporary file"
+msgstr "ERRORE: Impossibile terminare la deviazione su file temporaneo"
+
+#: src/output.c:292
+msgid "ERROR: Copying inserted file"
+msgstr "ERRORE: Copiando archivio inserito"
+
+#: src/output.c:473
+msgid "ERROR: Reading inserted file"
+msgstr "ERRORE: Leggendo archivio inserito"
+
+#: src/output.c:572
+msgid "Cannot stat diversion"
+msgstr "Impossibile effettuare la `stat' per la deviazione"
+
+#: src/path.c:131
+#, c-format
+msgid "Path search for `%s' found `%s'"
+msgstr "La ricerca del percorso per `%s' ha trovato `%s'"
+
+#. sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+#. if the stack limit has not been reached.
+#: src/stackovf.c:168
+msgid "VMEM limit exceeded?\n"
+msgstr "Limite di VMEM superato?\n"
+
+#: src/stackovf.c:190
+msgid ""
+"Memory bounds violation detected (SIGSEGV). Either a stack overflow\n"
+"occurred, or there is a bug in "
+msgstr ""
+
+#: src/stackovf.c:195
+msgid ". Check for possible infinite recursion.\n"
+msgstr ". Controllare una possibile ricorsione infinita.\n"
+
+#: src/symtab.c:190
+msgid "INTERNAL ERROR: Illegal mode to symbol_lookup ()"
+msgstr "ERRORE INTERNO: Modo illegale in symbol_lookup ()"
+
+#: src/symtab.c:243
+#, c-format
+msgid "Name `%s' is unknown\n"
+msgstr "Il nome `%s' è sconosciuto\n"
+
+#~ msgid "Bad regular expression: `%s': %s"
+#~ msgstr "Espressione regolare errata: `%s': %s"
diff --git a/po/ja.gmo b/po/ja.gmo
new file mode 100644
index 00000000..da665805
--- /dev/null
+++ b/po/ja.gmo
Binary files differ
diff --git a/po/ja.po b/po/ja.po
new file mode 100644
index 00000000..f5bf54dd
--- /dev/null
+++ b/po/ja.po
@@ -0,0 +1,515 @@
+# Japanese messages for GNU m4.
+# Copyright (C) 1996 Free Software Foundation, Inc.
+# Akiko Matsushita <matusita@sra.co.jp>, 1996.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: GNU m4 1.4.3\n"
+"POT-Creation-Date: 1998-08-03 17:14+0200\n"
+"PO-Revision-Date: 1996-03-28 11:52 EST\n"
+"Last-Translator: Akiko Matsushita <matusita@sra.co.jp>\n"
+"Language-Team: Japanese <ja@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=EUC\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: src/builtin.c:272
+#, c-format
+msgid "Warning: Too few arguments to built-in `%s'"
+msgstr "·Ù¹đ¡§%s ¤Ø¤Î°ú¿ô¤¬ÉÔ­¤·¤Æ¤¤¤̃¤¹¡£"
+
+#: src/builtin.c:278
+#, c-format
+msgid "Warning: Excess arguments to built-in `%s' ignored"
+msgstr "·Ù¹đ¡§%s ¤Ø¤Î°ú¿ô¤¬Â¿²á¤®¤̃¤¹ (Ķ¤¨¤¿Ê¬¤Ï̀µ»ë¤µ¤́¤̃¤¹)¡£"
+
+#: src/builtin.c:298
+#, c-format
+msgid "Non-numeric argument to built-in `%s'"
+msgstr "`%s' ¤Ë¿ô»ú¤Ç¤Ê¤¤°ú¿ô¤¬ÅϤµ¤́¤Æ¤¤¤̃¤¹¡£"
+
+#: src/builtin.c:438
+msgid "INTERNAL ERROR: Bad token data type in define_macro ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô define_macro () Æâ¤Î¥È¡¼¥¯¥ó¥Ç¡¼¥¿¤Î¼ïÎबÉÔÀµ¤Ç¤¹¡£"
+
+#: src/builtin.c:608 src/builtin.c:671 src/builtin.c:1188 src/builtin.c:1212
+#, c-format
+msgid "Undefined name %s"
+msgstr "`%s' ¤ÏÄêµÁ¤µ¤́¤Æ¤¤¤̃¤»¤ó¡£"
+
+#: src/builtin.c:636
+msgid "INTERNAL ERROR: Builtin not found in builtin table!"
+msgstr "ÆâÉô¥¨¥é¡¼¡§`Built-in' ¤È¤¤¤¦¥Ó¥ë¥È¥¤¥ó¥̃¥¯¥í¤Ï¤¢¤ê¤̃¤»¤ó¡£"
+
+#: src/builtin.c:644
+msgid "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô m4_dumpdef () ¤Î¥È¡¼¥¯¥ó¥Ç¡¼¥¿¤Î¼ïÎबÉÔÀµ¤Ç¤¹¡£"
+
+#: src/builtin.c:695
+#, c-format
+msgid "Undefined macro `%s'"
+msgstr "¥̃¥¯¥í `%s' ¤ÏÄêµÁ¤µ¤́¤Æ¤¤¤̃¤»¤ó¡£"
+
+#: src/builtin.c:735
+msgid "INTERNAL ERROR: Bad symbol type in m4_defn ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô m4_defn () Æâ¤Î¥·¥ó¥Ü¥ë¤Î¼ïÎबÉÔÀµ¤Ç¤¹¡£"
+
+#: src/builtin.c:772
+#, c-format
+msgid "Cannot open pipe to command `%s'"
+msgstr "¥³¥̃¥ó¥É `%s' ¤Ø¤Î¥Ñ¥¤¥×¤¬¥ª¡¼¥×¥ó¤Ç¤­¤̃¤»¤ó¡£"
+
+#: src/builtin.c:811
+#, c-format
+msgid "Radix in eval out of range (radix = %d)"
+msgstr "eval ¤Î´đ¿ô ( %d ¿ÊË¡) ¤Î·å¿ô¤¬µöÍÆÈϰϳ°¤Ë¤¢¤ê¤̃¤¹¡£"
+
+#: src/builtin.c:820
+msgid "Negative width to eval"
+msgstr "eval ¤Î½ĐÎÏ·å¿ô¤¬Éé¿ô¤Ë¤Ê¤Ă¤Æ¤¤¤̃¤¹¡£"
+
+#: src/builtin.c:925
+#, c-format
+msgid "Non-numeric argument to %s"
+msgstr "`%s' ¤Ë¿ô»ú¤Ç¤Ê¤¤°ú¿ô¤¬ÅϤµ¤́¤Æ¤¤¤̃¤¹¡£"
+
+#: src/builtin.c:937
+#, c-format
+msgid "Cannot undivert %s"
+msgstr "`%s' ¤̣ undivert ¤Ç¤­¤̃¤»¤ó¡£"
+
+#: src/builtin.c:1043 src/freeze.c:207
+#, c-format
+msgid "Cannot open %s"
+msgstr "`%s' ¤̣¥ª¡¼¥×¥ó¤Ç¤­¤̃¤»¤ó¡£"
+
+#: src/builtin.c:1248
+#, c-format
+msgid "Debugmode: bad debug flags: `%s'"
+msgstr "debugmode ¥̃¥¯¥í¤Ë¤ª¤¤¤Æ %s ¤ÏÉÔÀµ¤Ê¥Ç¥Đ¥Ă¥°¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£"
+
+#: src/builtin.c:1284
+#, c-format
+msgid "Cannot set error file: %s"
+msgstr "`%s' ¤̣¥¨¥é¡¼¥í¥°¥Ơ¥¡¥¤¥ë¤È¤·¤Æ¥»¥Ă¥È¤Ç¤­¤̃¤»¤ó¡£"
+
+#: src/builtin.c:1501
+msgid "WARNING: \\0 will disappear, use \\& instead in replacements"
+msgstr "·Ù¹đ¡§\\0 ¤Ïµ́¼°¤ÎÍÑË¡¤Ç¤¹¡£\\& ¤̣Âå¤ï¤ê¤Ë»È¤Ă¤Æ²¼¤µ¤¤¡£"
+
+#: src/builtin.c:1562 src/builtin.c:1622 src/input.c:637
+#, c-format
+msgid "Bad regular expression `%s': %s"
+msgstr "`%s' : %s ¤Ï¡¢ÉÔÀµ¤ÊÀµµ¬É½¸½¤Ç¤¹¡£"
+
+#: src/builtin.c:1573 src/builtin.c:1646
+#, c-format
+msgid "Error matching regular expression `%s'"
+msgstr "Àµµ¬É½¸½ %s ¤Î¥̃¥Ă¥Á¥ó¥°¤Ë¼ºÇÔ¤·¤̃¤·¤¿¡£"
+
+#: src/debug.c:379
+msgid "INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"
+msgstr ""
+"ÆâÉô¥¨¥é¡¼¡§`Builtin' ¤È¤¤¤¦¥Ó¥ë¥È¥¤¥ó¥̃¥¯¥í¤Ï¤¢¤ê¤̃¤»¤ó¡£\n"
+" (´Ø¿ô trace_pre () ¤¬¤³¤Î¥¨¥é¡¼¥á¥Ă¥»¡¼¥¸¤̣½Đ¤·¤Æ¤¤¤̃¤¹¡£) "
+
+#: src/debug.c:387
+msgid "INTERNAL ERROR: Bad token data type (trace_pre ())"
+msgstr ""
+"ÆâÉô¥¨¥é¡¼¡§¥È¡¼¥¯¥ó¥Ç¡¼¥¿¤Î¼ïÎबÉÔÀµ¤Ç¤¹¡£\n"
+" (´Ø¿ô trace_pre () ¤¬¤³¤Î¥¨¥é¡¼¥á¥Ă¥»¡¼¥¸¤̣½Đ¤·¤Æ¤¤¤̃¤¹¡£)"
+
+#: src/eval.c:277
+#, c-format
+msgid "Bad expression in eval (missing right parenthesis): %s"
+msgstr "eval ¤Ç %s ¤È¤¤¤¦ÉÔÀµ¤Êɽ¸½¤¬ÍѤ¤¤é¤́¤Æ¤¤¤̃¤¹ (ÊĤ¸³ç¸̀¤¬¤¢¤ê¤̃¤»¤ó)¡£"
+
+#: src/eval.c:283
+#, c-format
+msgid "Bad expression in eval: %s"
+msgstr "eval ¤Ç %s ¤È¤¤¤¦ÉÔÀµ¤Ê¼°¤¬ÍѤ¤¤é¤́¤Æ¤¤¤̃¤¹¡£"
+
+#: src/eval.c:288
+#, c-format
+msgid "Bad expression in eval (bad input): %s"
+msgstr ""
+"eval ¤Ç `%s' ¤È¤¤¤¦ÉÔÀµ¤Êɽ¸½¤¬ÍѤ¤¤é¤́¤Æ¤¤¤̃¤¹ \n"
+" (Æ₫Îϥǡ¼¥¿¤¬Àµ¤·¤¯¤¢¤ê¤̃¤»¤ó)¡£"
+
+#: src/eval.c:293
+#, c-format
+msgid "Bad expression in eval (excess input): %s"
+msgstr "eval ¤Ç %s ¤È¤¤¤¦ÉÔÀµ¤Ê¼°¤¬ÍѤ¤¤é¤́¤Æ¤¤¤̃¤¹ (Æ₫Îϥǡ¼¥¿¤¬Â¿²á¤®¤̃¤¹)¡£"
+
+#: src/eval.c:298
+#, c-format
+msgid "Divide by zero in eval: %s"
+msgstr "`%s' ¤È¤¤¤¦É½¸½¤Ç¡¢0 ¤Ë¤è¤ë³ä»»¤¬¹Ô¤ï¤́¤Æ¤¤¤̃¤¹¡£"
+
+#: src/eval.c:303
+#, c-format
+msgid "Modulo by zero in eval: %s"
+msgstr "`%s' ¤È¤¤¤¦ eval ¤Ç¡¢´đ¿ô¤¬ 0 ¤Ë¤Ê¤Ă¤Æ¤¤¤̃¤¹¡£"
+
+#: src/eval.c:308
+msgid "INTERNAL ERROR: Bad error code in evaluate ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô evaluate () Æâ¤Î¥¨¥é¡¼¥³¡¼¥É¤¬ÉÔÀµ¤Ç¤¹¡£"
+
+#: src/eval.c:547
+msgid "INTERNAL ERROR: Bad comparison operator in cmp_term ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô cmp_term () ¤ÎÈæ³Ó±é»»»̉¤¬ÉÔÀµ¤Ç¤¹¡£"
+
+#: src/eval.c:590
+msgid "INTERNAL ERROR: Bad shift operator in shift_term ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§shift_term () ¤Î¥·¥Ơ¥È±é»»»̉¤¬ÉÔÀµ¤Ç¤¹¡£"
+
+#: src/eval.c:674
+msgid "INTERNAL ERROR: Bad operator in mult_term ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô mult_term () Æâ¤Î±é»»»̉¤¬ÉÔÀµ¤Ç¤¹¡£"
+
+#: src/freeze.c:115
+msgid "INTERNAL ERROR: Built-in not found in builtin table!"
+msgstr "ÆâÉô¥¨¥é¡¼¡§`Built-in' ¤È¤¤¤¦¥Ó¥ë¥È¥¤¥ó¥̃¥¯¥í¤Ï¤¢¤ê¤̃¤»¤ó¡£"
+
+#: src/freeze.c:128
+msgid "INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"
+msgstr ""
+"ÆâÉô¥¨¥é¡¼¡§´Ø¿ô freeze_one_symbol () ¤Î¥È¡¼¥¯¥ó¥Ç¡¼¥¿¤Î¼ïÎबÉÔÀµ¤Ç¤¹¡£"
+
+#: src/freeze.c:159
+msgid "Expecting line feed in frozen file"
+msgstr "Åà·ë¥Ơ¥¡¥¤¥ëÆâ¤Ç²₫¹Ô¥³¡¼¥É¤̣´üÂÔ¤·¤Æ¤¤¤̃¤¹¡£"
+
+#: src/freeze.c:161
+#, c-format
+msgid "Expecting character `%c' in frozen file"
+msgstr "Åà·ë¥Ơ¥¡¥¤¥ëÆâ¤Çʸ»ú `%c' ¤̣´üÂÔ¤·¤Æ¤¤¤̃¤¹¡£"
+
+#: src/freeze.c:218
+msgid "Ill-formated frozen file"
+msgstr "ÆâÉô¥¨¥é¡¼¡§Åà·ë¥Ơ¥¡¥¤¥ë¤Î¥Ơ¥©¡¼¥̃¥Ă¥È¤¬ÉÔÀµ¤Ç¤¹¡£"
+
+#: src/freeze.c:273 src/freeze.c:289
+msgid "Premature end of frozen file"
+msgstr "Åà·ë¥Ơ¥¡¥¤¥ë¤Î EOF ¤¬Á᤯Íè²á¤®¤Æ¤¤¤̃¤¹¡£"
+
+#: src/freeze.c:323
+#, c-format
+msgid "`%s' from frozen file not found in builtin table!"
+msgstr "Åà·ë¥Ơ¥¡¥¤¥ë¤Î %s ¤Ï¥Ó¥ë¥È¥¤¥ó¥³¥̃¥ó¥É¤Î¥Æ¡¼¥Ö¥ë¤Ë¤Ï¤¢¤ê¤̃¤»¤ó¡£"
+
+#: src/input.c:174
+#, c-format
+msgid "Input read from %s"
+msgstr "%s ¤«¤é¤ÎÆ₫ÎϤ̣Æɤ߹₫¤ß¤̃¤¹¡£"
+
+#: src/input.c:231
+msgid "INTERNAL ERROR: Recursive push_string!"
+msgstr "ÆâÉô¥¨¥é¡¼¡§ºÆµ¢Åª¤Ëʸ»úÎó¤̣ push ¤·¤Æ¤¤¤̃¤¹¡£"
+
+#: src/input.c:311
+#, c-format
+msgid "Input reverted to %s, line %d"
+msgstr "¥Ơ¥¡¥¤¥ë %s, %d ¹Ồܤ«¤éÆ₫ÎϤ·Ä¾¤·¤̃¤¹¡£"
+
+#: src/input.c:325
+msgid "INTERNAL ERROR: Input stack botch in pop_input ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô pop_input () Æâ¤Ç¥¹¥¿¥Ă¥¯¤ÎÆ₫ÎϤ˼ºÇÔ¤·¤Æ¤¤¤̃¤¹¡£"
+
+#: src/input.c:364
+msgid "INTERNAL ERROR: Bad call to init_macro_token ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô init_macro_token () ¤¬ÉÔÀµ¤Ë¸Æ¤Đ¤́¤Æ¤¤¤̃¤¹¡£"
+
+#: src/input.c:413
+msgid "INTERNAL ERROR: Input stack botch in peek_input ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô peek_input () Æâ¤Ç¥¹¥¿¥Ă¥¯¤ÎÆ₫ÎϤ˼ºÇÔ¤·¤Æ¤¤¤̃¤¹¡£"
+
+#: src/input.c:470
+msgid "INTERNAL ERROR: Input stack botch in next_char ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô next_char () Æâ¤Ç¥¹¥¿¥Ă¥¯¤ÎÆ₫ÎϤ˼ºÇÔ¤·¤Æ¤¤¤̃¤¹¡£"
+
+#: src/input.c:550
+msgid "NONE"
+msgstr "¤Ê¤·"
+
+#: src/input.c:777
+msgid "ERROR: EOF in string"
+msgstr "¥¨¥é¡¼: ʸ»úÎóÆâ¤Ë¥Ơ¥¡¥¤¥ë¤Î½ªĂ¼µ­¹æ¤¬¤¢¤ê¤̃¤¹¡£"
+
+#: src/m4.c:106
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr ""
+"¥¨¥é¡¼: ¥¹¥¿¥Ă¥¯¤¬¥ª¡¼¥Đ¡¼¥Ơ¥í¡¼¤̣µ¯¤³¤·¤Æ¤¤¤̃¤¹¡£\n"
+" (̀µ¸Â¤ËºÆµ¢ÅªÄêµÁ¤̣¤·¤Æ¤¤¤̃¤»¤ó¤«¡©)"
+
+#: src/m4.c:133
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "¾Ü¤·¤¯¤Ï `%s --help' ¤Î½ĐÎϤ̣¸æÍ÷²¼¤µ¤¤¡£\n"
+
+#: src/m4.c:137
+#, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr "»ÈÍÑÊưË¡: %s [¥ª¥×¥·¥ç¥ó]...[¥Ơ¥¡¥¤¥ë̀¾]\n"
+
+#: src/m4.c:138
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+"Ť¤¥ª¥×¥·¥ç¥ó¤¬¼è¤ëɬ¿Ü°ú¿ô¤ª¤è¤ÓÁªẬ²Äǽ¤Ê°ú¿ô¤Ï\n"
+"Ă»¤¤¥ª¥×¥·¥ç¥ó¤Î¾́¹ç¤Ë¤âɬÍפǤ¹¡£\n"
+"Operation modes:\n"
+" --help ¥ª¥×¥·¥ç¥ó¤Î°́Í÷¤̣½ĐÎϤ·¡¢½ªÎ»¤·¤̃¤¹¡£\n"
+" --version ¥Đ¡¼¥¸¥ç¥ó¾đÊó¤̣½ĐÎϤ·¡¢½ªÎ»¤·¤̃¤¹¡£\n"
+" -e, --interactive "
+"½ĐÎϤ̣¥Đ¥Ă¥Ơ¥¡¥ê¥ó¥°¤»¤º¡¢³ä¤ê¹₫¤ß¤̣̀µ»ë¤·¤̃¤¹¡£\n"
+" -E, --fatal-warnings ·Ù¹đ¤¬½Đ¤µ¤́¤ë¤È¼Â¹Ô¤̣Ăæ»ß¤·¤̃¤¹¡£\n"
+" -Q, --quiet, --silent "
+"¤¤¤¯¤Ä¤«¤Î¥Ó¥ë¥È¥¤¥ó¥³¥̃¥ó¥É¤Î·Ù¹đ¤̣Í̃À©¤·¤̃¤¹¡£\n"
+" -P, --prefix-builtins Á´¤Æ¤Î¥Ó¥ë¥È¥¤¥ó¥̃¥¯¥í¤Ë `m4_' ¤È¤¤¤¦ÀÜƬ¼­¤̣ "
+" ¶¯À©Åª¤ËÄÉ²Ă¤·¤̃¤¹¡£\n"
+
+#: src/m4.c:151
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr ""
+"-W, --word-regexp=REGEXP ¥̃¥¯¥í̀¾¤Î¥·¥ó¥¿¥Ă¥¯¥¹¤Ë REGEXP ¤̣ "
+" Àµµ¬É½¸½¤È¤·¤ÆÍѤ¤¤̃¤¹¡£\n"
+
+#: src/m4.c:155
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+"\n"
+"¥×¥ê¥×¥í¥»¥Ă¥µµ¡Ç½:\n"
+" -I, --include=DIRECTORY ¥«¥́¥ó¥È¥Ç¥£¥́¥¯¥È¥ê¤Î¼¡¤Ë¤³¤Î¥Ç¥£¥́¥¯¥È¥ê\n"
+" ¤«¤é¥¤¥ó¥¯¥ë¡¼¥É¥Ơ¥¡¥¤¥ë¤̣¥µ¡¼¥Á¤·¤̃¤¹¡£\n"
+" -D, --define=NAME[=VALUE] NAME ¤̣ VALUE ¤ËÄêµÁ¤·¤̃¤¹¡£\n"
+" (VALUE ¤Ï¾Êά²Äǽ¤Ç¡¢¤³¤Î¾́¹ç¤Ï NAME ¤Ï "
+" ¶ơ¤Îʸ»úÎó¤ËÄêµÁ¤µ¤́¤̃¤¹¡£)\n"
+" -U, --undefine=NAME NAME ¤ÎÄêµÁ¤̣¼è¤ê¾Ă¤·¤̃¤¹¡£\n"
+" -s, --synclines ¹ÔÈÖ¹æ¤È¥Ơ¥¡¥¤¥ë̀¾¤Î¹Ô¤̣À¸À®¤·¤̃¤¹¡£\n"
+
+#: src/m4.c:163
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+"\n"
+"¸Â³¦ĂͤΥ³¥ó¥È¥í¡¼¥ë:\n"
+" -G, --traditional GNU ÈǤËÆĂÍ­¤Î³ÈÄ¥¤̣Í̃À©¤·¤̃¤¹¡£\n"
+" -H, --hashsize=PRIME ¥·¥ó¥Ü¥ë¸¡º÷¥Ï¥Ă¥·¥å¥Æ¡¼¥Ö¥ë¤Î¥µ¥¤¥º¤̣\n"
+" ¥»¥Ă¥È¤·¤̃¤¹¡£\n"
+" -L, --nesting-limit=NUNBER "
+"¥̃¥¯¥í¤Î¥Í¥¹¥È²ó¿ô¤Î¾å¸ÂẶͤ¿Í°ÙŪ¤ËÊѹ¹¤·¤̃¤¹¡£\n"
+
+#: src/m4.c:170
+msgid ""
+"\n"
+"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"
+msgstr ""
+"\n"
+"Åà·ë¾ơÂ֤ΥƠ¥¡¥¤¥ë: -F, --freeze-state=FILE ºÇ¸å¤Ë»ØÄꤵ¤́¤¿ FILE "
+"¤̣Åà·ë¾ơÂ֤ˤ·¤̃¤¹¡£\n"
+" -R, --reload-state=FILE ºÇ½é¤Ë»ØÄꤵ¤́¤¿ FILE ¤«¤é\n"
+" Åà·ë¤µ¤́¤¿ÄêµÁ¤̣¥í¡¼¥É¤·¤̃¤¹\n"
+
+#: src/m4.c:176
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+"\n"
+" ¥Ç¥Đ¥Ă¥®¥ó¥°:\n"
+" -d, --debug=[FLAGS] ¥Ç¥Đ¥Ă¥°¥́¥Ù¥ë¤̣¥»¥Ă¥È¤·¤̃¤¹¡£\n"
+" (`aeq' ¤Ï FLAGS ¤Ë´̃¤̃¤́¤̃¤»¤ó¡£)\n"
+" -t, --trace=NAME NAME ¤¬ÄêµÁ¤µ¤́¤ë¤È¤½¤́¤̣¥È¥́¡¼¥¹¤·¤̃¤¹¡£\n"
+" -l, --arglength=NUM ¥̃¥¯¥í¥È¥́¡¼¥¹¤Î¥µ¥¤¥º¤̣ NUM ¤ËÀ©¸Â¤·¤̃¤¹¡£\n"
+" -o, --error-output=FILE ¥Ç¥Đ¥Ă¥°¤È¥È¥́¡¼¥¹¤Î½ĐÎϤ̣ FILE ¤Ë\n"
+" ¥ê¥À¥¤¥́¥¯¥È¤·¤̃¤¹¡£\n"
+
+#: src/m4.c:184
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+"\n"
+"FLAG ¤Ï°Ê²¼¤Î¤¤¤º¤́¤«¤Ç¤¹:\n"
+" t Á´¤Æ¤Î¥̃¥¯¥í¸Æ¤Ó¤À¤·¤̣¥È¥́¡¼¥¹¤·¤̃¤¹\n"
+" (traceon ¤Ë¤è¤ë¤â¤Î¤Ë¸ÂÄꤷ¤̃¤»¤ó)\n"
+" a ¸½ºß¤Î°ú¿ô¤̣ɽ¼¨¤·¤̃¤¹\n"
+" e Ÿ³«¤µ¤́¤¿¤â¤Î¤̣ɽ¼¨¤·¤̃¤¹\n"
+" q `a' ¤̃¤¿¤Ï `e' ¤È¶¦¤ËÍѤ¤¡¢É¬Íפ˱₫¤¸¤ÆẶͤ°úÍÑÉä¤Ç°Ï¤ß¤̃¤¹¡£\n"
+" c ÄûÀµÁ°¤ÈÄûÀµ¸å¡¢¸Æ½Đ¸å¤Ëɽ¼¨¤·¤̃¤¹\n"
+" x ¤½¤Î¥̃¥¯¥í¥³¡¼¥ë¤Ë¸ÇÍ­¤Î ID ¤̣ÄÉ²Ă¤·¤̃¤¹¡£\n"
+" `c' ¤ÈÁȤ߹ç¤ï¤»¤ë¤ÈÊØÍø¤Ç¤¹¡£\n"
+" f ¤½¤Î»₫ÅÀ¤ÇÆ₫ÎϤ·¤Æ¤¤¤ë¥Ơ¥¡¥¤¥ë̀¾¤̣ɽ¼¨¤·¤̃¤¹¡£\n"
+" l ¤½¤Î»₫ÅÀ¤ÇÆ₫ÎϤ·¤Æ¤¤¤ë¹ÔÈÖ¹æ¤̣ɽ¼¨¤·¤̃¤¹¡£\n"
+" p ¥Ñ¥¹¤̣¸¡º÷¤·¤¿·ë²̀¤̣ɽ¼¨¤·¤̃¤¹¡£\n"
+" i Æ₫ÎÏ¥Ơ¥¡¥¤¥ë¤ËÀ¸¤¸¤¿ÊѲ½¤̣ɽ¼¨¤·¤̃¤¹¡£\n"
+" V ¾åµ­¤ÎÁ´¤Æ¤Î FLAG ¤̣»ØÄꤹ¤ë¤³¤È¤̣°Ờ£¤·¤̃¤¹¡£\n"
+
+#: src/m4.c:199
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+"\n"
+"FILE ¤¬»ØÄꤵ¤́¤Æ¤¤¤Ê¤¤¾́¹ç¤ª¤è¤Ó»ØÄꤵ¤́¤¿¥Ơ¥¡¥¤¥ë¤¬ `-' ¤Î¾́¹ç¤Ï\n"
+" ɸ½àÆ₫ÎϤ¬Æɤ߹₫¤̃¤́¤̃¤¹¡£\n"
+
+#: src/m4.c:358
+#, c-format
+msgid "Bad debug flags: `%s'"
+msgstr "`%s' ¤ÏÉÔÀµ¤Ê¥Ç¥Đ¥Ă¥°¥ª¥×¥·¥ç¥ó°ú¿ô¤Ç¤¹¡£"
+
+#: src/m4.c:437
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr "ÆâÉô¥¨¥é¡¼¡§¥ª¥×¥·¥ç¥ó¤Î¸å½èÍư¤Ç¡¢ÉÔÀµ¥³¡¼¥É¤¬¸¡½Đ¤µ¤́¤̃¤·¤¿¡£"
+
+#: src/macro.c:92
+msgid "INTERNAL ERROR: Bad token type in expand_token ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô expand_token () Æâ¤Î¥È¡¼¥¯¥ó¤Î¼ïÎबÉÔÀµ¤Ç¤¹¡£"
+
+#: src/macro.c:158
+msgid "ERROR: EOF in argument list"
+msgstr "¥¨¥é¡¼: °ú¿ô¥ê¥¹¥ÈÆâ¤Ë¥Ơ¥¡¥¤¥ë¤Î½ªĂ¼µ­¹æ¤¬¤¢¤ê¤̃¤¹¡£"
+
+#: src/macro.c:176
+msgid "INTERNAL ERROR: Bad token type in expand_argument ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô expand_argument () ¤Î¥È¡¼¥¯¥ó¤Î¼ïÎबÉÔÀµ¤Ç¤¹¡£"
+
+#: src/macro.c:253
+msgid "INTERNAL ERROR: Bad symbol type in call_macro ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô call_macro () Æâ¤Î¥·¥ó¥Ü¥ë¤Î¼ïÎबÉÔÀµ¤Ç¤¹¡£"
+
+#: src/macro.c:282
+#, c-format
+msgid "ERROR: Recursion limit of %d exceeded, use -L<N> to change it"
+msgstr ""
+"¥¨¥é¡¼¡§ºÆµ¢ÅªÄêµÁ¤Î¥Í¥¹¥È¤¬»ØÄꤵ¤́¤¿ĂÍ %d ¤̣Ķ¤¨¤Æ¤¤¤̃¤¹¡£\n"
+" -L<¿ô»ú> ¥ª¥×¥·¥ç¥ó¤̣ÍѤ¤¤Æ¥Í¥¹¥È¿ô¤Î¾å¸Â¤̣Áư¤ä¤·¤Æ²¼¤µ¤¤¡£"
+
+#: src/output.c:198
+msgid "ERROR: Cannot create temporary file for diversion"
+msgstr "¥¨¥é¡¼: divert ¤Î¤¿¤á¤Î¥Æ¥ó¥Ư¥é¥ê¥Ơ¥¡¥¤¥ë¤¬ºîÀ®¤Ç¤­¤̃¤»¤ó¡£"
+
+#: src/output.c:208
+msgid "ERROR: Cannot flush diversion to temporary file"
+msgstr "¥¨¥é¡¼: ¥Æ¥ó¥Ư¥é¥ê¥Ơ¥¡¥¤¥ë¤Ë divert ¤¹¤Ù¤­ÆâÍƤ̣ write ¤Ç¤­¤̃¤»¤ó¡£"
+
+#: src/output.c:292
+msgid "ERROR: Copying inserted file"
+msgstr "¥¨¥é¡¼: Á̃Æ₫¤µ¤́¤ë¤Ù¤­¥Ơ¥¡¥¤¥ë¤̣¥³¥Ô¡¼Ăæ¤Ç¤¹¡£"
+
+#: src/output.c:473
+msgid "ERROR: Reading inserted file"
+msgstr "¥¨¥é¡¼: Á̃Æ₫¤µ¤́¤ë¤Ù¤­¥Ơ¥¡¥¤¥ë¤̣¥ê¡¼¥ÉĂæ¤Ç¤¹¡£"
+
+#: src/output.c:572
+msgid "Cannot stat diversion"
+msgstr ""
+"divert ¤Î¤¿¤á¤Î¥Ơ¥¡¥¤¥ë¤Î¥¹¥Æ¡¼¥¿¥¹¤̣ÆÀ¤ë¤³¤È¤¬¤Ç¤­¤̃¤»¤ó¡£\n"
+" (stat ¤Ç¤­¤̃¤»¤ó¡£)"
+
+#: src/path.c:131
+#, c-format
+msgid "Path search for `%s' found `%s'"
+msgstr "`%s' ¤È¤¤¤¦¥Ç¥£¥́¥¯¥È¥ê¤«¤é `%s' ¤È¤¤¤¦¥Ơ¥¡¥¤¥ë¤̣¸«¤Ä¤±¤̃¤·¤¿¡£"
+
+#. sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+#. if the stack limit has not been reached.
+#: src/stackovf.c:168
+msgid "VMEM limit exceeded?\n"
+msgstr "¥ê¥½¡¼¥¹ĂÍ RLIMIT_VMEM ¤̣Ķ¤¨¤Æ¤¤¤̃¤»¤ó¤«¡©\n"
+
+#: src/stackovf.c:190
+msgid ""
+"Memory bounds violation detected (SIGSEGV). Either a stack overflow\n"
+"occurred, or there is a bug in "
+msgstr ""
+"¥á¥â¥ê (¥»¥°¥á¥ó¥Æ¡¼¥·¥ç¥ó°ăÈ¿) ¤¬¸¡½Đ¤µ¤́¤̃¤·¤¿¡£\n"
+" ¥¹¥¿¥Ă¥¯¤¬¥ª¡¼¥Đ¡¼¥Ơ¥í¡¼¤·¤Æ¤¤¤ë¡¢¤¢¤ë¤¤¤Ï¥Đ¥°¤¬Â¸ºß¤¹¤ë\n"
+" ²ÄǽÀ­¤¬¤¢¤ê¤̃¤¹¡£"
+
+#: src/stackovf.c:195
+msgid ". Check for possible infinite recursion.\n"
+msgstr ". ̀µ¸Â¤ÎºÆµ¢¸Æ¤Ó½Đ¤·¤¬¹Ô¤ï¤́¤Æ¤¤¤Ê¤¤¤«¤É¤¦¤«¥Á¥§¥Ă¥¯¤·¤Æ²¼¤µ¤¤¡£\n"
+
+#: src/symtab.c:190
+msgid "INTERNAL ERROR: Illegal mode to symbol_lookup ()"
+msgstr "ÆâÉô¥¨¥é¡¼¡§´Ø¿ô symbol_lookup () ¤Ø¤Î°ú¿ô mode ¤¬ÉÔÀµ¤Ç¤¹¡£"
+
+#: src/symtab.c:243
+#, c-format
+msgid "Name `%s' is unknown\n"
+msgstr "`%s' ¤ÏÄêµÁ¤µ¤́¤Æ¤¤¤̃¤»¤ó¡£\n"
+
+#~ msgid "Bad regular expression: `%s': %s"
+#~ msgstr "`%s' : %s ¤Ï¡¢ÉÔÀµ¤ÊÀµµ¬É½¸½¤Ç¤¹¡£"
+
+#~ msgid "%s: option `%s' is ambiguous\n"
+#~ msgstr "%s: `%s' ¤ÏÉỒÀÎƤʥª¥×¥·¥ç¥ó̀¾¤Ç¤¹¡£\n"
+
+#~ msgid "%s: option `--%s' doesn't allow an argument\n"
+#~ msgstr "%s: ¥ª¥×¥·¥ç¥ó `--%s' ¤Ï°ú¿ô¤̣¼è¤ë¤³¤È¤¬¤Ç¤­¤̃¤»¤ó¡£\n"
+
+#~ msgid "%s: option `%c%s' doesn't allow an argument\n"
+#~ msgstr "%s: ¥ª¥×¥·¥ç¥ó `%c%s' ¤Ï°ú¿ô¤̣¼è¤ë¤³¤È¤¬¤Ç¤­¤̃¤»¤ó¡£\n"
+
+#~ msgid "%s: option `%s' requires an argument\n"
+#~ msgstr "%s: ¥ª¥×¥·¥ç¥ó `%s' ¤Ï°ú¿ô¤̣ɬÍפȤ·¤̃¤¹¡£\n"
+
+#~ msgid "%s: unrecognized option `--%s'\n"
+#~ msgstr "%s: --%s ¤Ïǧ¼±¤µ¤́¤Ê¤¤¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£\n"
+
+#~ msgid "%s: unrecognized option `%c%s'\n"
+#~ msgstr "%s: %c%s ¤Ïǧ¼±¤µ¤́¤Ê¤¤¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£\n"
+
+#~ msgid "%s: illegal option -- %c\n"
+#~ msgstr "%s: %c ¤ÏÉÔÀµ¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£\n"
+
+#~ msgid "%s: invalid option -- %c\n"
+#~ msgstr "%s: %c ¤Ï̀µ¸ú¤Ê¥ª¥×¥·¥ç¥ó¤Ç¤¹¡£\n"
+
+#~ msgid "%s: option requires an argument -- %c\n"
+#~ msgstr "%s: %c ¥ª¥×¥·¥ç¥ó¤Ë¤Ï°ú¿ô¤¬É¬ÍפǤ¹¡£\n"
+
+#~ msgid "No previous regular expression"
+#~ msgstr "Àµµ¬É½¸½¤¬ÄêµÁ¤µ¤́¤Æ¤¤¤̃¤»¤ó¡£"
+
+#~ msgid "Memory exhausted"
+#~ msgstr "¥á¥â¥ê¤¬»Ä¤Ă¤Æ¤¤¤̃¤»¤ó¡£"
diff --git a/po/m4.pot b/po/m4.pot
new file mode 100644
index 00000000..75077ee6
--- /dev/null
+++ b/po/m4.pot
@@ -0,0 +1,116 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 1997-10-06 07:30+0159\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#: src/m4.c:106
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr ""
+
+#: src/m4.c:133
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr ""
+
+#: src/m4.c:137
+#, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr ""
+
+#: src/m4.c:138
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+
+#: src/m4.c:151
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr ""
+
+#: src/m4.c:155
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+
+#: src/m4.c:163
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+
+#: src/m4.c:170
+msgid ""
+"\n"
+"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"
+msgstr ""
+
+#: src/m4.c:176
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+
+#: src/m4.c:184
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+
+#: src/m4.c:199
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+
+#: src/m4.c:355
+#, c-format
+msgid "Bad debug flags: `%s'"
+msgstr ""
+
+#: src/m4.c:434
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr ""
diff --git a/po/nl.gmo b/po/nl.gmo
new file mode 100644
index 00000000..1452272f
--- /dev/null
+++ b/po/nl.gmo
Binary files differ
diff --git a/po/nl.po b/po/nl.po
new file mode 100644
index 00000000..fd69a4ff
--- /dev/null
+++ b/po/nl.po
@@ -0,0 +1,464 @@
+# Dutch messages for GNU m4.
+# Copyright (C) 1998 Free Software Foundation, Inc.
+# Erick Branderhorst <Erick.Branderhorst@asml.nl>, 1998.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: m4 1.4d\n"
+"POT-Creation-Date: 1998-05-25 12:26+0200\n"
+"PO-Revision-Date: 1998-05-23 09:27+02:00\n"
+"Last-Translator: Erick Branderhorst <Erick.Branderhorst@asml.nl>\n"
+"Language-Team: dutch <nl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: src/builtin.c:272
+#, c-format
+msgid "Warning: Too few arguments to built-in `%s'"
+msgstr "Let op: Te weinig argument voor ingebouwde functie `%s'"
+
+#: src/builtin.c:278
+#, c-format
+msgid "Warning: Excess arguments to built-in `%s' ignored"
+msgstr ""
+"Let op: Overbodige argumenten voor ingebouwde functie `%s' worden genegeerd"
+
+#: src/builtin.c:298
+#, c-format
+msgid "Non-numeric argument to built-in `%s'"
+msgstr "Niet numeriek argument voor ingebouwde functie `%s'"
+
+#: src/builtin.c:438
+msgid "INTERNAL ERROR: Bad token data type in define_macro ()"
+msgstr "INTERNE FOUT: Onjuist teken data type in define_macro ()"
+
+#: src/builtin.c:608 src/builtin.c:671 src/builtin.c:1188 src/builtin.c:1212
+#, c-format
+msgid "Undefined name %s"
+msgstr "Ongedefinieerde naam %s"
+
+#: src/builtin.c:636
+msgid "INTERNAL ERROR: Builtin not found in builtin table!"
+msgstr "INTERNE FOUT: Ingebouwde functie niet gevonden in functie tabel!"
+
+#: src/builtin.c:644
+msgid "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"
+msgstr "INTERNE FOUT: Onjuist teken data type in m4_dumpdef ()"
+
+#: src/builtin.c:695
+#, c-format
+msgid "Undefined macro `%s'"
+msgstr "Ongedefinieerde macro `%s'"
+
+#: src/builtin.c:735
+msgid "INTERNAL ERROR: Bad symbol type in m4_defn ()"
+msgstr "INTERNE FOUT: Onjuist symbool type in m4_defn ()"
+
+#: src/builtin.c:772
+#, c-format
+msgid "Cannot open pipe to command `%s'"
+msgstr "Kan geen pijp openen voor commando `%s'"
+
+#: src/builtin.c:811
+#, c-format
+msgid "Radix in eval out of range (radix = %d)"
+msgstr "Radix in evaluatie buiten bereik (radix = %d)"
+
+#: src/builtin.c:820
+msgid "Negative width to eval"
+msgstr "Negatieve breedte te evalueren"
+
+#: src/builtin.c:925
+#, c-format
+msgid "Non-numeric argument to %s"
+msgstr "Niet numeriek argument voor %s"
+
+#: src/builtin.c:937
+#, c-format
+msgid "Cannot undivert %s"
+msgstr "Cannot undivert %s"
+
+#: src/builtin.c:1043 src/freeze.c:207
+#, c-format
+msgid "Cannot open %s"
+msgstr "Kan %s niet openen"
+
+#: src/builtin.c:1248
+#, c-format
+msgid "Debugmode: bad debug flags: `%s'"
+msgstr "Debugmode: onjuiste debug vlaggen: `%s'"
+
+#: src/builtin.c:1284
+#, c-format
+msgid "Cannot set error file: %s"
+msgstr "Kan fout bestand niet instellen: %s"
+
+#: src/builtin.c:1501
+msgid "WARNING: \\0 will disappear, use \\& instead in replacements"
+msgstr "LET OP: \\0 zal verdwijnen, gebruik hiervoor \\& als vervanging"
+
+#: src/builtin.c:1562 src/builtin.c:1622 src/input.c:637
+#, c-format
+msgid "Bad regular expression `%s': %s"
+msgstr "Onjuiste reguliere expressie `%s': %s"
+
+#: src/builtin.c:1573 src/builtin.c:1646
+#, c-format
+msgid "Error matching regular expression `%s'"
+msgstr "Fout overeenkomen reguliere expressies `%s'"
+
+#: src/debug.c:379
+msgid "INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"
+msgstr ""
+"INTERNE FOUT: Ingebouwde functie niet gevonden in functie tabel! (trace_pre "
+"())"
+
+#: src/debug.c:387
+msgid "INTERNAL ERROR: Bad token data type (trace_pre ())"
+msgstr "INTERNE FOUT: Onjuiste teken data type (trace_pre ())"
+
+#: src/eval.c:277
+#, c-format
+msgid "Bad expression in eval (missing right parenthesis): %s"
+msgstr "Onjuiste expressie in evaluatie (ontbrekend rechter haakje): %s"
+
+#: src/eval.c:283
+#, c-format
+msgid "Bad expression in eval: %s"
+msgstr "Onjuist expressie in evaluatie: %s"
+
+#: src/eval.c:288
+#, c-format
+msgid "Bad expression in eval (bad input): %s"
+msgstr "Onjuist expressie in evaluatie (onjuiste invoer): %s"
+
+#: src/eval.c:293
+#, c-format
+msgid "Bad expression in eval (excess input): %s"
+msgstr "Onjuist expressie in evaluatie (te veel invoer): %s"
+
+#: src/eval.c:298
+#, c-format
+msgid "Divide by zero in eval: %s"
+msgstr "Delen door nul in evaluatie: %s"
+
+#: src/eval.c:303
+#, c-format
+msgid "Modulo by zero in eval: %s"
+msgstr "Modulo door nul in evaluatie: %s"
+
+#: src/eval.c:308
+msgid "INTERNAL ERROR: Bad error code in evaluate ()"
+msgstr "INTERNE FOUT: Onjuiste fout code in evaluate ()"
+
+#: src/eval.c:547
+msgid "INTERNAL ERROR: Bad comparison operator in cmp_term ()"
+msgstr "INTERNE FOUT: Onjuiste vergelijkings operator in cmp_term ()"
+
+#: src/eval.c:590
+msgid "INTERNAL ERROR: Bad shift operator in shift_term ()"
+msgstr "INTERNE FOUT: Onjuiste schuif operator in shift_term ()"
+
+#: src/eval.c:674
+msgid "INTERNAL ERROR: Bad operator in mult_term ()"
+msgstr "INTERNE FOUT: Onjuiste operator in mult_term ()"
+
+#: src/freeze.c:115
+msgid "INTERNAL ERROR: Built-in not found in builtin table!"
+msgstr "INTERNE FOUT: Ingebouwde functie niet gevonden in functie tabel!"
+
+#: src/freeze.c:128
+msgid "INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"
+msgstr "INTERNE FOUT: Onjuist teken data type in freeze_one_symbol ()"
+
+#: src/freeze.c:159
+msgid "Expecting line feed in frozen file"
+msgstr "Verwacht nieuwe regel in gefixeerd bestand"
+
+#: src/freeze.c:161
+#, c-format
+msgid "Expecting character `%c' in frozen file"
+msgstr "Verwacht karakter `%c' in gefixeerd bestand"
+
+#: src/freeze.c:218
+msgid "Ill-formated frozen file"
+msgstr "Slecht geformateerd gefixeerd bestand"
+
+#: src/freeze.c:273 src/freeze.c:289
+msgid "Premature end of frozen file"
+msgstr "Voorbarig einde van gefixeerd bestand"
+
+#: src/freeze.c:323
+#, c-format
+msgid "`%s' from frozen file not found in builtin table!"
+msgstr "`%s' van gefixeerd bestand niet gevonden in functie tabel!"
+
+#: src/input.c:174
+#, c-format
+msgid "Input read from %s"
+msgstr "Invoer gelezen vanuit %s"
+
+#: src/input.c:231
+msgid "INTERNAL ERROR: Recursive push_string!"
+msgstr "INTERNE FOUT: Recursieve push_string!"
+
+#: src/input.c:311
+#, c-format
+msgid "Input reverted to %s, line %d"
+msgstr "Invoer reverted naar %s, lijn %d"
+
+#: src/input.c:325
+msgid "INTERNAL ERROR: Input stack botch in pop_input ()"
+msgstr "INTERNE FOUT: Invoer stapel botch in pop_input ()"
+
+#: src/input.c:364
+msgid "INTERNAL ERROR: Bad call to init_macro_token ()"
+msgstr "INTERNE FOUT: Onjuiste aanroep naar init_macro_token ()"
+
+#: src/input.c:413
+msgid "INTERNAL ERROR: Input stack botch in peek_input ()"
+msgstr "INTERNE FOUT: Invoer stapel botch in peek_input ()"
+
+#: src/input.c:470
+msgid "INTERNAL ERROR: Input stack botch in next_char ()"
+msgstr "INTERNE FOUT: Invoer stapel botch in next_char ()"
+
+#: src/input.c:550
+msgid "NONE"
+msgstr "GEEN"
+
+#: src/input.c:777
+msgid "ERROR: EOF in string"
+msgstr "FOUT: Einde van bestand teken in string"
+
+#: src/m4.c:106
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr "FOUT: Stapel overflow. (Infinite define recursion?)"
+
+#: src/m4.c:133
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Probeer `%s --help' voor meer informatie.\n"
+
+#: src/m4.c:137
+#, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr "Gebruik: %s [OPTIE]... [BESTAND]...\n"
+
+#: src/m4.c:138
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+"Verplichte of optionele argumenten voor lange opties zijn ook verplicht of\n"
+"optioneel voor korte opties.\n"
+"\n"
+"Operatie modi:\n"
+" --help toon help tekst en beëindig programma\n"
+" --version toon versie informatie en beeindig programma\n"
+" -e, --interactive unbuffer output, negeer interrupts\n"
+" -E, --fatal-warnings stop uitvoering na eerste waarschuwing\n"
+" -Q, --quiet, --silent onderdruk sommige waarschuwingen voor\n"
+" ingebouwde functies\n"
+" -P, --prefix-builtins forceer een `m4_' voorvoegsel voor alle \n"
+" ingebouwde functies\n"
+
+#: src/m4.c:151
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr " -W, --word-regexp=REGEXP gebruik REGEXP voor macro naam syntax\n"
+
+#: src/m4.c:155
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+"\n"
+"Voorbewerkings features:\n"
+" -I, --include=DIRECTORY zoek in tweede instantie in deze directory "
+"voor\n"
+" inclusies\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME verwijder ingebouwde functie NAME\n"
+" -s, --synclines genereer `#line NO \"FILE\"' regel\n"
+
+#: src/m4.c:163
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+"\n"
+"Limieten controlle:\n"
+" -G, --traditional onderdruk alle GNU uitbreidingen\n"
+" -H, --hashsize=PRIME stel symbolen opzoek hash tabel grootte\n"
+" -L, --nesting-limit=NUMBER verander kunstmatige nesting limiet\n"
+
+#: src/m4.c:170
+msgid ""
+"\n"
+"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"
+msgstr ""
+"\n"
+"Gefixeerd staat bestanden:\n"
+" -F, --freeze-state=FILE produceerd een gefixeerd staat van BESTAND\n"
+" aan het einde\n"
+" -R, --reload-state=FILE herlaad een gefixeerde staat van BESTAND\n"
+" aan het begin\n"
+
+#: src/m4.c:176
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[VLAGGEN] stel debug nivo in (geen VLAGGEN \n"
+" impliceert `aeq')\n"
+" -t, --trace=NAAM traceer NAAM wanneer het wordt gedefinieerd\n"
+" -l, --arglength=NUM restrict macro traceer grootte\n"
+" -o, --error-output=FILE redirect debug en traceer uitvoer\n"
+
+#: src/m4.c:184
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+
+#: src/m4.c:199
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+"\n"
+"Als geen BESTAND of als BESTAND `-' is, standaard invoer wordt gelezen.\n"
+
+#: src/m4.c:355
+#, c-format
+msgid "Bad debug flags: `%s'"
+msgstr "Onjuiste debug vlaggen: `%s'"
+
+#: src/m4.c:434
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr "INTERNE FOUT: Onjuiste code in afgeleide argumenten"
+
+#: src/macro.c:92
+msgid "INTERNAL ERROR: Bad token type in expand_token ()"
+msgstr "INTERNE FOUT: Onjuist teken type in expand_token ()"
+
+#: src/macro.c:158
+msgid "ERROR: EOF in argument list"
+msgstr "FOUT: Einde van bestand teken in argumentenlijst"
+
+#: src/macro.c:176
+msgid "INTERNAL ERROR: Bad token type in expand_argument ()"
+msgstr "INTERNE FOUT: Onjuist teken type in expand_argument ()"
+
+#: src/macro.c:253
+msgid "INTERNAL ERROR: Bad symbol type in call_macro ()"
+msgstr "INTERNE FOUT: Onjuist symbool type in call_macro ()"
+
+#: src/macro.c:282
+#, c-format
+msgid "ERROR: Recursion limit of %d exceeded, use -L<N> to change it"
+msgstr ""
+"FOUT: Recursie limiet of %d overschreden, gebruik -L<N> om dit te wijzigen"
+
+#: src/output.c:198
+msgid "ERROR: Cannot create temporary file for diversion"
+msgstr "FOUT: Kan geen tijdelijk bestand aanmaken voor diversion"
+
+#: src/output.c:208
+msgid "ERROR: Cannot flush diversion to temporary file"
+msgstr "FOUT: Kan diversion niet flushen naar tijdelijk bestand"
+
+#: src/output.c:292
+msgid "ERROR: Copying inserted file"
+msgstr "FOUT: Kopieren ingevoegde bestanden"
+
+#: src/output.c:473
+msgid "ERROR: Reading inserted file"
+msgstr "FOUT: Lezen ingevoegd bestand"
+
+#: src/output.c:572
+msgid "Cannot stat diversion"
+msgstr "Cannot stat diversion"
+
+#: src/path.c:131
+#, c-format
+msgid "Path search for `%s' found `%s'"
+msgstr "Zoeken naar `%s' via PATH levert `%s'"
+
+#. sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+#. if the stack limit has not been reached.
+#: src/stackovf.c:168
+msgid "VMEM limit exceeded?\n"
+msgstr "VMEM limiet overschreden?\n"
+
+#: src/stackovf.c:190
+msgid ""
+"Memory bounds violation detected (SIGSEGV). Either a stack overflow\n"
+"occurred, or there is a bug in "
+msgstr ""
+"Geheugen bounds violation gedetecteerd (SIGSEGV). Een stack overflow \n"
+"is opgetreden, of er is een fout in "
+
+#: src/stackovf.c:195
+msgid ". Check for possible infinite recursion.\n"
+msgstr ". Kontroleer voor mogelijk oneindige recusie.\n"
+
+#: src/symtab.c:190
+msgid "INTERNAL ERROR: Illegal mode to symbol_lookup ()"
+msgstr "INTERNE FOUT: Ongeldige mode voor symbol_lookup ()"
+
+#: src/symtab.c:243
+#, c-format
+msgid "Name `%s' is unknown\n"
+msgstr "Naam `%s' is niet bekend\n"
+
+#~ msgid "Bad regular expression: `%s': %s"
+#~ msgstr "Onjuiste reguliere expressie: `%s': %s"
diff --git a/po/pl.gmo b/po/pl.gmo
new file mode 100644
index 00000000..4bb38992
--- /dev/null
+++ b/po/pl.gmo
Binary files differ
diff --git a/po/pl.po b/po/pl.po
new file mode 100644
index 00000000..8cdf9481
--- /dev/null
+++ b/po/pl.po
@@ -0,0 +1,500 @@
+# Polish translations for the GNU m4 messages.
+# Copyright (C) 1998 Free Software Foundation, Inc.
+# Rafa³ Maszkowski <rzm@icm.edu.pl>, 1998.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: m4 1.4.3\n"
+"POT-Creation-Date: 1998-10-04 01:31+0200\n"
+"PO-Revision-Date: 1998-08-05 17:30+0200\n"
+"Last-Translator: Rafa³ Maszkowski <rzm@icm.edu.pl>\n"
+"Language-Team: Polish <pl@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-2\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: src/builtin.c:317
+#, c-format
+msgid "Warning: Too few arguments to built-in `%s'"
+msgstr "Uwaga: Za ma³o argumentów dla wbodowanego `%s'"
+
+#: src/builtin.c:323
+#, c-format
+msgid "Warning: Excess arguments to built-in `%s' ignored"
+msgstr "Uwaga: Nadmiarowe argumenty do built-in `%s' zosta³y zignorowane"
+
+#: src/builtin.c:351
+#, c-format
+msgid "Non-numeric argument to built-in `%s'"
+msgstr "Nienumeryczny argument do built-in `%s'"
+
+#: src/builtin.c:450
+msgid "INTERNAL ERROR: Bad token data type in define_macro ()"
+msgstr "B£¡D WEWNÊTRZNY: Z³y typ danych tokenu w define_macro ()"
+
+#: src/builtin.c:645 src/builtin.c:708 src/builtin.c:1331 src/builtin.c:1355
+#, c-format
+msgid "Undefined name %s"
+msgstr "Niezdefiniowana nazwa %s"
+
+#: src/builtin.c:673
+msgid "INTERNAL ERROR: Builtin not found in builtin table!"
+msgstr "B£¡D WEWNÊTRZNY: Wbudowane nie znalezione w tablicy wbudowanych!"
+
+#: src/builtin.c:681
+msgid "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"
+msgstr "B£¡D WEWNÊTRZNY: Z³y typ danych tokenu w m4_dumpref ()"
+
+#: src/builtin.c:732
+#, c-format
+msgid "Undefined macro `%s'"
+msgstr "Niezdefiniowane makro `%s'"
+
+#: src/builtin.c:772
+msgid "INTERNAL ERROR: Bad symbol type in m4_defn ()"
+msgstr "B£¡D WEWNETRZNY: Z³y typ symbolu w m4_defn ()"
+
+#: src/builtin.c:838
+#, c-format
+msgid "Cannot open pipe to command `%s'"
+msgstr "Nie mogê otworzyæ potoku do komendy `%s'"
+
+#: src/builtin.c:875
+#, c-format
+msgid "Radix in eval out of range (radix = %d)"
+msgstr "Baza w eval poza zakresem (radix = %d)"
+
+#: src/builtin.c:884
+msgid "Negative width to eval"
+msgstr "Ujemna d³ugo¶æ w eval"
+
+#: src/builtin.c:976
+#, c-format
+msgid "Non-numeric argument to %s"
+msgstr "Nienumeryczny argument dla %s"
+
+#: src/builtin.c:988
+#, c-format
+msgid "Cannot undivert %s"
+msgstr "Nie mogê przetowrzyæ z powrotem %s"
+
+#: src/builtin.c:1132
+#, fuzzy, c-format
+msgid "Undefined syntax code %c"
+msgstr "Niezdefiniowana nazwa %s"
+
+#: src/builtin.c:1182 src/freeze.c:207
+#, c-format
+msgid "Cannot open %s"
+msgstr "Nie mogê otworzyæ %s"
+
+#: src/builtin.c:1391
+#, c-format
+msgid "Debugmode: bad debug flags: `%s'"
+msgstr "Tryb debugowania: z³e flagi debugowania: `%s'"
+
+#: src/builtin.c:1427
+#, c-format
+msgid "Cannot set error file: %s"
+msgstr "Nie mogê ustawiæ pliku b³êdów: %s"
+
+#: src/builtin.c:1644
+msgid "WARNING: \\0 will disappear, use \\& instead in replacements"
+msgstr "UWAGA: \\0 zniknie, w podstawieniach u¿yj zamiast tego \\&"
+
+#: src/builtin.c:1705 src/builtin.c:1765 src/input.c:979
+#, c-format
+msgid "Bad regular expression `%s': %s"
+msgstr "B³êdne wyra¿enie regularne `%s': %s"
+
+#: src/builtin.c:1716 src/builtin.c:1789
+#, c-format
+msgid "Error matching regular expression `%s'"
+msgstr "B³±d dopasowania do wyra¿enia regularnego `%s'"
+
+#: src/debug.c:379
+msgid "INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"
+msgstr ""
+"B£¡D WEWNÊTRZNY: Wbudowane nie znalezione w tablicy wbudowanych! (trace_pre "
+"())"
+
+#: src/debug.c:387
+msgid "INTERNAL ERROR: Bad token data type (trace_pre ())"
+msgstr "B£¡D WEWNÊTRZNY: Z³y typ danych tokenu (trace_pre ())"
+
+#: src/eval.c:297
+#, c-format
+msgid "Bad expression in eval (missing right parenthesis): %s"
+msgstr "B³êdne wyra¿enie w eval (brakuj±cy prawy nawias): %s"
+
+#: src/eval.c:303
+#, c-format
+msgid "Bad expression in eval: %s"
+msgstr "B³êdne wyra¿enie w eval: %s"
+
+#: src/eval.c:308
+#, c-format
+msgid "Bad expression in eval (bad input): %s"
+msgstr "B³êdne wyra¿enie w eval (z³e dane wej¶ciowe): %s"
+
+#: src/eval.c:313
+#, c-format
+msgid "Bad expression in eval (excess input): %s"
+msgstr "B³êdne wyra¿enie w eval (nadmiarowe dane): %s"
+
+#: src/eval.c:318
+#, c-format
+msgid "Divide by zero in eval: %s"
+msgstr "Dzielenie przez zero w eval: %s"
+
+#: src/eval.c:323
+#, c-format
+msgid "Modulo by zero in eval: %s"
+msgstr "Modulo zero w eval: %s"
+
+#: src/eval.c:328
+msgid "INTERNAL ERROR: Bad error code in evaluate ()"
+msgstr "B£¡D WEWNÊTRZNY: B³êdny kod b³êdu w evaluate ()"
+
+#: src/eval.c:582
+msgid "INTERNAL ERROR: Bad comparison operator in cmp_term ()"
+msgstr "B£¡D WEWNÊTRZNY: B³êdny operator porównania w cmp_term ()"
+
+#: src/eval.c:627
+msgid "INTERNAL ERROR: Bad shift operator in shift_term ()"
+msgstr "B£¡D WEWNÊTRZNY: B³êdny operator przesuniêcia w shift_term ()"
+
+#: src/eval.c:726
+msgid "INTERNAL ERROR: Bad operator in mult_term ()"
+msgstr "B£¡D WEWNÊTRZNY: B³êdny opertaotr w mult_term ()"
+
+#: src/freeze.c:115
+msgid "INTERNAL ERROR: Built-in not found in builtin table!"
+msgstr "B£¡D WEWNÊTRZNY: Wbudowane nie znalezione w tablicy wbudowanych!"
+
+#: src/freeze.c:128
+msgid "INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"
+msgstr "B£¡D WEWNÊTRZNY: B³êdny typ danych tokenu w freeze_one_symbol ()"
+
+#: src/freeze.c:159
+msgid "Expecting line feed in frozen file"
+msgstr "Oczekiwany line fedd w pliku zamro¿onym"
+
+#: src/freeze.c:161
+#, c-format
+msgid "Expecting character `%c' in frozen file"
+msgstr "Oczekiwany znak `%c' w pliku zamro¿onym"
+
+#: src/freeze.c:218
+msgid "Ill-formated frozen file"
+msgstr "¬le sformatowy plik zamro¿ony"
+
+#: src/freeze.c:273 src/freeze.c:289
+msgid "Premature end of frozen file"
+msgstr "Przedwczesny koniec pliku zamro¿onego"
+
+#: src/freeze.c:323
+#, c-format
+msgid "`%s' from frozen file not found in builtin table!"
+msgstr "`%s' z pliku zamro¿onego nie znalezione w tablicy wbudowanych!"
+
+#: src/input.c:306
+#, c-format
+msgid "Input reverted to %s, line %d"
+msgstr "Dane wej¶ciowe wycofane do %s, linia %d"
+
+#: src/input.c:334
+#, c-format
+msgid "Input read from %s"
+msgstr "Dane wej¶ciowe przeczytane z %s"
+
+#: src/input.c:494
+msgid "INTERNAL ERROR: Recursive push_string!"
+msgstr "B£¡D WEWNÊTRZNY: Rekursywny push_string!"
+
+#: src/input.c:611
+msgid "INTERNAL ERROR: Bad call to init_macro_token ()"
+msgstr "B£¡D WEWNÊTRZNY: B³êdne wywo³anie init_macro_token ()"
+
+#: src/input.c:651
+msgid "INTERNAL ERROR: Input stack botch in next_char ()"
+msgstr "B£¡D WEWNÊTRZNY: B³±d stosu wej¶ciowego w next_char ()"
+
+#: src/input.c:688
+msgid "INTERNAL ERROR: Input stack botch in peek_input ()"
+msgstr "B£¡D WEWNÊTRZNY: B³±d stosu wej¶ciowego w peek_input ()"
+
+#: src/input.c:791
+msgid "NONE"
+msgstr "¯ADEN"
+
+#: src/input.c:1130 src/input.c:1157
+msgid "ERROR: EOF in string"
+msgstr "B£¡D: EOF w ³añcuchu"
+
+#: src/m4.c:106
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr "B£¡D: Przepe³nienie stosu. (Nieskoñczona rekursja definicji?)"
+
+#: src/m4.c:133
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Spróbuj `%s --help' ¿eby dowiedzieæ siê wiêcej.\n"
+
+#: src/m4.c:137
+#, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr "U¿ycie: %s [OPCJA]... [PLIK]...\n"
+
+#: src/m4.c:138
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+"Argumenty obowi±zkowe lub opcjonalne dla opcji d³ugich s± obowi±zkowe lub\n"
+"opcjonalne równie¿ dla krótkich.\n"
+"\n"
+"Tryby pracy:\n"
+" --help wy¶wietl ten opis i zakoñcz\n"
+" --version wy¶wietl informacjê o wersji i zakoñcz\n"
+" -e, --intercative nie buforuj wyj¶cia, ignoruj przerwania\n"
+" -E, --fatal-warnings zatrzymaj siê po pierwszym ostrz¿eniu\n"
+" -Q, --quiet, --silent nie pokazuj niektórych ostrze¿eñ dla "
+"wbudowanych\n"
+" -P, --prefix-builtins dodaj zawsze `m4_' przez wszystkimi "
+"wbudowanymi\n"
+
+#: src/m4.c:151
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr " -W, --word-regexp=WYR_REGUL u¿yj WYR_REGUL w sk³adni nazw makr\n"
+
+#: src/m4.c:155
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+"\n"
+"W³a¶ciwo¶ci preprocesora:\n"
+" -I, --include=KATALOG szukaj includes w tym KATALOGu\n"
+" -D, --define=NAZWA[=WARTO¦Æ] wprowad¼ NAZWÊ z WARTO¦CI¡ lub pust±\n"
+" -U, --undefine=NAZWA skasuj wbudowan± NAZWÊ\n"
+" -s, --synclines generuj linie `#line NR \"PLIK\"\n"
+
+#: src/m4.c:163
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+"\n"
+"Sterowanie ograniczeniami:\n"
+" -G, --traditional wy³±cz wszystkie rozszrzenia GNU\n"
+" -H, --hashzize=PIERWSZA ustaw rozmiar tablicy mieszaj±cej dla "
+"symboli\n"
+" -L, --nesting-limit=LICZBA zmieñ sztuczny limit zag³ebieñ\n"
+
+#: src/m4.c:170
+msgid ""
+"\n"
+"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"
+msgstr ""
+"\n"
+"Zamro¿one pliki stanu:\n"
+" -F, --freeze-state=PLIK zapisz zamro¿ony PLIK stanu na koñcu\n"
+" -R, --reload-state=PLIK za³aduj zamro¿ony PLIK stanu na pocz±tku\n"
+
+#: src/m4.c:176
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+"\n"
+"Debugowanie:\n"
+" -d, --debug=[FLAGI] ustaw poziom debugowania (bez FLAG: `aeg')\n"
+" -t, --trace=NAZWA ¶led¼ NAZWÊ, kiedy bêdzie zdefiniowana\n"
+" -l, --arglength=ILE ogranicz rozmiar ¶ledzenia makr\n"
+" -o, --error-output=PLIK przekieruj wyniki debugowania i ¶ledzenia\n"
+
+#: src/m4.c:184
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+"\n"
+"FLAGI mog± byæ nastêpuj±ce:\n"
+" t ¶led¼ wszystkie wywo³ania makr, nie tylko te z traceon\n"
+" a poka¿ w³a¶ciwe argumenty\n"
+" e poka¿ rozwiniêcie\n"
+" q zabezpiecz znaki specjalne, z flag± a lub e\n"
+" c poka¿ przez zebraniem, po zebraniu i po wywo³aniu\n"
+" x dodaj unikalny identfikator wywo³ania makra, po¿yteczne z flag± c\n"
+" f podaj nazwê bie¿±cego pliku wej¶ciowego\n"
+" l podaj numer bie¿±cej linii\n"
+" p poka¿ wyniki przeszukiwañ ¶cie¿ek\n"
+" i poka¿ zmiany plików wej¶ciowych\n"
+" V skrót do wszystkich powy¿szych flag\n"
+
+#: src/m4.c:199
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+"\n"
+"Je¿eli brak PLIKu lub PLIK to `-', czytane jest std. wej¶cie.\n"
+
+#: src/m4.c:365
+#, c-format
+msgid "Bad debug flags: `%s'"
+msgstr "B³êdne flagi debugowania: `%s'"
+
+#: src/m4.c:444
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr "B£¡D WEWNÊTRZNY: B³êdny kod w od³o¿onych argumentach"
+
+#: src/macro.c:92
+msgid "INTERNAL ERROR: Bad token type in expand_token ()"
+msgstr "B£¡D WEWNÊTRZNY: B³êdny typ tokena w expand_token ()"
+
+#: src/macro.c:158
+msgid "ERROR: EOF in argument list"
+msgstr "B£¡D: EOF w li¶cie argumentów"
+
+#: src/macro.c:176
+msgid "INTERNAL ERROR: Bad token type in expand_argument ()"
+msgstr "B£¡D WEWNÊTRZNY: B³êdny typ tokena w expand_argument ()"
+
+#: src/macro.c:253
+msgid "INTERNAL ERROR: Bad symbol type in call_macro ()"
+msgstr "B£¡D WEWNÊTRZNY: B³êdny symbol w call_macro ()"
+
+#: src/macro.c:282
+#, c-format
+msgid "ERROR: Recursion limit of %d exceeded, use -L<N> to change it"
+msgstr "B£¡D: Osi±gniêty limit rekursji %d, u¿yj -L<N> ¿eby go zmieniæ"
+
+#: src/output.c:198
+msgid "ERROR: Cannot create temporary file for diversion"
+msgstr "B£¡D: Nie mogê utworzyæ plików tymczasowych dla przetwarzania"
+
+#: src/output.c:208
+msgid "ERROR: Cannot flush diversion to temporary file"
+msgstr "B£¡D: Nie mogê zapisac zmian przetwarzania do pliku tymczasowego"
+
+#: src/output.c:292
+msgid "ERROR: Copying inserted file"
+msgstr "B£¡D: Kopiowanie w³o¿onego pliku"
+
+#: src/output.c:473
+msgid "ERROR: Reading inserted file"
+msgstr "B£¡D: Czytanie w³o¿onego pliku"
+
+#: src/output.c:572
+msgid "Cannot stat diversion"
+msgstr "Nie mogê zrobiæ stat na danych przetwarzanych"
+
+#: src/path.c:162
+#, c-format
+msgid "Path search for `%s' found `%s'"
+msgstr "Przeszukanie ¶cie¿ki dla `%s' znalaz³o `%s'"
+
+#: src/path.c:239
+#, fuzzy, c-format
+msgid "Module search for `%s' found `%s'"
+msgstr "Przeszukanie ¶cie¿ki dla `%s' znalaz³o `%s'"
+
+#. sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+#. if the stack limit has not been reached.
+#: src/stackovf.c:168
+msgid "VMEM limit exceeded?\n"
+msgstr "przekroczony limit VMEM\n"
+
+#: src/stackovf.c:190
+msgid ""
+"Memory bounds violation detected (SIGSEGV). Either a stack overflow\n"
+"occurred, or there is a bug in "
+msgstr ""
+"Wykryto pogwa³cenie ograniczeñ adresów pamiêci (SIGSEGV). Albo dosz³o do\n"
+"przepe³nienia stosu albo jest b³±d w "
+
+#: src/stackovf.c:195
+msgid ". Check for possible infinite recursion.\n"
+msgstr ". Sprawd¼ czy nie dosz³o do nieskoñczonej rekursji.\n"
+
+#: src/symtab.c:190
+msgid "INTERNAL ERROR: Illegal mode to symbol_lookup ()"
+msgstr "B£¡D WEWNÊTRZNY: Nielegalny tryb w symbol_lookup ()"
+
+#: src/symtab.c:243
+#, c-format
+msgid "Name `%s' is unknown\n"
+msgstr "Nazwa `%s' jest nieznana\n"
+
+#~ msgid "Bad regular expression: `%s': %s"
+#~ msgstr "Z³e wyra¿enie regularne: `%s': %s"
+
+#~ msgid "INTERNAL ERROR: Input stack botch in pop_input ()"
+#~ msgstr "B£¡D WEWNÊTRZNY: B³±d stosu wej¶ciowego w pop_input ()"
+
+#~ msgid "%s: option `%s' is ambiguous\n"
+#~ msgstr "%s: opcja `%s' jest niejednoznaczna\n"
+
+#~ msgid "%s: option `--%s' doesn't allow an argument\n"
+#~ msgstr "%s: opcja `--%s' nie mo¿e mieæ argumentu\n"
+
+#~ msgid "%s: option `%c%s' doesn't allow an argument\n"
+#~ msgstr "%s: opcja `%c%s' nie mo¿e mieæ argumentu\n"
+
+#~ msgid "%s: option `%s' requires an argument\n"
+#~ msgstr "%s: opcja `%s' wymaga argumentu\n"
+
+#~ msgid "%s: unrecognized option `--%s'\n"
+#~ msgstr "%s: nierozpoznana opcja --%s'\n"
+
+#~ msgid "%s: unrecognized option `%c%s'\n"
+#~ msgstr "%s: nierozpoznana opcja %c%s'\n"
+
+#~ msgid "%s: illegal option -- %c\n"
+#~ msgstr "%s: nielegalna opcja -- %c\n"
+
+#~ msgid "%s: invalid option -- %c\n"
+#~ msgstr "%s: b³êdna opcja -- %c\n"
+
+#~ msgid "%s: option requires an argument -- %c\n"
+#~ msgstr "%s: opcja wymaga argumentu -- %c\n"
+
+#~ msgid "No previous regular expression"
+#~ msgstr "Brak uprzedniego wyra¿enia regularnego"
+
+#~ msgid "Memory exhausted"
+#~ msgstr "Pamiêæ wyczerpana"
diff --git a/po/ru.gmo b/po/ru.gmo
new file mode 100644
index 00000000..bd27331a
--- /dev/null
+++ b/po/ru.gmo
Binary files differ
diff --git a/po/ru.po b/po/ru.po
new file mode 100644
index 00000000..1f847158
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,498 @@
+# ́ÏËÁ̀ÉÚÁĂÉÑ m4-1.4.3
+# Copyright (C) 1997 Free Software Foundation, Inc.
+# Denis Y. Pershin <dyp@siblug.org>, 1997.
+msgid ""
+msgstr ""
+"Project-Id-Version: m4 1.4.3\n"
+"POT-Creation-Date: 1998-08-03 17:14+0200\n"
+"PO-Revision-Date: 1997-07-12 20:58\n"
+"Last-Translator: Denis Y. Pershin <dyp@siblug.org>\n"
+"Language-Team: Russian <ru@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=koi8-r\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: src/builtin.c:272
+#, c-format
+msgid "Warning: Too few arguments to built-in `%s'"
+msgstr "đ̉ÅÄƠĐ̉ÅÖÄÅÎÉÅ: ó̀ÉÛËÏÍ ÍÁ̀Ï Á̉ÇƠÍÅÎÔÏ× Ä̀Ñ ×ÓỔÏÅÎÎÏÊ ̀ÅËÓÅÍÙ '%s'"
+
+#: src/builtin.c:278
+#, c-format
+msgid "Warning: Excess arguments to built-in `%s' ignored"
+msgstr ""
+"đ̉ÅÄƠĐ̉ÅÖÄÅÎÉÅ: éÚÂÙÔÏ̃ÎÙÅ Á̉ÇƠÍÅÎÔÙ Ä̀Ñ ×ÓỔÏÅÎÎÏÊ ̀ÅËÓÅÍÙ '%s' "
+"Đ̉ÏÉÇÎÏ̉É̉Ï×ÁÎÙ"
+
+#: src/builtin.c:298
+#, c-format
+msgid "Non-numeric argument to built-in `%s'"
+msgstr "îÅ ̃ÉÓ̀Ï×ÏÊ Á̉ÇƠÍÅÎÔ Ä̀Ñ ×ÓỔÏÅÎÎÏÊ ̀ÅËÓÅÍÙ '%s'"
+
+#: src/builtin.c:438
+msgid "INTERNAL ERROR: Bad token data type in define_macro ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ÔÉĐ ̀ÅËÓÅÍÙ × define_macro ()"
+
+#: src/builtin.c:608 src/builtin.c:671 src/builtin.c:1188 src/builtin.c:1212
+#, c-format
+msgid "Undefined name %s"
+msgstr "éÍÑ %s ÎÅÏĐ̉ÅÄÅ̀ÅÎÏ"
+
+#: src/builtin.c:636
+msgid "INTERNAL ERROR: Builtin not found in builtin table!"
+msgstr "÷îơộåîîññ ïûéâëá: ÷ÓỔÏÅÎÎÁÑ ̀ÅËÓÅÍÁ ÎÅ ÎÁÊÄÅÎÁ!"
+
+#: src/builtin.c:644
+msgid "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ÔÉĐ ̀ÅËÓÅÍÙ × m4_dumpdef ()"
+
+#: src/builtin.c:695
+#, c-format
+msgid "Undefined macro `%s'"
+msgstr "îÅÏĐ̉ÅÄÅ̀ÅÎÎÙÊ ÍÁË̉ÏÓ '%s'"
+
+#: src/builtin.c:735
+msgid "INTERNAL ERROR: Bad symbol type in m4_defn ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ÔÉĐ ÓÉÍ×Ï̀Á × m4_defn ()"
+
+#: src/builtin.c:772
+#, c-format
+msgid "Cannot open pipe to command `%s'"
+msgstr "îÅ×ÏÚÍÏÖÎÏ ÏÔË̉ÙÔØ ËÁÎÁ̀ Ä̀Ñ ËÏÍÍÁÎÄÙ '%s'"
+
+#: src/builtin.c:811
+#, c-format
+msgid "Radix in eval out of range (radix = %d)"
+msgstr "̣ÁÄÉËÓ × ×Ù̉ÁÖÅÎÉÉ ×ÙÈÏÄÉÔ ÚÁ Đ̉ÅÄÅ̀Ù (radix = %d)"
+
+#: src/builtin.c:820
+msgid "Negative width to eval"
+msgstr "ïỔÉĂÁÔÅ̀ØÎÁÑ ÛÉ̉ÉÎÁ"
+
+#: src/builtin.c:925
+#, c-format
+msgid "Non-numeric argument to %s"
+msgstr "îÅ ̃ÉÓ̀Ï×ÏÊ Á̉ÇƠÍÅÎÔ Ä̀Ñ %s"
+
+#: src/builtin.c:937
+#, c-format
+msgid "Cannot undivert %s"
+msgstr "îÅ×ÏÚÍÏÖÎÏ ×Å̉ÎƠÔØ ×Ù×ÏÄ ÉÚ %s"
+
+#: src/builtin.c:1043 src/freeze.c:207
+#, c-format
+msgid "Cannot open %s"
+msgstr "îÅ×ÏÚÍÏÖÎÏ ÏÔË̉ÙÔØ %s"
+
+#: src/builtin.c:1248
+#, c-format
+msgid "Debugmode: bad debug flags: `%s'"
+msgstr "̣ÅÖÉÍ ÏỒÁÄËÉ: ÎÅ×Å̉ÎÙÊ Æ̀ÁÇ ÏỒÁÄËÉ: '%s'"
+
+#: src/builtin.c:1284
+#, c-format
+msgid "Cannot set error file: %s"
+msgstr "îÅ×ÏÚÍÏÖÎÏ ÎÁÚÎÁ̃ÉÔØ ÆÁỀ ÏÛÉÂÏË %s"
+
+#: src/builtin.c:1501
+msgid "WARNING: \\0 will disappear, use \\& instead in replacements"
+msgstr "đ̣åäơđ̣åöäåîéå: \\0 ÉÓ̃ÅÚÎÅÔ, ÉÓĐÏ̀ØÚƠÊÔÅ \\& × ÚÁÍÅÎÁÈ"
+
+#: src/builtin.c:1562 src/builtin.c:1622 src/input.c:637
+#, c-format
+msgid "Bad regular expression `%s': %s"
+msgstr "îÅ×Å̉ÎÏÅ ̉ÅÇỜÑ̉ÎÏÅ ×Ù̉ÁÖÅÎÉÅ: '%s': %s"
+
+#: src/builtin.c:1573 src/builtin.c:1646
+#, c-format
+msgid "Error matching regular expression `%s'"
+msgstr "ïÛÉÂËÁ ÓÏĐÏÓÔÁ×̀ÅÎÉÑ ̉ÅÇỜÑ̉ÎÏÇÏ ×Ù̉ÁÖÅÎÉÑ '%s'"
+
+#: src/debug.c:379
+msgid "INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"
+msgstr "÷îơộåîîññ ïûéâëá: ÷ÓỔÏÅÎÎÁÑ ̀ÅËÓÅÍÁ ÎÅ ÎÁÊÄÅÎÁ! (trace_pre ())"
+
+#: src/debug.c:387
+msgid "INTERNAL ERROR: Bad token data type (trace_pre ())"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ÔÉĐ ̀ÅËÓÅÍÙ (trace_pre ())"
+
+#: src/eval.c:277
+#, c-format
+msgid "Bad expression in eval (missing right parenthesis): %s"
+msgstr "îÅ×Å̉ÎÏÅ ×Ù̉ÁÖÅÎÉÅ (ÏÔÓƠÔÓÔ×ƠÅÔ Đ̉Á×ÙÅ ÓËÏÂËÉ): %s"
+
+#: src/eval.c:283
+#, c-format
+msgid "Bad expression in eval: %s"
+msgstr "îÅ×Å̉ÎÏÅ ×Ù̉ÁÖÅÎÉÅ: %s"
+
+#: src/eval.c:288
+#, c-format
+msgid "Bad expression in eval (bad input): %s"
+msgstr "îÅ×Å̉ÎÏÅ ×Ù̉ÁÖÅÎÉÅ (bad input): %s"
+
+#: src/eval.c:293
+#, c-format
+msgid "Bad expression in eval (excess input): %s"
+msgstr "îÅ×Å̉ÎÏÅ ×Ù̉ÁÖÅÎÉÅ (excess input): %s"
+
+#: src/eval.c:298
+#, c-format
+msgid "Divide by zero in eval: %s"
+msgstr "äÅ̀ÅÎÉÅ ÎÁ ÎÏ̀Ø × ×Ù̉ÁÖÅÎÉÉ: %s"
+
+#: src/eval.c:303
+#, c-format
+msgid "Modulo by zero in eval: %s"
+msgstr "íÏÄỜØÎÏÅ ÄÅ̀ÅÎÉÅ ÎÁ ÎÏ̀Ø × ×Ù̉ÁÖÅÎÉÉ: %s"
+
+#: src/eval.c:308
+msgid "INTERNAL ERROR: Bad error code in evaluate ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ËÏÄ ÏÛÉÂËÉ × evaluate ()"
+
+#: src/eval.c:547
+msgid "INTERNAL ERROR: Bad comparison operator in cmp_term ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÏÅ Ó̉Á×ÎÅÎÉÅ × cmp_term ()"
+
+#: src/eval.c:590
+msgid "INTERNAL ERROR: Bad shift operator in shift_term ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ÏĐÅ̉ÁÔÏ̉ ÓÄ×ÉÇÁ × shift_term ()"
+
+#: src/eval.c:674
+msgid "INTERNAL ERROR: Bad operator in mult_term ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ÏĐÅ̉ÁÔÏ̉ × mult_term ()"
+
+#: src/freeze.c:115
+msgid "INTERNAL ERROR: Built-in not found in builtin table!"
+msgstr "÷îơộåîîññ ïûéâëá: ÷ÓỔÏÅÎÎÁÑ ̀ÅËÓÅÍÁ ÎÅ ÎÁÊÄÅÎÁ!"
+
+#: src/freeze.c:128
+msgid "INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ÔÉĐ ̀ÅËÓÅÍÙ × freeze_one_symbol ()"
+
+#: src/freeze.c:159
+msgid "Expecting line feed in frozen file"
+msgstr "ïÖÉÄÁÅÔÓÑ ĐÅ̉Å×ÏÄ ÓỔÏËÉ × ÆÁỀÅ-ÏẨÁÚÅ ĐÁÍÑÔÉ"
+
+#: src/freeze.c:161
+#, c-format
+msgid "Expecting character `%c' in frozen file"
+msgstr "ïÖÉÄÁÅÔÓÑ ÓÉÍ×Ï̀ '%c' × ÆÁỀÅ-ÏẨÁÚÅ ĐÁÍÑÔÉ"
+
+#: src/freeze.c:218
+msgid "Ill-formated frozen file"
+msgstr "îÅ×Å̉ÎÙÊ ÆÏ̉ÍÁÔ ÆÁỀÁ-ÏẨÁÚÁ ĐÁÍÑÔÉ"
+
+#: src/freeze.c:273 src/freeze.c:289
+msgid "Premature end of frozen file"
+msgstr "đ̉ÅÖÄÅ×̉ÅÍÅÎÎÙÊ ËÏÎÅĂ ÆÁỀÁ-ÏẨÁÚÁ ĐÁÍÑÔÉ"
+
+#: src/freeze.c:323
+#, c-format
+msgid "`%s' from frozen file not found in builtin table!"
+msgstr "'%s' ÉÚ ÆÁỀÁ-ÏẨÁÚÁ ĐÁÍÑÔÉ ÎÅ ÎÁÊÄÅÎÁ ×Ï ×ÓỔÏÅÎÎÏÊ ÔÁẦÉĂÅ!"
+
+#: src/input.c:174
+#, c-format
+msgid "Input read from %s"
+msgstr "÷×ÏÄ ÉÚ %s"
+
+#: src/input.c:231
+msgid "INTERNAL ERROR: Recursive push_string!"
+msgstr "÷îơộåîîññ ïûéâëá: ̣ÅËỞÓÉ×ÎÁÑ push_string!"
+
+#: src/input.c:311
+#, c-format
+msgid "Input reverted to %s, line %d"
+msgstr "÷×ÏÄ ĐÅ̉ÅÎÁĐ̉Á×̀ÅÎ × %s , ÓỔÏËÁ %d"
+
+#: src/input.c:325
+msgid "INTERNAL ERROR: Input stack botch in pop_input ()"
+msgstr "÷îơộåîîññ ïûéâëá: ïÛÉÂËÁ ×ÈÏÄÎÏÇÏ ÓÔÅËÁ × pop_input ()"
+
+#: src/input.c:364
+msgid "INTERNAL ERROR: Bad call to init_macro_token ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ×ÙÚÏ× init_macro_token ()"
+
+#: src/input.c:413
+msgid "INTERNAL ERROR: Input stack botch in peek_input ()"
+msgstr "÷îơộåîîññ ïûéâëá: ïÛÉÂËÁ ×ÈÏÄÎÏÇÏ ÓÔÅËÁ × peek_input ()"
+
+#: src/input.c:470
+msgid "INTERNAL ERROR: Input stack botch in next_char ()"
+msgstr "÷îơộåîîññ ïûéâëá: ïÛÉÂËÁ ×ÈÏÄÎÏÇÏ ÓÔÅËÁ × next_char ()"
+
+#: src/input.c:550
+msgid "NONE"
+msgstr "îé₫åçï"
+
+#: src/input.c:777
+msgid "ERROR: EOF in string"
+msgstr "ïûéâëá: ëÏÎÅĂ ÆÁỀÁ × ÓỔÏËÅ"
+
+#: src/m4.c:106
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr "ïûéâëá: đÅ̉ÅĐÏ̀ÎÅÎÉÅ ÓÔÅËÁ. (âÅÓËÏÎÅ̃ÎÏÅ ̉ÅËỞÓÉ×ÎÏÅ ÏĐ̉ÅÄÅ̀ÅÎÉÅ?)"
+
+#: src/m4.c:133
+#, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "đÏĐ̉ÏÂƠÊÔÅ '%s --help' Ä̀Ñ ÉÎÆÏ̉ÍÁĂÉÉ.\n"
+
+#: src/m4.c:137
+#, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr "éÓĐÏ̀ØÚÏ×ÁÎÉÅ: %s [OPTION]... [FILE]...\n"
+
+#: src/m4.c:138
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+"ïÂÑÚÁÔÅ̀ØÎÙÅ É̀É ÎÅÏÂÑÚÁÔÅ̀ØÎÙÅ Á̉ÇƠÍÅÎÔÙ Ä̀Ñ Ä̀ÉÎÎÙÈ ÏĐĂÉÉ ÔÁËÏ×Ù É Ä̀Ñ "
+"ËÏ̉ÏÔËÉÈ\n"
+"\n"
+"̣ÅÖÉÍÙ ̉ÁÂÏÔÙ:\n"
+" --help ĐÏËÁÚÁÔØ ĐÏÍÏƯØ É ×ÙÊÔÉ\n"
+" --version ×Ù×ÅÓÔÉ ÉÎÆÏ̉ÍÁĂÉÀ Ï ×Å̉ÓÉÉ É ×ÙÊÔÉ\n"
+" -e, --interactive ÎÅÂƠÆÅ̉ÉÚÏ×ÁÎÎÙÊ ×Ù×ÏÄ, ÉÇÎÏ̉É̉Ï×ÁÔØ "
+"Đ̉Å̉Ù×ÁÎÉÑ\n"
+" -E, --fatal-warnings ÏÓÔÁÎÏ×ÉÔØÓÑ ĐÏÓ̀Å ĐÅ̉×ÏÇÏ Đ̉ÅÄƠĐ̉ÅÖÄÅÎÉÑ\n"
+" -Q, --quiet, --silent ĐÏÄÁ×̀ÑÔØ Đ̉ÅÄƠĐ̉ÅÖÄÅÎÉÑ Ä̀Ñ ×ÓỔÏÅÎÎÙÈ "
+"ÆƠÎËĂÉÊ\n"
+" -P, --prefix-builtins ÄÏÂÁ×̀ÑÔØ Đ̉ÅÆÉËÓ `m4_' Ä̀Ñ ×ÓÅÈ ×ÓỔÏÅÎÎÙÈ "
+"ÆƠÎËĂÉÊ\n"
+
+#: src/m4.c:151
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr ""
+" -W, --word-regexp=REGEXP ÉÓĐÏ̀ØÚÏ×ÁÔØ REGEXP Ä̀Ñ ÓÉÎÔÁËÓÉÓÁ ÉÍÅÎ "
+"ÍÁË̉ÏÓÏ×\n"
+
+#: src/m4.c:155
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+"\n"
+"ïĐĂÉÉ Đ̉ÅĐ̉ÏĂÅÓÓÏ̉Á:\n"
+" -I, --include=DIRECTORY ÉÓËÁÔØ × ĐÏÄËÁÔÁ̀ÏÇÅ ×Ë̀À̃ÁÅÍÙÅ ÆÁỀÙ\n"
+" -D, --define=NAME[=VALUE] ÏĐ̉ÅÄÅ̀ÉÔØ, ̃ÔÏ NAME ÉÍÅÅÔ VALUE, É̀É ĐƠÓÔ\n"
+" -U, --undefine=NAME ƠÄÁ̀ÉÔØ ×ÓỔÏÅÎÎƠÀ ÆƠÎËĂÉÀ NAME\n"
+" -s, --synclines ÇÅÎÅ̉É̉Ï×ÁÔØ ÓỔÏËÉ `#line NO \"FILE\"'\n"
+
+#: src/m4.c:163
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+"\n"
+"ïÇ̉ÁÎÉ̃ÅÎÉÑ:\n"
+" -G, --traditional ĐÏÄÁ×̀ÑÔØ ×ÓÅ GNU ̉ÁÓÛÉ̉ÅÎÉÑ\n"
+" -H, --hashsize=PRIME ƠÓÔÁÎÏ×ÉÔØ ̉ÁÚÍÅ̉ ÈÜÛ-ÔÁẦÉĂÙ Ä̀Ñ ĐÏÉÓËÁ "
+"ÓÉÍ×Ï̀Ï×\n"
+" -L, --nesting-limit=NUMBER ÉÚÍÅÎÉÔØ Đ̉ÅÄÅ̀ Ç̀ƠÂÉÎÙ ÉÎÔÅ̀ÅËÔƠÁ̀ØÎÏÇÏ "
+"ĐÏÉÓËÁ\n"
+
+#: src/m4.c:170
+msgid ""
+"\n"
+"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"
+msgstr ""
+"\n"
+"ầÏËÉ̉Ï×ÁÎÎÙÅ ÆÁỀÙ:\n"
+" -F, --freeze-state=FILE × ËÏÎĂÅ ÓÏÚÄÁÔØ ÏẨÁÚ ĐÁÍÑÔÉ Ä̀Ñ FILE\n"
+" -R, --reload-state=FILE × ÎÁ̃Á̀Å ÚÁÇ̉ƠÖÁÔØ ÏẨÁÚ ĐÁÍÑÔÉ Ä̀Ñ FILE\n"
+
+#: src/m4.c:176
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+"\n"
+"ïỒÁÄËÁ:\n"
+" -d, --debug=[FLAGS] ƠÓÔÁÎÏ×ÉÔØ ỞÏ×ÅÎØ ÏỒÁÄËÉ (ĐÏ ƠÍÏ̀̃ÁÎÉÀ "
+"FLAGS=`aeq')\n"
+" -t, --trace=NAME ỔÁÓÓÉ̉Ï×ÁÔØ NAME ËÏÇÄÁ ÏÎÏ ÂƠÄÅÔ ÏĐ̉ÅÄÅ̀ÅÎÏ\n"
+" -l, --arglength=NUM ƠÓÔÁÎÏ×ÉÔØ ̉ÁÚÍÅ̉ ỔÁÓÓÉ̉Ï×ËÉ Ä̀Ñ ÍÁË̉ÏÓÁ\n"
+" -o, --error-output=FILE ĐÅ̉ÅÎÁĐ̉Á×ÉÔØ ÏỒÁÄÏ̃ÎÙÊ É ỔÁÓÓÉ̉Ï×Ï̃ÎÙÊ "
+"×Ù×ÏÄ × ÆÁỀ FILE\n"
+
+#: src/m4.c:184
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+"\n"
+"FLAGS is any of:\n"
+" t ỔÁÓÓÉ̉Ï×ÁÔØ ×ÓÅ ×ÙÚÏ×Ù ÍÁË̉ÏÓÏ×\n"
+" a ĐÏËÁÚÁÔØ ÔÅËƠƯÉÅ Á̉ÇƠÍÅÎÔÙ\n"
+" e ĐÏËÁÚÙ×ÁÔØ ÍÁË̉Ï̉ÁÓÛÉ̉ÅÎÉÅ\n"
+" q ÚÁË̀À̃ÁÔØ ÚÎÁ̃ÅÎÉÑ × ËÁ×Ù̃ËÉ ĐÏ ÎÅÏÂÈÏÄÉÍÏÓÔÉ, Ó a É̀É e Æ̀ÁÇÁÍÉ\n"
+" c ĐÏËÁÚÙ×ÁÔØ ĐÅ̉ÅÄ ÓÂÏ̉ÏÍ , ĐÏÓ̀Å ÓÂÏ̉Á É ĐÏÓ̀Å ×ÙÚÏ×Á\n"
+" x ÄÏÂÁ×̀ÑÔØ ƠÎÉËÁ̀ØÎÙÊ ÉÄÅÎÔÉÆÉËÁÔÏ̉ ×ÙÚÏ×Á ÍÁË̉ÏÓÁ, ÉÓĐÏ̀ØÚƠÅÔÓÑ ×ÍÅÓÔÅ "
+"Ó Æ̀ÁÇÏÍ c\n"
+" f ×Ù×ÏÄÉÔØ ÔÅËƠƯÅÅ ÉÍÑ ×ÈÏÄÎÏÇÏ ÆÁỀÁ\n"
+" l ×Ù×ÏÄÉÔØ ÎÏÍÅ̉ ÔÅËƠƯÅÊ ÓỔÏ̃ËÉ\n"
+" p ĐÏËÁÚÙ×ÁÔØ ̉ÅÚỜØÔÁÔÙ ĐÏÉÓËÁ ĐÏ ĐƠÔÑÍ\n"
+" i ĐÏËÁÚÙ×ÁÔØ ÉÚÍÅÎÅÎÉÑ ×Ï ×ÈÏÄÎÙÈ ÆÁỀÁÈ\n"
+" V ÓÏË̉ÁƯÅÎÉÅ Ä̀Ñ ×ÓÅÈ Æ̀ÁÇÏ× ×ÍÅÓÔÅ\n"
+
+#: src/m4.c:199
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+"\n"
+"åÓ̀É FILE ÎÅ ÓƠƯÅÓÔ×ƠÅÔ É̀É FILE ÜÔÏ `-', ÉÓĐÏ̀ØÚƠÅÔÓÑ ÓÔÁÎÄÁ̉ÔÎÙÊ ×ÈÏÄ.\n"
+
+#: src/m4.c:358
+#, c-format
+msgid "Bad debug flags: `%s'"
+msgstr "îÅ×Å̉ÎÙÊ Æ̀ÁÇ ÏỒÁÄËÉ: '%s'"
+
+#: src/m4.c:437
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ËÏÄ × ËÏÓ×ÅÎÎÙÈ Á̉ÇƠÍÅÎÔÁÈ"
+
+#: src/macro.c:92
+msgid "INTERNAL ERROR: Bad token type in expand_token ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ÔÉĐ ̀ÅËÓÅÍÙ × expand_token ()"
+
+#: src/macro.c:158
+msgid "ERROR: EOF in argument list"
+msgstr "ïûéâëá: ëÏÎÅĂ ÆÁỀÁ × ÓĐÉÓËÅ Á̉ÇƠÍÅÎÔÏ×"
+
+#: src/macro.c:176
+msgid "INTERNAL ERROR: Bad token type in expand_argument ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ÔÉĐ ̀ÅËÓÅÍÙ × expand_argument ()"
+
+#: src/macro.c:253
+msgid "INTERNAL ERROR: Bad symbol type in call_macro ()"
+msgstr "÷îơộåîîññ ïûéâëá: îÅ×Å̉ÎÙÊ ÔÉĐ ÓÉÍ×Ï̀Á × call_macro ()"
+
+#: src/macro.c:282
+#, c-format
+msgid "ERROR: Recursion limit of %d exceeded, use -L<N> to change it"
+msgstr ""
+"ïûéâëá: ́ÉÍÉÔ ̉ÅËỞÓÉÉ %d ÉÓ̃Å̉ĐÁÎ, ÉÓĐÏ̀ØÚƠÊÔÅ -L<N> ̃ÔÏÂÙ ÉÚÍÅÎÉÔØ ÅÇÏ"
+
+#: src/output.c:198
+msgid "ERROR: Cannot create temporary file for diversion"
+msgstr "ïûéâëá: îÅ ÍÏÇƠ ÓÏÚÄÁÔØ ×̉ÅÍÅÎÎÙÊ ÆÁỀ Ä̀Ñ ̉ÁÚ×ÅÔ×̀ÅÎÉÑ ÍÁË̉ÏÏẨÁÂÏÔËÉ"
+
+#: src/output.c:208
+msgid "ERROR: Cannot flush diversion to temporary file"
+msgstr "ïûéâëá: îÅ ÍÏÇƠ ÚÁĐÉÓÁÔØ ̉ÁÚ×ÅÔ×̀ÅÎÉÅ ×Ï ×̉ÅÍÅÎÎÙÊ ÆÁỀ"
+
+#: src/output.c:292
+msgid "ERROR: Copying inserted file"
+msgstr "ïûéâëá: ëÏĐÉ̉ƠÀ ×ÓÔÁ×̀ÅÎÎÙÊ ÆÁỀ"
+
+#: src/output.c:473
+msgid "ERROR: Reading inserted file"
+msgstr "ïûéâëá: ₫ÉÔÁÀ ×ÓÔÁ×̀ÅÎÎÙÊ ÆÁỀ"
+
+#: src/output.c:572
+msgid "Cannot stat diversion"
+msgstr "îÅ×ÏÚÍÏÖÎÏ ĐÏÄÓ̃ÉÔÁÔØ ̉ÁÚ×ÅÔ×̀ÅÎÉÅ"
+
+#: src/path.c:131
+#, c-format
+msgid "Path search for `%s' found `%s'"
+msgstr "đƠÔØ ĐÏÉÓËÁ Ä̀Ñ `%s' ÎÁÊÄÅÎ `%s'"
+
+#. sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+#. if the stack limit has not been reached.
+#: src/stackovf.c:168
+msgid "VMEM limit exceeded?\n"
+msgstr "ëÏÎ̃É̀ÁÓØ ×É̉ÔƠÁ̀ØÎÁÑ ĐÁÍÑÔØ?\n"
+
+#: src/stackovf.c:190
+msgid ""
+"Memory bounds violation detected (SIGSEGV). Either a stack overflow\n"
+"occurred, or there is a bug in "
+msgstr ""
+"ïÂÎÁ̉ƠÖÅÎ ×ÙÈÏÄ ÚÁ Ç̉ÁÎÉĂƠ ĐÁÍÑÔÉ (SIGSEGV). üÔÏ ̀ÉÂÏ ĐÅ̉ÅĐÏ̀ÎÅÎÉÅ ÓÔÅËÁ\n"
+"É̀É ÏÛÉÂËÁ × "
+
+#: src/stackovf.c:195
+msgid ". Check for possible infinite recursion.\n"
+msgstr ". đ̉Ï×Å̉ËÁ ÎÁ ×ÏÚÍÏÖÎƠÀ ÂÅÓËÏÎÅ̃ÎƠÀ ̉ÅËỞÓÉÀ.\n"
+
+#: src/symtab.c:190
+msgid "INTERNAL ERROR: Illegal mode to symbol_lookup ()"
+msgstr "÷îơộåîîññ ïûéâëá: ÎÅ×Å̉ÎÙÊ ̉ÅÖÉÍ Ä̀Ñ symbol_lookup ()"
+
+#: src/symtab.c:243
+#, c-format
+msgid "Name `%s' is unknown\n"
+msgstr "éÍÑ `%s' ÎÅÉÚ×ÅÓÔÎÏ\n"
+
+#~ msgid "Bad regular expression: `%s': %s"
+#~ msgstr "îÅ×Å̉ÎÏÅ ̉ÅÇỜÑ̉ÎÏÅ ×Ù̉ÁÖÅÎÉÅ: '%s': %s"
+
+#~ msgid "%s: option `%s' is ambiguous\n"
+#~ msgstr "%s: ÏĐĂÉÑ `%s' ÎÅÏÄÎÏÚÎÁ̃ÎÁ\n"
+
+#~ msgid "%s: option `--%s' doesn't allow an argument\n"
+#~ msgstr "%s: Ơ ÏĐĂÉÉ `--%s' ÎÅ ÄÏ̀ÖÎÏ ÂÙÔØ Á̉ÇƠÍÅÎÔÏ×\n"
+
+#~ msgid "%s: option `%c%s' doesn't allow an argument\n"
+#~ msgstr "%s: Ơ ÏĐĂÉÉ `%c%s' ÎÅ ÄÏ̀ÖÎÏ ÂÙÔØ Á̉ÇƠÍÅÎÔÏ×\n"
+
+#~ msgid "%s: option `%s' requires an argument\n"
+#~ msgstr "%s: Ơ ÏĐĂÉÉ `%s' ÄÏ̀ÖÅÎ ÂÙÔØ Á̉ÇƠÍÅÎÔ\n"
+
+#~ msgid "%s: unrecognized option `--%s'\n"
+#~ msgstr "%s: ÎÅÉÚ×ÅÓÔÎÁÑ ÏĐĂÉÑ `--%s'\n"
+
+#~ msgid "%s: unrecognized option `%c%s'\n"
+#~ msgstr "%s: ÎÅÉÚ×ÅÓÔÎÁÑ ÏĐĂÉÑ '%c%s'\n"
+
+#~ msgid "%s: illegal option -- %c\n"
+#~ msgstr "%s: ÚÁĐ̉ÅƯÅÎÎÁÑ ÏĐĂÉÑ -- %c\n"
+
+#~ msgid "%s: invalid option -- %c\n"
+#~ msgstr "%s: ÎÅ×Å̉ÎÁÑ ÏĐĂÉÑ -- %c\n"
+
+#~ msgid "%s: option requires an argument -- %c\n"
+#~ msgstr "%s: ÏĐĂÉÉ ÎÅÏÂÈÏÄÉÍ Á̉ÇƠÍÅÎÔ -- %c\n"
+
+#~ msgid "No previous regular expression"
+#~ msgstr "îÅÔ Đ̉ÅÄÛÅÄÓÔ×ƠÀƯÅÇÏ ̉ÅÇỜÑ̉ÎÏÇÏ ×Ù̉ÁÖÅÎÉÑ"
+
+#~ msgid "Memory exhausted"
+#~ msgstr "đÁÍÑÔØ ÉÓ̃Å̉ĐÁÎÁ"
diff --git a/po/stamp-cat-id b/po/stamp-cat-id
new file mode 100644
index 00000000..9788f702
--- /dev/null
+++ b/po/stamp-cat-id
@@ -0,0 +1 @@
+timestamp
diff --git a/po/sv.gmo b/po/sv.gmo
new file mode 100644
index 00000000..2cebf070
--- /dev/null
+++ b/po/sv.gmo
Binary files differ
diff --git a/po/sv.po b/po/sv.po
new file mode 100644
index 00000000..73ef692a
--- /dev/null
+++ b/po/sv.po
@@ -0,0 +1,549 @@
+# Swedish messages for m4
+# Copyright (C) 1996 Free Software Foundation, Inc.
+# <Jan.Djarv@mbox200.swipnet.se>, 1996.
+# $Revision$
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: m4 1.4.3\n"
+"POT-Creation-Date: 1998-08-03 17:14+0200\n"
+"PO-Revision-Date: $Date$\n"
+"Last-Translator: Jan Djärv <Jan.Djarv@mbox200.swipnet.se>\n"
+"Language-Team: Swedish <sv@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=ISO-8859-1\n"
+"Content-Transfer-Encoding: 8-bit\n"
+
+#: src/builtin.c:272
+#, fuzzy, c-format
+msgid "Warning: Too few arguments to built-in `%s'"
+msgstr "Varning: För få argument till inbyggt makro \"%s\""
+
+#: src/builtin.c:278
+#, fuzzy, c-format
+msgid "Warning: Excess arguments to built-in `%s' ignored"
+msgstr "Varning: Överskottsargument till inbyggt makro \"%s\" ignorerade"
+
+#: src/builtin.c:298
+#, fuzzy, c-format
+msgid "Non-numeric argument to built-in `%s'"
+msgstr "Ickenumeriskt argument till inbyggt makro \"%s\""
+
+#: src/builtin.c:438
+#, fuzzy
+msgid "INTERNAL ERROR: Bad token data type in define_macro ()"
+msgstr "INTERNT FEL: Otillåten lexikalisk datatyp i define_macro ()"
+
+#: src/builtin.c:608 src/builtin.c:671 src/builtin.c:1188 src/builtin.c:1212
+#, fuzzy, c-format
+msgid "Undefined name %s"
+msgstr "Odefinierat namn \"%s\""
+
+#: src/builtin.c:636
+#, fuzzy
+msgid "INTERNAL ERROR: Builtin not found in builtin table!"
+msgstr "INTERNT FEL: Inbyggt makro finns inte i tabellen!"
+
+#: src/builtin.c:644
+#, fuzzy
+msgid "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"
+msgstr "INTERNT FEL: Otillåten lexikalisk datatyp i m4_dumpdef ()"
+
+#: src/builtin.c:695
+#, fuzzy, c-format
+msgid "Undefined macro `%s'"
+msgstr "Odefinierat makro \"%s\""
+
+#: src/builtin.c:735
+#, fuzzy
+msgid "INTERNAL ERROR: Bad symbol type in m4_defn ()"
+msgstr "INTERNT FEL: Otillåten symboltyp i m4_defn ()"
+
+#: src/builtin.c:772
+#, fuzzy, c-format
+msgid "Cannot open pipe to command `%s'"
+msgstr "Kan inte skapa rör till kommandot \"%s\""
+
+#: src/builtin.c:811
+#, fuzzy, c-format
+msgid "Radix in eval out of range (radix = %d)"
+msgstr "Otillåten bas i \"eval\" (bas = %d)"
+
+#: src/builtin.c:820
+#, fuzzy
+msgid "Negative width to eval"
+msgstr "Negativ bredd till \"eval\""
+
+#: src/builtin.c:925
+#, fuzzy, c-format
+msgid "Non-numeric argument to %s"
+msgstr "Ickenumeriskt argument till %s"
+
+#: src/builtin.c:937
+#, fuzzy, c-format
+msgid "Cannot undivert %s"
+msgstr "Kan inte återleda %s"
+
+#: src/builtin.c:1043 src/freeze.c:207
+#, fuzzy, c-format
+msgid "Cannot open %s"
+msgstr "Kan inte öppna %s"
+
+#: src/builtin.c:1248
+#, fuzzy, c-format
+msgid "Debugmode: bad debug flags: `%s'"
+msgstr "Felsökningsläge: okänd flagga: \"%s\""
+
+#: src/builtin.c:1284
+#, fuzzy, c-format
+msgid "Cannot set error file: %s"
+msgstr "Kan inte sätta felutskriftsfil: %s"
+
+#: src/builtin.c:1501
+#, fuzzy
+msgid "WARNING: \\0 will disappear, use \\& instead in replacements"
+msgstr "VARNING: \\0 kommer att försvinna, använd \\& i ersättningar"
+
+#: src/builtin.c:1562 src/builtin.c:1622 src/input.c:637
+#, fuzzy, c-format
+msgid "Bad regular expression `%s': %s"
+msgstr "Otillåtet reguljäruttryck \"%s\": %s"
+
+#: src/builtin.c:1573 src/builtin.c:1646
+#, fuzzy, c-format
+msgid "Error matching regular expression `%s'"
+msgstr "Reguljäruttrycket \"%s\" matchar inte"
+
+#: src/debug.c:379
+#, fuzzy
+msgid "INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"
+msgstr "INTERNT FEL: Inbyggt makro finns inte i tabellen (trace_pre ())"
+
+#: src/debug.c:387
+#, fuzzy
+msgid "INTERNAL ERROR: Bad token data type (trace_pre ())"
+msgstr "INTERNT FEL: Otillåten lexikalisk datatyp (trace_pre ())"
+
+#: src/eval.c:277
+#, fuzzy, c-format
+msgid "Bad expression in eval (missing right parenthesis): %s"
+msgstr "Otillåtet uttryck i \"eval\" (högerparentes saknas): %s"
+
+#: src/eval.c:283
+#, fuzzy, c-format
+msgid "Bad expression in eval: %s"
+msgstr "Otillåtet uttryck i \"eval\": %s"
+
+#: src/eval.c:288
+#, fuzzy, c-format
+msgid "Bad expression in eval (bad input): %s"
+msgstr "Otillåtet uttryck i \"eval\" (otillåtet indata): %s"
+
+#: src/eval.c:293
+#, fuzzy, c-format
+msgid "Bad expression in eval (excess input): %s"
+msgstr "Otillåtet uttryck i \"eval\" (för mycket indata): %s"
+
+#: src/eval.c:298
+#, fuzzy, c-format
+msgid "Divide by zero in eval: %s"
+msgstr "Division med noll i \"eval\": %s"
+
+#: src/eval.c:303
+#, fuzzy, c-format
+msgid "Modulo by zero in eval: %s"
+msgstr "Modulo med noll i \"eval\": %s"
+
+#: src/eval.c:308
+#, fuzzy
+msgid "INTERNAL ERROR: Bad error code in evaluate ()"
+msgstr "INTERNT FEL: Otillåten felkod i evaluate ()"
+
+#: src/eval.c:547
+#, fuzzy
+msgid "INTERNAL ERROR: Bad comparison operator in cmp_term ()"
+msgstr "INTERNT FEL: Otillåten jämförelseoperator i cmp_term ()"
+
+#: src/eval.c:590
+#, fuzzy
+msgid "INTERNAL ERROR: Bad shift operator in shift_term ()"
+msgstr "INTERNT FEL: Otillåten skiftoperator i shift_term ()"
+
+#: src/eval.c:674
+#, fuzzy
+msgid "INTERNAL ERROR: Bad operator in mult_term ()"
+msgstr "INTERNT FEL: Otillåten operator i mult_term ()"
+
+#: src/freeze.c:115
+#, fuzzy
+msgid "INTERNAL ERROR: Built-in not found in builtin table!"
+msgstr "INTERNT FEL: Inbyggt makro finns inte i tabellen!"
+
+#: src/freeze.c:128
+#, fuzzy
+msgid "INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"
+msgstr "INTERNT FEL: Otillåten lexikalisk datatyp i freeze_one_symbol ()"
+
+#: src/freeze.c:159
+#, fuzzy
+msgid "Expecting line feed in frozen file"
+msgstr "Förväntar nyrad i fryst fil"
+
+#: src/freeze.c:161
+#, fuzzy, c-format
+msgid "Expecting character `%c' in frozen file"
+msgstr "Förväntar tecknet \"%c\" i fryst fil"
+
+#: src/freeze.c:218
+#, fuzzy
+msgid "Ill-formated frozen file"
+msgstr "Korrupt fryst fil"
+
+#: src/freeze.c:273 src/freeze.c:289
+#, fuzzy
+msgid "Premature end of frozen file"
+msgstr "För tidigt filslut i fryst fil"
+
+#: src/freeze.c:323
+#, fuzzy, c-format
+msgid "`%s' from frozen file not found in builtin table!"
+msgstr "\"%s\" från fryst fil hittades inte i tabellen för inbyggda makron!"
+
+#: src/input.c:174
+#, fuzzy, c-format
+msgid "Input read from %s"
+msgstr "Indata läses från %s"
+
+#: src/input.c:231
+#, fuzzy
+msgid "INTERNAL ERROR: Recursive push_string!"
+msgstr "INTERNT FEL: Rekursiv push_string!"
+
+#: src/input.c:311
+#, fuzzy, c-format
+msgid "Input reverted to %s, line %d"
+msgstr "Indata återgår till %s, rad %d"
+
+#: src/input.c:325
+#, fuzzy
+msgid "INTERNAL ERROR: Input stack botch in pop_input ()"
+msgstr "INTERNT FEL: Instacken havererade i pop_input ()"
+
+#: src/input.c:364
+#, fuzzy
+msgid "INTERNAL ERROR: Bad call to init_macro_token ()"
+msgstr "INTERNT FEL: Otillåtet anrop till init_macro_token ()"
+
+#: src/input.c:413
+#, fuzzy
+msgid "INTERNAL ERROR: Input stack botch in peek_input ()"
+msgstr "INTERNT FEL: Instacken havererade i peek_input ()"
+
+#: src/input.c:470
+#, fuzzy
+msgid "INTERNAL ERROR: Input stack botch in next_char ()"
+msgstr "INTERNT FEL: Instacken havererade i next_char ()"
+
+#: src/input.c:550
+#, fuzzy
+msgid "NONE"
+msgstr "INGET"
+
+#: src/input.c:777
+#, fuzzy
+msgid "ERROR: EOF in string"
+msgstr "FEL: Filslut i sträng"
+
+#: src/m4.c:106
+#, fuzzy
+msgid "ERROR: Stack overflow. (Infinite define recursion?)"
+msgstr "FEL: Stacken flödar över. (Oändlig rekursion?)"
+
+#: src/m4.c:133
+#, fuzzy, c-format
+msgid "Try `%s --help' for more information.\n"
+msgstr "Försök med \"%s --help\" för mer information.\n"
+
+#: src/m4.c:137
+#, fuzzy, c-format
+msgid "Usage: %s [OPTION]... [FILE]...\n"
+msgstr "Användning: %s [FLAGGA]... [FIL]...\n"
+
+#: src/m4.c:138
+#, fuzzy
+msgid ""
+"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"
+" -e, --interactive unbuffer output, ignore interrupts\n"
+" -E, --fatal-warnings stop execution after first warning\n"
+" -Q, --quiet, --silent suppress some warnings for builtins\n"
+" -P, --prefix-builtins force a `m4_' prefix to all builtins\n"
+msgstr ""
+"Obligatoriska respektive valfria argument för långa flaggor är\n"
+"obligatoriska respektive valfria även för korta flaggor.\n"
+"\n"
+"Körlägen:\n"
+" --help visa denna hjälptext och avsluta\n"
+" --version visa versionsinformation och avsluta\n"
+" -e, --interactive obuffrad utskrift, ignorera avbrott\n"
+" -E, --fatal-warnings avsluta exekvering efter första varningen\n"
+" -Q, --quiet, --silent undertryck vissa varningar för inbyggda "
+"makron\n"
+" -P, --prefix-builtins alla inbyggda makron börjar med `m4_'\n"
+
+#: src/m4.c:151
+#, fuzzy
+msgid " -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n"
+msgstr " -W, --word-regexp=REGEXP använd REGEXP som makronamnsyntax\n"
+
+#: src/m4.c:155
+#, fuzzy
+msgid ""
+"\n"
+"Preprocessor features:\n"
+" -I, --include=DIRECTORY search this directory second for includes\n"
+" -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n"
+" -U, --undefine=NAME delete builtin NAME\n"
+" -s, --synclines generate `#line NO \"FILE\"' lines\n"
+msgstr ""
+"\n"
+"Förprocessorstyrning:\n"
+" -I, --include=KATALOG sök i katalog efter inkluderade filer\n"
+" -D, --define=NAMN[=VÄRDE] definiera NAMN som VÄRDE, eller tomt\n"
+" -U, --undefine=NAMN ta bort inbyggt makro\n"
+" -s, --synclines generera `#line NNN \"FIL\"' rader\n"
+
+#: src/m4.c:163
+#, fuzzy
+msgid ""
+"\n"
+"Limits control:\n"
+" -G, --traditional suppress all GNU extensions\n"
+" -H, --hashsize=PRIME set symbol lookup hash table size\n"
+" -L, --nesting-limit=NUMBER change artificial nesting limit\n"
+msgstr ""
+"\n"
+"Begränsningskontroll:\n"
+" -G, --traditional undertryck alla extra GNU tillägg\n"
+" -H, --hashsize=PRIMTAL sätt storlek på symboltabellen\n"
+" -L, --nesting-limit=NUMMER ändra artificiell nästningsnivå\n"
+
+#: src/m4.c:170
+#, fuzzy
+msgid ""
+"\n"
+"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"
+msgstr ""
+"\n"
+"Frysta tillståndsfiler:\n"
+" -F, --freeze-state=FIL spara fryst tillstånd i FIL i slutet\n"
+" -R, --reload-state=FIL läs fryst tillstånd från FIL i början\n"
+
+#: src/m4.c:176
+#, fuzzy
+msgid ""
+"\n"
+"Debugging:\n"
+" -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n"
+" -t, --trace=NAME trace NAME when it will be defined\n"
+" -l, --arglength=NUM restrict macro tracing size\n"
+" -o, --error-output=FILE redirect debug and trace output\n"
+msgstr ""
+"\n"
+"Felsökning:\n"
+" -d, --debug=[FLAGGOR] sätt felsökningsnivå\n"
+" (inga FLAGGOR tolkas som \"aeq\")\n"
+" -t, --trace=NAMN spåra NAMN när den blir definierad\n"
+" -l, --arglength=NUMMER begränsa makrospårningsstorleken\n"
+" -o, --error-output=FIL avled felsöknings och spårutskrifter till "
+"FIL\n"
+
+#: src/m4.c:184
+#, fuzzy
+msgid ""
+"\n"
+"FLAGS is any of:\n"
+" t trace for all macro calls, not only traceon'ed\n"
+" a show actual arguments\n"
+" e show expansion\n"
+" q quote values as necessary, with a or e flag\n"
+" c show before collect, after collect and after call\n"
+" x add a unique macro call id, useful with c flag\n"
+" f say current input file name\n"
+" l say current input line number\n"
+" p show results of path searches\n"
+" i show changes in input files\n"
+" V shorthand for all of the above flags\n"
+msgstr ""
+"\n"
+"FLAGGOR kan vara en eller flera av:\n"
+" t spåra alla makroanrop, inte bara de som spåras med \"traceon\"\n"
+" a visa aktuella argument\n"
+" e visa expansioner\n"
+" q sätt citationstecken där det behövs, gäller \"a\" och \"e\"\n"
+" c visa före insamling, efter insamling och efter anrop\n"
+" x lägg till en unik identifierare för makroanrop, användbart med \"c\"\n"
+" f visa namnet på aktuell infil\n"
+" l visa raden i aktuell infil\n"
+" p visa resultatet av sökvägssökningar\n"
+" i visa byten av infil\n"
+" V förkortning för alla ovanstående flaggor\n"
+
+#: src/m4.c:199
+#, fuzzy
+msgid ""
+"\n"
+"If no FILE or if FILE is `-', standard input is read.\n"
+msgstr ""
+"\n"
+"Om ingen FIL anges eller om FIL är `-', så läses standard in.\n"
+
+#: src/m4.c:358
+#, fuzzy, c-format
+msgid "Bad debug flags: `%s'"
+msgstr "Okänd felsökningsflagga \"%s\""
+
+#: src/m4.c:437
+#, fuzzy
+msgid "INTERNAL ERROR: Bad code in deferred arguments"
+msgstr "INTERNT FEL: Otillåten kod i argument"
+
+#: src/macro.c:92
+#, fuzzy
+msgid "INTERNAL ERROR: Bad token type in expand_token ()"
+msgstr "INTERNT FEL: Otillåten lexikalisk datatyp i expand_token ()"
+
+#: src/macro.c:158
+#, fuzzy
+msgid "ERROR: EOF in argument list"
+msgstr "FEL: Filslut i argumentlistan"
+
+#: src/macro.c:176
+#, fuzzy
+msgid "INTERNAL ERROR: Bad token type in expand_argument ()"
+msgstr "INTERNT FEL: Otillåten lexikalisk datatyp i expand_argument ()"
+
+#: src/macro.c:253
+#, fuzzy
+msgid "INTERNAL ERROR: Bad symbol type in call_macro ()"
+msgstr "INTERNT FEL: Otillåten symboltyp i call_macro ()"
+
+#: src/macro.c:282
+#, fuzzy, c-format
+msgid "ERROR: Recursion limit of %d exceeded, use -L<N> to change it"
+msgstr "FEL: Rekursionsgräns %d överskriden, använd -L<N> för att ändra"
+
+#: src/output.c:198
+#, fuzzy
+msgid "ERROR: Cannot create temporary file for diversion"
+msgstr "FEL: Kan inte skapa temporär fil för avledning"
+
+#: src/output.c:208
+#, fuzzy
+msgid "ERROR: Cannot flush diversion to temporary file"
+msgstr "FEL: Kan inte skriva avledningen till temporär fil"
+
+#: src/output.c:292
+#, fuzzy
+msgid "ERROR: Copying inserted file"
+msgstr "FEL: Kopiering av insatt fil"
+
+#: src/output.c:473
+#, fuzzy
+msgid "ERROR: Reading inserted file"
+msgstr "FEL: Läsning av insatt fil"
+
+#: src/output.c:572
+#, fuzzy
+msgid "Cannot stat diversion"
+msgstr "Kan inte ta status på avledningen"
+
+#: src/path.c:131
+#, fuzzy, c-format
+msgid "Path search for `%s' found `%s'"
+msgstr "\"%s\" hittades som \"%s\" i sökvägen"
+
+#. sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+#. if the stack limit has not been reached.
+#: src/stackovf.c:168
+#, fuzzy
+msgid "VMEM limit exceeded?\n"
+msgstr "VMEM begränsning överskriden?\n"
+
+#: src/stackovf.c:190
+#, fuzzy
+msgid ""
+"Memory bounds violation detected (SIGSEGV). Either a stack overflow\n"
+"occurred, or there is a bug in "
+msgstr ""
+"Otillåten referens utanför minnesgränserna har upptäckts (SIGSEGV).\n"
+"Antingen flödade stacken över eller så är det ett fel i "
+
+#: src/stackovf.c:195
+#, fuzzy
+msgid ". Check for possible infinite recursion.\n"
+msgstr ". Kontrollera om oändlig rekursion förekommer.\n"
+
+#: src/symtab.c:190
+#, fuzzy
+msgid "INTERNAL ERROR: Illegal mode to symbol_lookup ()"
+msgstr "INTERNT FEL: Otillåtet läge till symbol_lookup ()"
+
+#: src/symtab.c:243
+#, fuzzy, c-format
+msgid "Name `%s' is unknown\n"
+msgstr "Namnet \"%s\" är okänt\n"
+
+#, fuzzy
+#~ msgid "Bad regular expression: `%s': %s"
+#~ msgstr "Otillåtet reguljäruttryck \"%s\": %s"
+
+#, fuzzy
+#~ msgid "%s: option `%s' is ambiguous\n"
+#~ msgstr "%s: flaggan \"%s\" är tvetydig\n"
+
+#, fuzzy
+#~ msgid "%s: option `--%s' doesn't allow an argument\n"
+#~ msgstr "%s: flaggan \"--%s\" tar inget argument\n"
+
+#, fuzzy
+#~ msgid "%s: option `%c%s' doesn't allow an argument\n"
+#~ msgstr "%s: flaggan \"%c%s\" tar inget argument\n"
+
+#, fuzzy
+#~ msgid "%s: option `%s' requires an argument\n"
+#~ msgstr "%s: flaggan \"%s\" behöver ett argument\n"
+
+#, fuzzy
+#~ msgid "%s: unrecognized option `--%s'\n"
+#~ msgstr "%s: okänd flagga \"--%s\"\n"
+
+#, fuzzy
+#~ msgid "%s: unrecognized option `%c%s'\n"
+#~ msgstr "%s: okänd flagga \"%c%s\"\n"
+
+#, fuzzy
+#~ msgid "%s: illegal option -- %c\n"
+#~ msgstr "%s: otillåten flagga -- %c\n"
+
+#, fuzzy
+#~ msgid "%s: invalid option -- %c\n"
+#~ msgstr "%s: ogiltig flagga -- %c\n"
+
+#, fuzzy
+#~ msgid "%s: option requires an argument -- %c\n"
+#~ msgstr "%s: flaggan behöver ett argument -- %c\n"
+
+#, fuzzy
+#~ msgid "No previous regular expression"
+#~ msgstr "Inget föregående reguljäruttryck"
+
+#, fuzzy
+#~ msgid "Memory exhausted"
+#~ msgstr "Minnet slut"
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 00000000..00e8b063
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,15 @@
+AUTOMAKE_OPTIONS = ansi2knr
+CATALOGS = fr.msg
+LIBS = @LIBS@
+STACKOVF = @STACKOVF@
+
+bin_PROGRAMS = m4
+
+INCLUDES = -I$(top_srcdir) -I$(srcdir) -I$(top_srcdir)/lib
+
+m4_SOURCES = m4.c m4.h builtin.c debug.c eval.c format.c freeze.c input.c \
+ macro.c output.c path.c symtab.c stackovf.c
+
+m4_LDADD = ../lib/libm4.a @INTLLIBS@
+
+
diff --git a/src/Makefile.in b/src/Makefile.in
new file mode 100644
index 00000000..eb20b843
--- /dev/null
+++ b/src/Makefile.in
@@ -0,0 +1,122 @@
+# Makefile for GNU m4 sources.
+# Copyright (C) 1994 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 2, 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, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+PRODUCT = @PRODUCT@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+DEFS = @DEFS@
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+STACKOVF = @STACKOVF@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+transform = @program_transform_name@
+bindir = $(exec_prefix)/bin
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+LINK = $(CC) $(LDFLAGS) -o $@
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+.c.o:
+ $(COMPILE) $<
+
+ANSI2KNR = @ANSI2KNR@
+O = .@U@o
+
+.SUFFIXES: ._c ._o
+.c._c:
+ ./ansi2knr --varargs $< > $@
+._c._o:
+ @echo $(COMPILE) $<
+ @rm -f _$*.c
+ @ln $< _$*.c && $(COMPILE) _$*.c && mv _$*.o $@ && rm _$*.c
+.c._o:
+ ./ansi2knr --varargs $< > $*._c
+ @echo $(COMPILE) $*._c
+ @rm -f _$*.c
+ @ln $*._c _$*.c && $(COMPILE) _$*.c && mv _$*.o $@ && rm _$*.c
+
+INCLUDES = -I.. -I$(srcdir) -I$(srcdir)/../lib
+
+HEADERS = m4.h
+SOURCES = m4.c builtin.c debug.c eval.c format.c freeze.c input.c \
+macro.c output.c path.c stackovf.c symtab.c
+OBJECTS = m4$O builtin$O debug$O eval$O format$O freeze$O input$O \
+macro$O output$O path$O $(STACKOVF) symtab$O
+
+DISTFILES = Makefile.in ansi2knr.c ansi2knr.1 $(HEADERS) $(SOURCES) \
+TAGS
+
+all: m4
+
+m4: $(OBJECTS) ../lib/libm4.a
+ $(LINK) $(OBJECTS) ../lib/libm4.a $(LIBS)
+
+$(OBJECTS): $(ANSI2KNR) ../config.h m4.h ../lib/obstack.h
+builtin$O: ../lib/regex.h
+
+ansi2knr: ansi2knr.o
+ $(LINK) ansi2knr.o $(LIBS)
+
+install: all
+ $(srcdir)/../mkinstalldirs $(bindir)
+ $(INSTALL_PROGRAM) m4 $(bindir)/`echo m4 | sed '$(transform)'`
+
+uninstall:
+ rm -f $(bindir)/`echo m4 | sed '$(transform)'`
+
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES)
+ cd $(srcdir) && etags -i ../lib/TAGS $(HEADERS) $(SOURCES)
+
+mostlyclean:
+ rm -f *.o *._c *._o core core.*
+
+clean: mostlyclean
+ rm -f m4
+
+distclean: clean
+ rm -f Makefile ansi2knr
+
+realclean: distclean
+ rm -f TAGS
+
+dist: $(DISTFILES)
+ @echo "Copying distribution files"
+ @for file in $(DISTFILES); do \
+ ln $(srcdir)/$$file ../$(PRODUCT)-$(VERSION)/src 2> /dev/null \
+ || cp -p $(srcdir)/$$file ../$(PRODUCT)-$(VERSION)/src; \
+ done
+
+Makefile: Makefile.in ../config.status
+ cd .. && CONFIG_FILES=src/$@ CONFIG_HEADERS= ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/src/ansi2knr.1 b/src/ansi2knr.1
new file mode 100644
index 00000000..434ce8f0
--- /dev/null
+++ b/src/ansi2knr.1
@@ -0,0 +1,19 @@
+.TH ANSI2KNR 1 "31 December 1990"
+.SH NAME
+ansi2knr \- convert ANSI C to Kernighan & Ritchie C
+.SH SYNOPSIS
+.I ansi2knr
+input_file output_file
+.SH DESCRIPTION
+If no output_file is supplied, output goes to stdout.
+.br
+There are no error messages.
+.sp
+.I ansi2knr
+recognizes functions by seeing a non-keyword identifier at the left margin, followed by a left parenthesis, with a right parenthesis as the last character on the line. It will recognize a multi-line header if the last character on each line but the last is a left parenthesis or comma. These algorithms ignore whitespace and comments, except that the function name must be the first thing on the line.
+.sp
+The following constructs will confuse it:
+.br
+ - Any other construct that starts at the left margin and follows the above syntax (such as a macro or function call).
+.br
+ - Macros that tinker with the syntax of the function header.
diff --git a/src/ansi2knr.c b/src/ansi2knr.c
new file mode 100644
index 00000000..9bcc4adb
--- /dev/null
+++ b/src/ansi2knr.c
@@ -0,0 +1,439 @@
+/* Copyright (C) 1989, 1991, 1993, 1994 Aladdin Enterprises. All rights reserved. */
+
+/* ansi2knr.c */
+/* Convert ANSI function declarations to K&R syntax */
+
+/*
+ansi2knr is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
+to anyone for the consequences of using it or for whether it serves any
+particular purpose or works at all, unless he says so in writing. Refer
+to the GNU General Public License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+ansi2knr, but only under the conditions described in the GNU
+General Public License. A copy of this license is supposed to have been
+given to you along with ansi2knr so you can know your rights and
+responsibilities. It should be in a file named COPYLEFT. Among other
+things, the copyright notice and this notice must be preserved on all
+copies.
+*/
+
+/*
+ * Usage:
+ ansi2knr [--varargs] input_file [output_file]
+ * If no output_file is supplied, output goes to stdout.
+ * There are no error messages.
+ *
+ * ansi2knr recognizes function definitions by seeing a non-keyword
+ * identifier at the left margin, followed by a left parenthesis,
+ * with a right parenthesis as the last character on the line.
+ * It will recognize a multi-line header provided that the last character
+ * of the last line of the header is a right parenthesis,
+ * and no intervening line ends with a left brace or a semicolon.
+ * These algorithms ignore whitespace and comments, except that
+ * the function name must be the first thing on the line.
+ * The following constructs will confuse it:
+ * - Any other construct that starts at the left margin and
+ * follows the above syntax (such as a macro or function call).
+ * - Macros that tinker with the syntax of the function header.
+ *
+ * If the --varargs switch is supplied, ansi2knr will attempt to
+ * convert a ... argument to va_alist and va_dcl. If this switch is not
+ * supplied, ansi2knr will simply drop any such arguments.
+ */
+
+/*
+ * The original and principal author of ansi2knr is L. Peter Deutsch
+ * <ghost@aladdin.com>. Other authors are noted in the change history
+ * that follows (in reverse chronological order):
+ lpd 94-10-10 removed CONFIG_BROKETS conditional
+ lpd 94-07-16 added some conditionals to help GNU `configure',
+ suggested by Francois Pinard <pinard@iro.umontreal.ca>;
+ properly erase prototype args in function parameters,
+ contributed by Jim Avera <jima@netcom.com>;
+ correct error in writeblanks (it shouldn't erase EOLs)
+ lpd 89-xx-xx original version
+ */
+
+/* Most of the conditionals here are to make ansi2knr work with */
+/* the GNU configure machinery. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+
+#ifdef HAVE_CONFIG_H
+
+/*
+ For properly autoconfiguring ansi2knr, use AC_CONFIG_HEADER(config.h).
+ This will define HAVE_CONFIG_H and so, activate the following lines.
+ */
+
+# if STDC_HEADERS || HAVE_STRING_H
+# include <string.h>
+# else
+# include <strings.h>
+# endif
+
+#else /* not HAVE_CONFIG_H */
+
+/*
+ Without AC_CONFIG_HEADER, merely use <string.h> as in the original
+ Ghostscript distribution. This loses on older BSD systems.
+ */
+
+# include <string.h>
+
+#endif /* not HAVE_CONFIG_H */
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#else
+/*
+ malloc and free should be declared in stdlib.h,
+ but if you've got a K&R compiler, they probably aren't.
+ */
+char *malloc();
+void free();
+#endif
+
+/* Scanning macros */
+#define isidchar(ch) (isalnum(ch) || (ch) == '_')
+#define isidfirstchar(ch) (isalpha(ch) || (ch) == '_')
+
+/* Forward references */
+char *skipspace();
+void writeblanks();
+int test1();
+int convert1();
+
+/* The main program */
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{ FILE *in, *out;
+#define bufsize 5000 /* arbitrary size */
+ char *buf;
+ char *line;
+ int convert_varargs = 0;
+ if ( argc > 1 && argv[1][0] == '-' )
+ { if ( !strcmp(argv[1], "--varargs") )
+ { convert_varargs = 1;
+ argc--;
+ argv++;
+ }
+ else
+ { fprintf(stderr, "Unrecognized switch: %s\n", argv[1]);
+ exit(1);
+ }
+ }
+ switch ( argc )
+ {
+ default:
+ printf("Usage: ansi2knr [--varargs] input_file [output_file]\n");
+ exit(0);
+ case 2:
+ out = stdout;
+ break;
+ case 3:
+ out = fopen(argv[2], "w");
+ if ( out == NULL )
+ { fprintf(stderr, "Cannot open output file %s\n", argv[2]);
+ exit(1);
+ }
+ }
+ in = fopen(argv[1], "r");
+ if ( in == NULL )
+ { fprintf(stderr, "Cannot open input file %s\n", argv[1]);
+ exit(1);
+ }
+ fprintf(out, "#line 1 \"%s\"\n", argv[1]);
+ buf = malloc(bufsize);
+ line = buf;
+ while ( fgets(line, (unsigned)(buf + bufsize - line), in) != NULL )
+ { switch ( test1(buf) )
+ {
+ case 2: /* a function header */
+ convert1(buf, out, 1, convert_varargs);
+ break;
+ case 1: /* a function */
+ convert1(buf, out, 0, convert_varargs);
+ break;
+ case -1: /* maybe the start of a function */
+ line = buf + strlen(buf);
+ if ( line != buf + (bufsize - 1) ) /* overflow check */
+ continue;
+ /* falls through */
+ default: /* not a function */
+ fputs(buf, out);
+ break;
+ }
+ line = buf;
+ }
+ if ( line != buf ) fputs(buf, out);
+ free(buf);
+ fclose(out);
+ fclose(in);
+ return 0;
+}
+
+/* Skip over space and comments, in either direction. */
+char *
+skipspace(p, dir)
+ register char *p;
+ register int dir; /* 1 for forward, -1 for backward */
+{ for ( ; ; )
+ { while ( isspace(*p) ) p += dir;
+ if ( !(*p == '/' && p[dir] == '*') ) break;
+ p += dir; p += dir;
+ while ( !(*p == '*' && p[dir] == '/') )
+ { if ( *p == 0 ) return p; /* multi-line comment?? */
+ p += dir;
+ }
+ p += dir; p += dir;
+ }
+ return p;
+}
+
+/*
+ * Write blanks over part of a string.
+ * Don't overwrite end-of-line characters.
+ */
+void
+writeblanks(start, end)
+ char *start;
+ char *end;
+{ char *p;
+ for ( p = start; p < end; p++ )
+ if ( *p != '\r' && *p != '\n' ) *p = ' ';
+}
+
+/*
+ * Test whether the string in buf is a function definition.
+ * The string may contain and/or end with a newline.
+ * Return as follows:
+ * 0 - definitely not a function definition;
+ * 1 - definitely a function definition;
+ * 2 - definitely a function prototype (NOT USED);
+ * -1 - may be the beginning of a function definition,
+ * append another line and look again.
+ * The reason we don't attempt to convert function prototypes is that
+ * Ghostscript's declaration-generating macros look too much like
+ * prototypes, and confuse the algorithms.
+ */
+int
+test1(buf)
+ char *buf;
+{ register char *p = buf;
+ char *bend;
+ char *endfn;
+ int contin;
+ if ( !isidfirstchar(*p) )
+ return 0; /* no name at left margin */
+ bend = skipspace(buf + strlen(buf) - 1, -1);
+ switch ( *bend )
+ {
+ case ';': contin = 0 /*2*/; break;
+ case ')': contin = 1; break;
+ case '{': return 0; /* not a function */
+ default: contin = -1;
+ }
+ while ( isidchar(*p) ) p++;
+ endfn = p;
+ p = skipspace(p, 1);
+ if ( *p++ != '(' )
+ return 0; /* not a function */
+ p = skipspace(p, 1);
+ if ( *p == ')' )
+ return 0; /* no parameters */
+ /* Check that the apparent function name isn't a keyword. */
+ /* We only need to check for keywords that could be followed */
+ /* by a left parenthesis (which, unfortunately, is most of them). */
+ { static char *words[] =
+ { "asm", "auto", "case", "char", "const", "double",
+ "extern", "float", "for", "if", "int", "long",
+ "register", "return", "short", "signed", "sizeof",
+ "static", "switch", "typedef", "unsigned",
+ "void", "volatile", "while", 0
+ };
+ char **key = words;
+ char *kp;
+ int len = endfn - buf;
+ while ( (kp = *key) != 0 )
+ { if ( strlen(kp) == len && !strncmp(kp, buf, len) )
+ return 0; /* name is a keyword */
+ key++;
+ }
+ }
+ return contin;
+}
+
+/* Convert a recognized function definition or header to K&R syntax. */
+int
+convert1(buf, out, header, convert_varargs)
+ char *buf;
+ FILE *out;
+ int header; /* Boolean */
+ int convert_varargs; /* Boolean */
+{ char *endfn;
+ register char *p;
+ char **breaks;
+ unsigned num_breaks = 2; /* for testing */
+ char **btop;
+ char **bp;
+ char **ap;
+ char *vararg = 0;
+ /* Pre-ANSI implementations don't agree on whether strchr */
+ /* is called strchr or index, so we open-code it here. */
+ for ( endfn = buf; *(endfn++) != '('; ) ;
+top: p = endfn;
+ breaks = (char **)malloc(sizeof(char *) * num_breaks * 2);
+ if ( breaks == 0 )
+ { /* Couldn't allocate break table, give up */
+ fprintf(stderr, "Unable to allocate break table!\n");
+ fputs(buf, out);
+ return -1;
+ }
+ btop = breaks + num_breaks * 2 - 2;
+ bp = breaks;
+ /* Parse the argument list */
+ do
+ { int level = 0;
+ char *lp = NULL;
+ char *rp;
+ char *end = NULL;
+ if ( bp >= btop )
+ { /* Filled up break table. */
+ /* Allocate a bigger one and start over. */
+ free((char *)breaks);
+ num_breaks <<= 1;
+ goto top;
+ }
+ *bp++ = p;
+ /* Find the end of the argument */
+ for ( ; end == NULL; p++ )
+ { switch(*p)
+ {
+ case ',':
+ if ( !level ) end = p;
+ break;
+ case '(':
+ if ( !level ) lp = p;
+ level++;
+ break;
+ case ')':
+ if ( --level < 0 ) end = p;
+ else rp = p;
+ break;
+ case '/':
+ p = skipspace(p, 1) - 1;
+ break;
+ default:
+ ;
+ }
+ }
+ /* Erase any embedded prototype parameters. */
+ if ( lp )
+ writeblanks(lp + 1, rp);
+ p--; /* back up over terminator */
+ /* Find the name being declared. */
+ /* This is complicated because of procedure and */
+ /* array modifiers. */
+ for ( ; ; )
+ { p = skipspace(p - 1, -1);
+ switch ( *p )
+ {
+ case ']': /* skip array dimension(s) */
+ case ')': /* skip procedure args OR name */
+ { int level = 1;
+ while ( level )
+ switch ( *--p )
+ {
+ case ']': case ')': level++; break;
+ case '[': case '(': level--; break;
+ case '/': p = skipspace(p, -1) + 1; break;
+ default: ;
+ }
+ }
+ if ( *p == '(' && *skipspace(p + 1, 1) == '*' )
+ { /* We found the name being declared */
+ while ( !isidfirstchar(*p) )
+ p = skipspace(p, 1) + 1;
+ goto found;
+ }
+ break;
+ default: goto found;
+ }
+ }
+found: if ( *p == '.' && p[-1] == '.' && p[-2] == '.' )
+ { if ( convert_varargs )
+ { *bp++ = "va_alist";
+ vararg = p-2;
+ }
+ else
+ { p++;
+ if ( bp == breaks + 1 ) /* sole argument */
+ writeblanks(breaks[0], p);
+ else
+ writeblanks(bp[-1] - 1, p);
+ bp--;
+ }
+ }
+ else
+ { while ( isidchar(*p) ) p--;
+ *bp++ = p+1;
+ }
+ p = end;
+ }
+ while ( *p++ == ',' );
+ *bp = p;
+ /* Make a special check for 'void' arglist */
+ if ( bp == breaks+2 )
+ { p = skipspace(breaks[0], 1);
+ if ( !strncmp(p, "void", 4) )
+ { p = skipspace(p+4, 1);
+ if ( p == breaks[2] - 1 )
+ { bp = breaks; /* yup, pretend arglist is empty */
+ writeblanks(breaks[0], p + 1);
+ }
+ }
+ }
+ /* Put out the function name and left parenthesis. */
+ p = buf;
+ while ( p != endfn ) putc(*p, out), p++;
+ /* Put out the declaration. */
+ if ( header )
+ { fputs(");", out);
+ for ( p = breaks[0]; *p; p++ )
+ if ( *p == '\r' || *p == '\n' )
+ putc(*p, out);
+ }
+ else
+ { for ( ap = breaks+1; ap < bp; ap += 2 )
+ { p = *ap;
+ while ( isidchar(*p) )
+ putc(*p, out), p++;
+ if ( ap < bp - 1 )
+ fputs(", ", out);
+ }
+ fputs(") ", out);
+ /* Put out the argument declarations */
+ for ( ap = breaks+2; ap <= bp; ap += 2 )
+ (*ap)[-1] = ';';
+ if ( vararg != 0 )
+ { *vararg = 0;
+ fputs(breaks[0], out); /* any prior args */
+ fputs("va_dcl", out); /* the final arg */
+ fputs(bp[0], out);
+ }
+ else
+ fputs(breaks[0], out);
+ }
+ free((char *)breaks);
+ return 0;
+}
diff --git a/src/builtin.c b/src/builtin.c
new file mode 100644
index 00000000..47506018
--- /dev/null
+++ b/src/builtin.c
@@ -0,0 +1,1732 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Code for all builtin macros, initialisation of symbol table, and
+ expansion of user defined macros. */
+
+#include "m4.h"
+
+extern FILE *popen ();
+
+#include "regex.h"
+
+#define ARG(i) (argc > (i) ? TOKEN_DATA_TEXT (argv[i]) : "")
+
+/* Initialisation of builtin and predefined macros. The table
+ "builtin_tab" is both used for initialisation, and by the "builtin"
+ builtin. */
+
+#define DECLARE(name) \
+ static void name _((struct obstack *, int, token_data **))
+
+DECLARE (m4___file__);
+DECLARE (m4___line__);
+DECLARE (m4_builtin);
+DECLARE (m4_changecom);
+DECLARE (m4_changequote);
+#ifdef ENABLE_CHANGEWORD
+DECLARE (m4_changeword);
+#endif
+DECLARE (m4_debugmode);
+DECLARE (m4_debugfile);
+DECLARE (m4_decr);
+DECLARE (m4_define);
+DECLARE (m4_defn);
+DECLARE (m4_divert);
+DECLARE (m4_divnum);
+DECLARE (m4_dnl);
+DECLARE (m4_dumpdef);
+DECLARE (m4_errprint);
+DECLARE (m4_esyscmd);
+DECLARE (m4_eval);
+DECLARE (m4_format);
+DECLARE (m4_ifdef);
+DECLARE (m4_ifelse);
+DECLARE (m4_include);
+DECLARE (m4_incr);
+DECLARE (m4_index);
+DECLARE (m4_indir);
+DECLARE (m4_len);
+DECLARE (m4_m4exit);
+DECLARE (m4_m4wrap);
+DECLARE (m4_maketemp);
+DECLARE (m4_patsubst);
+DECLARE (m4_popdef);
+DECLARE (m4_pushdef);
+DECLARE (m4_regexp);
+DECLARE (m4_shift);
+DECLARE (m4_sinclude);
+DECLARE (m4_substr);
+DECLARE (m4_syscmd);
+DECLARE (m4_sysval);
+DECLARE (m4_traceoff);
+DECLARE (m4_traceon);
+DECLARE (m4_translit);
+DECLARE (m4_undefine);
+DECLARE (m4_undivert);
+
+#undef DECLARE
+
+static builtin
+builtin_tab[] =
+{
+
+ /* name GNUext macros blind function */
+
+ { "__file__", TRUE, FALSE, FALSE, m4___file__ },
+ { "__line__", TRUE, FALSE, FALSE, m4___line__ },
+ { "builtin", TRUE, FALSE, TRUE, m4_builtin },
+ { "changecom", FALSE, FALSE, FALSE, m4_changecom },
+ { "changequote", FALSE, FALSE, FALSE, m4_changequote },
+#ifdef ENABLE_CHANGEWORD
+ { "changeword", TRUE, FALSE, FALSE, m4_changeword },
+#endif
+ { "debugmode", TRUE, FALSE, FALSE, m4_debugmode },
+ { "debugfile", TRUE, FALSE, FALSE, m4_debugfile },
+ { "decr", FALSE, FALSE, TRUE, m4_decr },
+ { "define", FALSE, TRUE, TRUE, m4_define },
+ { "defn", FALSE, FALSE, TRUE, m4_defn },
+ { "divert", FALSE, FALSE, FALSE, m4_divert },
+ { "divnum", FALSE, FALSE, FALSE, m4_divnum },
+ { "dnl", FALSE, FALSE, FALSE, m4_dnl },
+ { "dumpdef", FALSE, FALSE, FALSE, m4_dumpdef },
+ { "errprint", FALSE, FALSE, FALSE, m4_errprint },
+ { "esyscmd", TRUE, FALSE, TRUE, m4_esyscmd },
+ { "eval", FALSE, FALSE, TRUE, m4_eval },
+ { "format", TRUE, FALSE, FALSE, m4_format },
+ { "ifdef", FALSE, FALSE, TRUE, m4_ifdef },
+ { "ifelse", FALSE, FALSE, TRUE, m4_ifelse },
+ { "include", FALSE, FALSE, TRUE, m4_include },
+ { "incr", FALSE, FALSE, TRUE, m4_incr },
+ { "index", FALSE, FALSE, TRUE, m4_index },
+ { "indir", TRUE, FALSE, FALSE, m4_indir },
+ { "len", FALSE, FALSE, TRUE, m4_len },
+ { "m4exit", FALSE, FALSE, FALSE, m4_m4exit },
+ { "m4wrap", FALSE, FALSE, FALSE, m4_m4wrap },
+ { "maketemp", FALSE, FALSE, TRUE, m4_maketemp },
+ { "patsubst", TRUE, FALSE, TRUE, m4_patsubst },
+ { "popdef", FALSE, FALSE, TRUE, m4_popdef },
+ { "pushdef", FALSE, TRUE, TRUE, m4_pushdef },
+ { "regexp", TRUE, FALSE, TRUE, m4_regexp },
+ { "shift", FALSE, FALSE, FALSE, m4_shift },
+ { "sinclude", FALSE, FALSE, TRUE, m4_sinclude },
+ { "substr", FALSE, FALSE, TRUE, m4_substr },
+ { "syscmd", FALSE, FALSE, TRUE, m4_syscmd },
+ { "sysval", FALSE, FALSE, FALSE, m4_sysval },
+ { "traceoff", FALSE, FALSE, FALSE, m4_traceoff },
+ { "traceon", FALSE, FALSE, FALSE, m4_traceon },
+ { "translit", FALSE, FALSE, TRUE, m4_translit },
+ { "undefine", FALSE, FALSE, TRUE, m4_undefine },
+ { "undivert", FALSE, FALSE, FALSE, m4_undivert },
+
+ { 0, FALSE, FALSE, FALSE, 0 },
+};
+
+static predefined const
+predefined_tab[] =
+{
+ { "unix", "__unix__", "" },
+ { NULL, "__gnu__", "" },
+
+ { NULL, NULL, NULL },
+};
+
+/*----------------------------------------.
+| Find the builtin, which lives on ADDR. |
+`----------------------------------------*/
+
+const builtin *
+find_builtin_by_addr (builtin_func *func)
+{
+ const builtin *bp;
+
+ for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
+ if (bp->func == func)
+ return bp;
+ return NULL;
+}
+
+/*-----------------------------------.
+| Find the builtin, which has NAME. |
+`-----------------------------------*/
+
+const builtin *
+find_builtin_by_name (const char *name)
+{
+ const builtin *bp;
+
+ for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
+ if (strcmp (bp->name, name) == 0)
+ return bp;
+ return NULL;
+}
+
+/*-------------------------------------------------------------------------.
+| Install a builtin macro with name NAME, bound to the C function given in |
+| BP. MODE is SYMBOL_INSERT or SYMBOL_PUSHDEF. TRACED defines whether |
+| NAME is to be traced. |
+`-------------------------------------------------------------------------*/
+
+void
+define_builtin (const char *name, const builtin *bp, symbol_lookup mode,
+ boolean traced)
+{
+ symbol *sym;
+
+ sym = lookup_symbol (name, mode);
+ SYMBOL_TYPE (sym) = TOKEN_FUNC;
+ SYMBOL_MACRO_ARGS (sym) = bp->groks_macro_args;
+ SYMBOL_BLIND_NO_ARGS (sym) = bp->blind_if_no_args;
+ SYMBOL_FUNC (sym) = bp->func;
+ SYMBOL_TRACED (sym) = traced;
+}
+
+/*-------------------------------------------------------------------------.
+| Define a predefined or user-defined macro, with name NAME, and expansion |
+| TEXT. MODE destinguishes between the "define" and the "pushdef" case. |
+| It is also used from main (). |
+`-------------------------------------------------------------------------*/
+
+void
+define_user_macro (const char *name, const char *text, symbol_lookup mode)
+{
+ symbol *s;
+
+ s = lookup_symbol (name, mode);
+ if (SYMBOL_TYPE (s) == TOKEN_TEXT)
+ xfree (SYMBOL_TEXT (s));
+
+ SYMBOL_TYPE (s) = TOKEN_TEXT;
+ SYMBOL_TEXT (s) = xstrdup (text);
+}
+
+/*-----------------------------------------------.
+| Initialise all builtin and predefined macros. |
+`-----------------------------------------------*/
+
+void
+builtin_init (void)
+{
+ const builtin *bp;
+ const predefined *pp;
+ char *string;
+
+ for (bp = &builtin_tab[0]; bp->name != NULL; bp++)
+ if (!no_gnu_extensions || !bp->gnu_extension)
+ if (prefix_all_builtins)
+ {
+ string = (char *) xmalloc (strlen (bp->name) + 4);
+ strcpy (string, "m4_");
+ strcat (string, bp->name);
+ define_builtin (string, bp, SYMBOL_INSERT, FALSE);
+ free (string);
+ }
+ else
+ define_builtin (bp->name, bp, SYMBOL_INSERT, FALSE);
+
+ for (pp = &predefined_tab[0]; pp->func != NULL; pp++)
+ if (no_gnu_extensions)
+ {
+ if (pp->unix_name != NULL)
+ define_user_macro (pp->unix_name, pp->func, SYMBOL_INSERT);
+ }
+ else
+ {
+ if (pp->gnu_name != NULL)
+ define_user_macro (pp->gnu_name, pp->func, SYMBOL_INSERT);
+ }
+}
+
+/*------------------------------------------------------------------------.
+| Give friendly warnings if a builtin macro is passed an inappropriate |
+| number of arguments. NAME is macro name for messages, ARGC is actual |
+| number of arguments, MIN is the minimum number of acceptable arguments, |
+| negative if not applicable, MAX is the maximum number, negative if not |
+| applicable. |
+`------------------------------------------------------------------------*/
+
+static boolean
+bad_argc (token_data *name, int argc, int min, int max)
+{
+ boolean isbad = FALSE;
+
+ if (min > 0 && argc < min)
+ {
+ if (!suppress_warnings)
+ M4ERROR ((warning_status, 0,
+ "Warning: Too few arguments to built-in `%s'",
+ TOKEN_DATA_TEXT (name)));
+ isbad = TRUE;
+ }
+ else if (max > 0 && argc > max && !suppress_warnings)
+ M4ERROR ((warning_status, 0,
+ "Warning: Excess arguments to built-in `%s' ignored",
+ TOKEN_DATA_TEXT (name)));
+
+ return isbad;
+}
+
+/*--------------------------------------------------------------------------.
+| The function numeric_arg () converts ARG to an int pointed to by VALUEP. |
+| If the conversion fails, print error message for macro MACRO. Return |
+| TRUE iff conversion succeeds. |
+`--------------------------------------------------------------------------*/
+
+static boolean
+numeric_arg (token_data *macro, const char *arg, int *valuep)
+{
+ char *endp;
+
+ if (*arg == 0 || (*valuep = strtol (arg, &endp, 10), *endp != 0))
+ {
+ M4ERROR ((warning_status, 0,
+ "Non-numeric argument to built-in `%s'",
+ TOKEN_DATA_TEXT (macro)));
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*------------------------------------------------------------------------.
+| The function ntoa () converts VALUE to a signed ascii representation in |
+| radix RADIX. |
+`------------------------------------------------------------------------*/
+
+/* Digits for number to ascii conversions. */
+static char const digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+static const char *
+ntoa (register eval_t value, int radix)
+{
+ boolean negative;
+ unsigned_eval_t uvalue;
+ static char str[256];
+ register char *s = &str[sizeof str];
+
+ *--s = '\0';
+
+ if (value < 0)
+ {
+ negative = TRUE;
+ uvalue = (unsigned_eval_t) -value;
+ }
+ else
+ {
+ negative = FALSE;
+ uvalue = (unsigned_eval_t) value;
+ }
+
+ do
+ {
+ *--s = digits[uvalue % radix];
+ uvalue /= radix;
+ }
+ while (uvalue > 0);
+
+ if (negative)
+ *--s = '-';
+ return s;
+}
+
+/*----------------------------------------------------------------------.
+| Format an int VAL, and stuff it into an obstack OBS. Used for macros |
+| expanding to numbers. |
+`----------------------------------------------------------------------*/
+
+static void
+shipout_int (struct obstack *obs, int val)
+{
+ const char *s;
+
+ s = ntoa ((eval_t) val, 10);
+ obstack_grow (obs, s, strlen (s));
+}
+
+/*----------------------------------------------------------------------.
+| Print ARGC arguments from the table ARGV to obstack OBS, separated by |
+| SEP, and quoted by the current quotes, if QUOTED is TRUE. |
+`----------------------------------------------------------------------*/
+
+static void
+dump_args (struct obstack *obs, int argc, token_data **argv,
+ const char *sep, boolean quoted)
+{
+ int i;
+ size_t len = strlen (sep);
+
+ for (i = 1; i < argc; i++)
+ {
+ if (i > 1)
+ obstack_grow (obs, sep, len);
+ if (quoted)
+ obstack_grow (obs, lquote.string, lquote.length);
+ obstack_grow (obs, TOKEN_DATA_TEXT (argv[i]),
+ strlen (TOKEN_DATA_TEXT (argv[i])));
+ if (quoted)
+ obstack_grow (obs, rquote.string, rquote.length);
+ }
+}
+
+/* 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 m4_MACRONAME (struct 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. */
+
+/* The first section are macros for definining, undefining, examining,
+ changing, ... other macros. */
+
+/*-------------------------------------------------------------------------.
+| The function define_macro is common for the builtins "define", |
+| "undefine", "pushdef" and "popdef". ARGC and ARGV is as for the caller, |
+| and MODE argument determines how the macro name is entered into the |
+| symbol table. |
+`-------------------------------------------------------------------------*/
+
+static void
+define_macro (int argc, token_data **argv, symbol_lookup mode)
+{
+ const builtin *bp;
+
+ if (bad_argc (argv[0], argc, 2, 3))
+ return;
+
+ if (TOKEN_DATA_TYPE (argv[1]) != TOKEN_TEXT)
+ return;
+
+ if (argc == 2)
+ {
+ define_user_macro (ARG (1), "", mode);
+ return;
+ }
+
+ switch (TOKEN_DATA_TYPE (argv[2]))
+ {
+ case TOKEN_TEXT:
+ define_user_macro (ARG (1), ARG (2), mode);
+ break;
+
+ case TOKEN_FUNC:
+ bp = find_builtin_by_addr (TOKEN_DATA_FUNC (argv[2]));
+ if (bp == NULL)
+ return;
+ else
+ define_builtin (ARG (1), bp, mode, TOKEN_DATA_FUNC_TRACED (argv[2]));
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad token data type in define_macro ()"));
+ abort ();
+ }
+ return;
+}
+
+static void
+m4_define (struct obstack *obs, int argc, token_data **argv)
+{
+ define_macro (argc, argv, SYMBOL_INSERT);
+}
+
+static void
+m4_undefine (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+ lookup_symbol (ARG (1), SYMBOL_DELETE);
+}
+
+static void
+m4_pushdef (struct obstack *obs, int argc, token_data **argv)
+{
+ define_macro (argc, argv, SYMBOL_PUSHDEF);
+}
+
+static void
+m4_popdef (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+ lookup_symbol (ARG (1), SYMBOL_POPDEF);
+}
+
+/*---------------------.
+| Conditionals of m4. |
+`---------------------*/
+
+static void
+m4_ifdef (struct obstack *obs, int argc, token_data **argv)
+{
+ symbol *s;
+ const char *result;
+
+ if (bad_argc (argv[0], argc, 3, 4))
+ return;
+ s = lookup_symbol (ARG (1), SYMBOL_LOOKUP);
+
+ if (s != NULL)
+ result = ARG (2);
+ else if (argc == 4)
+ result = ARG (3);
+ else
+ result = NULL;
+
+ if (result != NULL)
+ obstack_grow (obs, result, strlen (result));
+}
+
+static void
+m4_ifelse (struct obstack *obs, int argc, token_data **argv)
+{
+ const char *result;
+ token_data *argv0;
+
+ if (argc == 2)
+ return;
+
+ if (bad_argc (argv[0], argc, 4, -1))
+ return;
+ else
+ /* Diagnose excess arguments if 5, 8, 11, etc., actual arguments. */
+ bad_argc (argv[0], (argc + 2) % 3, -1, 1);
+
+ argv0 = argv[0];
+ argv++;
+ argc--;
+
+ result = NULL;
+ while (result == NULL)
+
+ if (strcmp (ARG (0), ARG (1)) == 0)
+ result = ARG (2);
+
+ else
+ switch (argc)
+ {
+ case 3:
+ return;
+
+ case 4:
+ case 5:
+ result = ARG (3);
+ break;
+
+ default:
+ argc -= 3;
+ argv += 3;
+ }
+
+ obstack_grow (obs, result, strlen (result));
+}
+
+/*---------------------------------------------------------------------.
+| The function dump_symbol () is for use by "dumpdef". It builds up a |
+| table of all defined, un-shadowed, symbols. |
+`---------------------------------------------------------------------*/
+
+/* The structure dump_symbol_data is used to pass the information needed
+ from call to call to dump_symbol. */
+
+struct dump_symbol_data
+{
+ struct obstack *obs; /* obstack for table */
+ symbol **base; /* base of table */
+ int size; /* size of table */
+};
+
+static void
+dump_symbol (symbol *sym, struct dump_symbol_data *data)
+{
+ if (!SYMBOL_SHADOWED (sym) && SYMBOL_TYPE (sym) != TOKEN_VOID)
+ {
+ obstack_blank (data->obs, sizeof (symbol *));
+ data->base = (symbol **) obstack_base (data->obs);
+ data->base[data->size++] = sym;
+ }
+}
+
+/*------------------------------------------------------------------------.
+| qsort comparison routine, for sorting the table made in m4_dumpdef (). |
+`------------------------------------------------------------------------*/
+
+static int
+dumpdef_cmp (const voidstar s1, const voidstar s2)
+{
+ return strcmp (SYMBOL_NAME (* (symbol *const *) s1),
+ SYMBOL_NAME (* (symbol *const *) s2));
+}
+
+/*-------------------------------------------------------------------------.
+| Implementation of "dumpdef" itself. It builds up a table of pointers to |
+| symbols, sorts it and prints the sorted table. |
+`-------------------------------------------------------------------------*/
+
+static void
+m4_dumpdef (struct obstack *obs, int argc, token_data **argv)
+{
+ symbol *s;
+ int i;
+ struct dump_symbol_data data;
+ const builtin *bp;
+
+ data.obs = obs;
+ data.base = (symbol **) obstack_base (obs);
+ data.size = 0;
+
+ if (argc == 1)
+ {
+ hack_all_symbols (dump_symbol, (char *) &data);
+ }
+ else
+ {
+ for (i = 1; i < argc; i++)
+ {
+ s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
+ if (s != NULL && SYMBOL_TYPE (s) != TOKEN_VOID)
+ dump_symbol (s, &data);
+ else
+ M4ERROR ((warning_status, 0,
+ "Undefined name %s", TOKEN_DATA_TEXT (argv[i])));
+ }
+ }
+
+ /* Make table of symbols invisible to expand_macro (). */
+
+ (void) obstack_finish (obs);
+
+ qsort ((char *) data.base, data.size, sizeof (symbol *), dumpdef_cmp);
+
+ for (; data.size > 0; --data.size, data.base++)
+ {
+ DEBUG_PRINT1 ("%s:\t", SYMBOL_NAME (data.base[0]));
+
+ switch (SYMBOL_TYPE (data.base[0]))
+ {
+ case TOKEN_TEXT:
+ if (debug_level & DEBUG_TRACE_QUOTE)
+ DEBUG_PRINT3 ("%s%s%s\n",
+ lquote.string, SYMBOL_TEXT (data.base[0]), rquote.string);
+ else
+ DEBUG_PRINT1 ("%s\n", SYMBOL_TEXT (data.base[0]));
+ break;
+
+ case TOKEN_FUNC:
+ bp = find_builtin_by_addr (SYMBOL_FUNC (data.base[0]));
+ if (bp == NULL)
+ {
+ M4ERROR ((warning_status, 0, "\
+INTERNAL ERROR: Builtin not found in builtin table!"));
+ abort ();
+ }
+ DEBUG_PRINT1 ("<%s>\n", bp->name);
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad token data type in m4_dumpdef ()"));
+ abort ();
+ break;
+ }
+ }
+}
+
+/*---------------------------------------------------------------------.
+| 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. This |
+| macro is not available in compatibility mode. |
+`---------------------------------------------------------------------*/
+
+static void
+m4_builtin (struct obstack *obs, int argc, token_data **argv)
+{
+ const builtin *bp;
+ const char *name = ARG (1);
+
+ if (bad_argc (argv[0], argc, 2, -1))
+ return;
+
+ bp = find_builtin_by_name (name);
+ if (bp == NULL)
+ M4ERROR ((warning_status, 0,
+ "Undefined name %s", name));
+ else
+ (*bp->func) (obs, argc - 1, argv + 1);
+}
+
+/*------------------------------------------------------------------------.
+| 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. This macro |
+| is not available in compatibility mode. |
+`------------------------------------------------------------------------*/
+
+static void
+m4_indir (struct obstack *obs, int argc, token_data **argv)
+{
+ symbol *s;
+ const char *name = ARG (1);
+
+ if (bad_argc (argv[0], argc, 1, -1))
+ return;
+
+ s = lookup_symbol (name, SYMBOL_LOOKUP);
+ if (s == NULL)
+ M4ERROR ((warning_status, 0,
+ "Undefined macro `%s'", name));
+ else
+ call_macro (s, argc - 1, argv + 1, obs);
+}
+
+/*-------------------------------------------------------------------------.
+| 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 ht input stack. |
+`-------------------------------------------------------------------------*/
+
+static void
+m4_defn (struct obstack *obs, int argc, token_data **argv)
+{
+ symbol *s;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ s = lookup_symbol (ARG (1), SYMBOL_LOOKUP);
+ if (s == NULL)
+ return;
+
+ switch (SYMBOL_TYPE (s))
+ {
+ case TOKEN_TEXT:
+ obstack_grow (obs, lquote.string, lquote.length);
+ obstack_grow (obs, SYMBOL_TEXT (s), strlen (SYMBOL_TEXT (s)));
+ obstack_grow (obs, rquote.string, rquote.length);
+ break;
+
+ case TOKEN_FUNC:
+ push_macro (SYMBOL_FUNC (s), SYMBOL_TRACED (s));
+ break;
+
+ case TOKEN_VOID:
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad symbol type in m4_defn ()"));
+ abort ();
+ }
+}
+
+/*------------------------------------------------------------------------.
+| This section contains macros to handle the builtins "syscmd", "esyscmd" |
+| and "sysval". "esyscmd" is GNU specific. |
+`------------------------------------------------------------------------*/
+
+/* Exit code from last "syscmd" command. */
+static int sysval;
+
+static void
+m4_syscmd (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ debug_flush_files ();
+ sysval = system (ARG (1));
+}
+
+static void
+m4_esyscmd (struct obstack *obs, int argc, token_data **argv)
+{
+ FILE *pin;
+ int ch;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ debug_flush_files ();
+ pin = popen (ARG (1), "r");
+ if (pin == NULL)
+ {
+ M4ERROR ((warning_status, errno,
+ "Cannot open pipe to command \"%s\"", ARG (1)));
+ sysval = 0xff << 8;
+ }
+ else
+ {
+ while ((ch = getc (pin)) != EOF)
+ obstack_1grow (obs, (char) ch);
+ sysval = pclose (pin);
+ }
+}
+
+static void
+m4_sysval (struct obstack *obs, int argc, token_data **argv)
+{
+ shipout_int (obs, (sysval >> 8) & 0xff);
+}
+
+/*-------------------------------------------------------------------------.
+| This section contains the top level code for the "eval" builtin. The |
+| actual work is done in the function evaluate (), which lives in eval.c. |
+`-------------------------------------------------------------------------*/
+
+static void
+m4_eval (struct obstack *obs, int argc, token_data **argv)
+{
+ eval_t value;
+ int radix = 10;
+ int min = 1;
+ const char *s;
+
+ if (bad_argc (argv[0], argc, 2, 4))
+ return;
+
+ if (argc >= 3 && !numeric_arg (argv[0], ARG (2), &radix))
+ return;
+
+ if (radix <= 1 || radix > (int) strlen (digits))
+ {
+ M4ERROR ((warning_status, 0,
+ "Radix in eval out of range (radix = %d)", radix));
+ return;
+ }
+
+ if (argc >= 4 && !numeric_arg (argv[0], ARG (3), &min))
+ return;
+ if (min <= 0)
+ {
+ M4ERROR ((warning_status, 0,
+ "Negative width to eval"));
+ return;
+ }
+
+ if (evaluate (ARG (1), &value))
+ return;
+
+ s = ntoa (value, radix);
+
+ if (*s == '-')
+ {
+ obstack_1grow (obs, '-');
+ min--;
+ s++;
+ }
+ for (min -= strlen (s); --min >= 0;)
+ obstack_1grow (obs, '0');
+
+ obstack_grow (obs, s, strlen (s));
+}
+
+static void
+m4_incr (struct obstack *obs, int argc, token_data **argv)
+{
+ int value;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ if (!numeric_arg (argv[0], ARG (1), &value))
+ return;
+
+ shipout_int (obs, value + 1);
+}
+
+static void
+m4_decr (struct obstack *obs, int argc, token_data **argv)
+{
+ int value;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ if (!numeric_arg (argv[0], ARG (1), &value))
+ return;
+
+ 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. |
+`-----------------------------------------------------------------------*/
+
+static void
+m4_divert (struct obstack *obs, int argc, token_data **argv)
+{
+ int i = 0;
+
+ if (bad_argc (argv[0], argc, 1, 2))
+ return;
+
+ if (argc == 2 && !numeric_arg (argv[0], ARG (1), &i))
+ return;
+
+ make_diversion (i);
+}
+
+/*-----------------------------------------------------.
+| Expand to the current diversion number, -1 if none. |
+`-----------------------------------------------------*/
+
+static void
+m4_divnum (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+ shipout_int (obs, current_diversion);
+}
+
+/*-----------------------------------------------------------------------.
+| Bring back the diversion given by the argument list. If none is |
+| specified, bring back all diversions. GNU specific is the option of |
+| undiverting named files, by passing a non-numeric argument to undivert |
+| (). |
+`-----------------------------------------------------------------------*/
+
+static void
+m4_undivert (struct obstack *obs, int argc, token_data **argv)
+{
+ int i, file;
+ FILE *fp;
+
+ if (argc == 1)
+ undivert_all ();
+ else
+ for (i = 1; i < argc; i++)
+ {
+ if (sscanf (ARG (i), "%d", &file) == 1)
+ insert_diversion (file);
+ else if (no_gnu_extensions)
+ M4ERROR ((warning_status, 0,
+ "Non-numeric argument to %s", TOKEN_DATA_TEXT (argv[0])));
+ else
+ {
+ fp = path_search (ARG (i));
+ if (fp != NULL)
+ {
+ insert_file (fp);
+ fclose (fp);
+ }
+ else
+ M4ERROR ((warning_status, errno,
+ "Cannot undivert %s", ARG (i)));
+ }
+ }
+}
+
+/* This section contains various macros, which does not fall into any
+ specific group. These are "dnl", "shift", "changequote", "changecom"
+ and "changeword". */
+
+/*------------------------------------------------------------------------.
+| Delete all subsequent whitespace from input. The function skip_line () |
+| lives in input.c. |
+`------------------------------------------------------------------------*/
+
+static void
+m4_dnl (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+
+ skip_line ();
+}
+
+/*-------------------------------------------------------------------------.
+| Shift all argument one to the left, discarding the first argument. Each |
+| output argument is quoted with the current quotes. |
+`-------------------------------------------------------------------------*/
+
+static void
+m4_shift (struct obstack *obs, int argc, token_data **argv)
+{
+ dump_args (obs, argc - 1, argv + 1, ",", TRUE);
+}
+
+/*--------------------------------------------------------------------------.
+| Change the current quotes. The function set_quotes () lives in input.c. |
+`--------------------------------------------------------------------------*/
+
+static void
+m4_changequote (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 1, 3))
+ return;
+
+ set_quotes ((argc >= 2) ? TOKEN_DATA_TEXT (argv[1]) : NULL,
+ (argc >= 3) ? TOKEN_DATA_TEXT (argv[2]) : NULL);
+}
+
+/*--------------------------------------------------------------------.
+| Change the current comment delimiters. The function set_comment () |
+| lives in input.c. |
+`--------------------------------------------------------------------*/
+
+static void
+m4_changecom (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 1, 3))
+ return;
+
+ if (argc == 1)
+ set_comment ("", ""); /* disable comments */
+ else
+ set_comment (TOKEN_DATA_TEXT (argv[1]),
+ (argc >= 3) ? TOKEN_DATA_TEXT (argv[2]) : NULL);
+}
+
+#ifdef ENABLE_CHANGEWORD
+
+/*-----------------------------------------------------------------------.
+| Change the regular expression used for breaking the input into words. |
+| The function set_word_regexp () lives in input.c. |
+`-----------------------------------------------------------------------*/
+
+static void
+m4_changeword (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ set_word_regexp (TOKEN_DATA_TEXT (argv[1]));
+}
+
+#endif /* ENABLE_CHANGEWORD */
+
+/* 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. */
+
+/*-------------------------------------------------------------------------.
+| Generic include function. Include the file given by the first argument, |
+| if it exists. Complain about inaccesible files iff SILENT is FALSE. |
+`-------------------------------------------------------------------------*/
+
+static void
+include (int argc, token_data **argv, boolean silent)
+{
+ FILE *fp;
+
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+
+ fp = path_search (ARG (1));
+ if (fp == NULL)
+ {
+ if (!silent)
+ M4ERROR ((warning_status, errno,
+ "Cannot open %s", ARG (1)));
+ return;
+ }
+
+ push_file (fp, ARG (1));
+}
+
+/*------------------------------------------------.
+| Include a file, complaining in case of errors. |
+`------------------------------------------------*/
+
+static void
+m4_include (struct obstack *obs, int argc, token_data **argv)
+{
+ include (argc, argv, FALSE);
+}
+
+/*----------------------------------.
+| Include a file, ignoring errors. |
+`----------------------------------*/
+
+static void
+m4_sinclude (struct obstack *obs, int argc, token_data **argv)
+{
+ include (argc, argv, TRUE);
+}
+
+/* More miscellaneous builtins -- "maketemp", "errprint", "__file__" and
+ "__line__". The last two are GNU specific. */
+
+/*------------------------------------------------------------------.
+| Use the first argument as at template for a temporary file name. |
+`------------------------------------------------------------------*/
+
+static void
+m4_maketemp (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+ mktemp (ARG (1));
+ obstack_grow (obs, ARG (1), strlen (ARG (1)));
+}
+
+/*----------------------------------------.
+| Print all arguments on standard error. |
+`----------------------------------------*/
+
+static void
+m4_errprint (struct obstack *obs, int argc, token_data **argv)
+{
+ dump_args (obs, argc, argv, " ", FALSE);
+ obstack_1grow (obs, '\0');
+ fprintf (stderr, "%s", (char *) obstack_finish (obs));
+ fflush (stderr);
+}
+
+static void
+m4___file__ (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+ obstack_grow (obs, lquote.string, lquote.length);
+ obstack_grow (obs, current_file, strlen (current_file));
+ obstack_grow (obs, rquote.string, rquote.length);
+}
+
+static void
+m4___line__ (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 1, 1))
+ return;
+ shipout_int (obs, current_line);
+}
+
+/* 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. |
+`-------------------------------------------------------------------------*/
+
+static void
+m4_m4exit (struct obstack *obs, int argc, token_data **argv)
+{
+ int exit_code = 0;
+
+ if (bad_argc (argv[0], argc, 1, 2))
+ return;
+ if (argc == 2 && !numeric_arg (argv[0], ARG (1), &exit_code))
+ exit_code = 0;
+
+ 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. |
+`-------------------------------------------------------------------------*/
+
+static void
+m4_m4wrap (struct obstack *obs, int argc, token_data **argv)
+{
+ if (no_gnu_extensions)
+ obstack_grow (obs, ARG (1), strlen (ARG (1)));
+ else
+ dump_args (obs, argc, argv, " ", FALSE);
+ obstack_1grow (obs, '\0');
+ push_wrapup (obstack_finish (obs));
+}
+
+/* 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. */
+
+/*-----------------------------------------------------------------------.
+| Set_trace () is used by "traceon" and "traceoff" to enable and disable |
+| tracing of a macro. It disables tracing if DATA is NULL, otherwise it |
+| enable tracing. |
+`-----------------------------------------------------------------------*/
+
+static void
+set_trace (symbol *sym, const char *data)
+{
+ SYMBOL_TRACED (sym) = (boolean) (data != NULL);
+}
+
+static void
+m4_traceon (struct obstack *obs, int argc, token_data **argv)
+{
+ symbol *s;
+ int i;
+
+ if (argc == 1)
+ hack_all_symbols (set_trace, (char *) obs);
+ else
+ for (i = 1; i < argc; i++)
+ {
+ s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
+ if (s != NULL)
+ set_trace (s, (char *) obs);
+ else
+ M4ERROR ((warning_status, 0,
+ "Undefined name %s", TOKEN_DATA_TEXT (argv[i])));
+ }
+}
+
+/*------------------------------------------------------------------------.
+| Disable tracing of all specified macros, or all, if none is specified. |
+`------------------------------------------------------------------------*/
+
+static void
+m4_traceoff (struct obstack *obs, int argc, token_data **argv)
+{
+ symbol *s;
+ int i;
+
+ if (argc == 1)
+ hack_all_symbols (set_trace, NULL);
+ else
+ for (i = 1; i < argc; i++)
+ {
+ s = lookup_symbol (TOKEN_DATA_TEXT (argv[i]), SYMBOL_LOOKUP);
+ if (s != NULL)
+ set_trace (s, NULL);
+ else
+ M4ERROR ((warning_status, 0,
+ "Undefined name %s", TOKEN_DATA_TEXT (argv[i])));
+ }
+}
+
+/*----------------------------------------------------------------------.
+| 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. |
+`----------------------------------------------------------------------*/
+
+static void
+m4_debugmode (struct obstack *obs, int argc, token_data **argv)
+{
+ int new_debug_level;
+ int change_flag;
+
+ if (bad_argc (argv[0], argc, 1, 2))
+ return;
+
+ if (argc == 1)
+ debug_level = 0;
+ else
+ {
+ if (ARG (1)[0] == '+' || ARG (1)[0] == '-')
+ {
+ change_flag = ARG (1)[0];
+ new_debug_level = debug_decode (ARG (1) + 1);
+ }
+ else
+ {
+ change_flag = 0;
+ new_debug_level = debug_decode (ARG (1));
+ }
+
+ if (new_debug_level < 0)
+ M4ERROR ((warning_status, 0,
+ "Debugmode: bad debug flags: `%s'", ARG (1)));
+ else
+ {
+ switch (change_flag)
+ {
+ case 0:
+ debug_level = new_debug_level;
+ break;
+
+ case '+':
+ debug_level |= new_debug_level;
+ break;
+
+ case '-':
+ debug_level &= ~new_debug_level;
+ break;
+ }
+ }
+ }
+}
+
+/*-------------------------------------------------------------------------.
+| Specify the destination of the debugging output. With one argument, the |
+| argument is taken as a file name, with no arguments, revert to stderr. |
+`-------------------------------------------------------------------------*/
+
+static void
+m4_debugfile (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 1, 2))
+ return;
+
+ if (argc == 1)
+ debug_set_output (NULL);
+ else if (!debug_set_output (ARG (1)))
+ M4ERROR ((warning_status, errno,
+ "Cannot set error file: %s", ARG (1)));
+}
+
+/* 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. |
+`---------------------------------------------*/
+
+static void
+m4_len (struct obstack *obs, int argc, token_data **argv)
+{
+ if (bad_argc (argv[0], argc, 2, 2))
+ return;
+ shipout_int (obs, strlen (ARG (1)));
+}
+
+/*-------------------------------------------------------------------------.
+| The macro expands to the first index of the second argument in the first |
+| argument. |
+`-------------------------------------------------------------------------*/
+
+static void
+m4_index (struct obstack *obs, int argc, token_data **argv)
+{
+ const char *cp, *last;
+ int l1, l2, retval;
+
+ if (bad_argc (argv[0], argc, 3, 3))
+ return;
+
+ l1 = strlen (ARG (1));
+ l2 = strlen (ARG (2));
+
+ last = ARG (1) + l1 - l2;
+
+ for (cp = ARG (1); cp <= last; cp++)
+ {
+ if (strncmp (cp, ARG (2), l2) == 0)
+ break;
+ }
+ retval = (cp <= last) ? cp - ARG (1) : -1;
+
+ 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, the |
+| substring extends to the end of the first argument. |
+`-------------------------------------------------------------------------*/
+
+static void
+m4_substr (struct obstack *obs, int argc, token_data **argv)
+{
+ int start, length, avail;
+
+ if (bad_argc (argv[0], argc, 3, 4))
+ return;
+
+ length = avail = strlen (ARG (1));
+ if (!numeric_arg (argv[0], ARG (2), &start))
+ return;
+
+ if (argc == 4 && !numeric_arg (argv[0], ARG (3), &length))
+ return;
+
+ if (start < 0 || length <= 0 || start >= avail)
+ return;
+
+ if (start + length > avail)
+ length = avail - start;
+ obstack_grow (obs, ARG (1) + start, length);
+}
+
+/*------------------------------------------------------------------------.
+| For "translit", ranges are allowed in the second and third argument. |
+| They are expanded in the following function, and the expanded strings, |
+| without any ranges left, are used to translate the characters of the |
+| first argument. 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. |
+`------------------------------------------------------------------------*/
+
+static const char *
+expand_ranges (const char *s, struct obstack *obs)
+{
+ char from;
+ char to;
+
+ for (from = '\0'; *s != '\0'; from = *s++)
+ {
+ if (*s == '-' && from != '\0')
+ {
+ to = *++s;
+ if (to == '\0')
+ obstack_1grow (obs, '-'); /* trailing dash */
+ else if (from <= to)
+ {
+ while (from++ < to)
+ obstack_1grow (obs, from);
+ }
+ else
+ {
+ while (--from >= to)
+ obstack_1grow (obs, from);
+ }
+ }
+ else
+ obstack_1grow (obs, *s);
+ }
+ obstack_1grow (obs, '\0');
+ return 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 (pueh). |
+`----------------------------------------------------------------------*/
+
+static void
+m4_translit (struct obstack *obs, int argc, token_data **argv)
+{
+ register const char *data, *tmp;
+ const char *from, *to;
+ int tolen;
+
+ if (bad_argc (argv[0], argc, 3, 4))
+ return;
+
+ from = ARG (2);
+ if (strchr (from, '-') != NULL)
+ {
+ from = expand_ranges (from, obs);
+ if (from == NULL)
+ return;
+ }
+
+ if (argc == 4)
+ {
+ to = ARG (3);
+ if (strchr (to, '-') != NULL)
+ {
+ to = expand_ranges (to, obs);
+ if (to == NULL)
+ return;
+ }
+ }
+ else
+ to = "";
+
+ tolen = strlen (to);
+
+ for (data = ARG (1); *data; data++)
+ {
+ tmp = strchr (from, *data);
+ if (tmp == NULL)
+ {
+ obstack_1grow (obs, *data);
+ }
+ else
+ {
+ if (tmp - from < tolen)
+ obstack_1grow (obs, *(to + (tmp - from)));
+ }
+ }
+}
+
+/*----------------------------------------------------------------------.
+| Frontend for printf like formatting. The function format () lives in |
+| the file format.c. |
+`----------------------------------------------------------------------*/
+
+static void
+m4_format (struct obstack *obs, int argc, token_data **argv)
+{
+ format (obs, argc - 1, argv + 1);
+}
+
+/*-------------------------------------------------------------------------.
+| Function to perform substitution by regular expressions. Used by the |
+| builtins regexp and patsubst. The changed text is placed on the |
+| obstack. The substitution is REPL, with \& substituted by this part of |
+| VICTIM matched by the last whole regular expression, taken from REGS[0], |
+| and \N substituted by the text matched by the Nth parenthesized |
+| sub-expression, taken from REGS[N]. |
+`-------------------------------------------------------------------------*/
+
+static int substitute_warned = 0;
+
+static void
+substitute (struct obstack *obs, const char *victim, const char *repl,
+ struct re_registers *regs)
+{
+ register unsigned int ch;
+
+ for (;;)
+ {
+ while ((ch = *repl++) != '\\')
+ {
+ if (ch == '\0')
+ return;
+ obstack_1grow (obs, ch);
+ }
+
+ switch ((ch = *repl++))
+ {
+ case '0':
+ if (!substitute_warned)
+ {
+ M4ERROR ((warning_status, 0, "\
+WARNING: \\0 will disappear, use \\& instead in replacements"));
+ substitute_warned = 1;
+ }
+ /* Fall through. */
+
+ case '&':
+ obstack_grow (obs, victim + regs->start[0],
+ regs->end[0] - 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 (regs->end[ch] > 0)
+ obstack_grow (obs, victim + regs->start[ch],
+ regs->end[ch] - regs->start[ch]);
+ break;
+
+ default:
+ obstack_1grow (obs, ch);
+ break;
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------.
+| 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 here is no match. Given a third argument, is changes |
+| the expansion to this argument. |
+`--------------------------------------------------------------------------*/
+
+static void
+m4_regexp (struct obstack *obs, int argc, token_data **argv)
+{
+ const char *victim; /* first argument */
+ const char *regexp; /* regular expression */
+ const char *repl; /* replacement string */
+
+ struct re_pattern_buffer buf; /* compiled regular expression */
+ struct re_registers regs; /* for subexpression matches */
+ const char *msg; /* error message from re_compile_pattern */
+ int startpos; /* start position of match */
+ int length; /* length of first argument */
+
+ if (bad_argc (argv[0], argc, 3, 4))
+ return;
+
+ victim = TOKEN_DATA_TEXT (argv[1]);
+ regexp = TOKEN_DATA_TEXT (argv[2]);
+
+ buf.buffer = NULL;
+ buf.allocated = 0;
+ buf.fastmap = NULL;
+ buf.translate = NULL;
+ msg = re_compile_pattern (regexp, strlen (regexp), &buf);
+
+ if (msg != NULL)
+ {
+ M4ERROR ((warning_status, 0,
+ "Bad regular expression: `%s': %s", regexp, msg));
+ return;
+ }
+
+ length = strlen (victim);
+ startpos = re_search (&buf, victim, length, 0, length, &regs);
+ xfree (buf.buffer);
+
+ if (startpos == -2)
+ {
+ M4ERROR ((warning_status, 0,
+ "Error matching regular expression \"%s\"", regexp));
+ return;
+ }
+
+ if (argc == 3)
+ shipout_int (obs, startpos);
+ else if (startpos >= 0)
+ {
+ repl = TOKEN_DATA_TEXT (argv[3]);
+ substitute (obs, victim, repl, &regs);
+ }
+
+ return;
+}
+
+/*--------------------------------------------------------------------------.
+| Substitute all matches of a regexp occuring in a string. Each match of |
+| the second argument (a regexp) in the first argument is changed to the |
+| third argument, with \& substituted by the matched text, and \N |
+| substituted by the text matched by the Nth parenthesized sub-expression. |
+`--------------------------------------------------------------------------*/
+
+static void
+m4_patsubst (struct obstack *obs, int argc, token_data **argv)
+{
+ const char *victim; /* first argument */
+ const char *regexp; /* regular expression */
+
+ struct re_pattern_buffer buf; /* compiled regular expression */
+ struct re_registers regs; /* for subexpression matches */
+ const char *msg; /* error message from re_compile_pattern */
+ int matchpos; /* start position of match */
+ int offset; /* current match offset */
+ int length; /* length of first argument */
+
+ if (bad_argc (argv[0], argc, 3, 4))
+ return;
+
+ regexp = TOKEN_DATA_TEXT (argv[2]);
+
+ buf.buffer = NULL;
+ buf.allocated = 0;
+ buf.fastmap = NULL;
+ buf.translate = NULL;
+ msg = re_compile_pattern (regexp, strlen (regexp), &buf);
+
+ if (msg != NULL)
+ {
+ M4ERROR ((warning_status, 0,
+ "Bad regular expression `%s': %s", regexp, msg));
+ if (buf.buffer != NULL)
+ xfree (buf.buffer);
+ return;
+ }
+
+ victim = TOKEN_DATA_TEXT (argv[1]);
+ length = strlen (victim);
+
+ offset = 0;
+ matchpos = 0;
+ while (offset < length)
+ {
+ matchpos = re_search (&buf, victim, length,
+ offset, length - offset, &regs);
+ 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)
+ M4ERROR ((warning_status, 0,
+ "Error matching regular expression \"%s\"", regexp));
+ else if (offset < length)
+ obstack_grow (obs, victim + offset, length - 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 (obs, victim, ARG (3), &regs);
+
+ /* 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 = regs.end[0];
+ if (regs.start[0] == regs.end[0])
+ obstack_1grow (obs, victim[offset++]);
+ }
+ obstack_1grow (obs, '\0');
+
+ xfree (buf.buffer);
+ return;
+}
+
+/*-------------------------------------------------------------------------.
+| 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. SYM points to the macro |
+| definition, giving the expansion text. ARGC and ARGV are the arguments, |
+| as usual. |
+`-------------------------------------------------------------------------*/
+
+void
+expand_user_macro (struct obstack *obs, symbol *sym,
+ int argc, token_data **argv)
+{
+ register const char *text;
+ int i;
+
+ for (text = SYMBOL_TEXT (sym); *text != '\0';)
+ {
+ if (*text != '$')
+ {
+ obstack_1grow (obs, *text);
+ text++;
+ continue;
+ }
+ text++;
+ switch (*text)
+ {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (no_gnu_extensions)
+ {
+ i = *text++ - '0';
+ }
+ else
+ {
+ for (i = 0; isdigit (*text); text++)
+ i = i*10 + (*text - '0');
+ }
+ if (i < argc)
+ obstack_grow (obs, TOKEN_DATA_TEXT (argv[i]),
+ strlen (TOKEN_DATA_TEXT (argv[i])));
+ break;
+
+ case '#': /* number of arguments */
+ shipout_int (obs, argc - 1);
+ text++;
+ break;
+
+ case '*': /* all arguments */
+ case '@': /* ... same, but quoted */
+ dump_args (obs, argc, argv, ",", *text == '@');
+ text++;
+ break;
+
+ default:
+ obstack_1grow (obs, '$');
+ break;
+ }
+ }
+}
diff --git a/src/builtin.h b/src/builtin.h
new file mode 100644
index 00000000..89088513
--- /dev/null
+++ b/src/builtin.h
@@ -0,0 +1,39 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1998 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Declarations for builtin macros. */
+
+#ifndef BUILTIN_H
+#define BUILTIN_H 1
+
+#include <m4.h>
+
+#define ARG(i) (argc > (i) ? TOKEN_DATA_TEXT (argv[i]) : "")
+
+#define DECLARE(name) \
+ static void name __P ((struct obstack *, int, token_data **))
+
+
+
+boolean bad_argc (token_data *name, int argc, int min, int max);
+const char *skip_space (const char *arg);
+
+boolean numeric_arg (token_data *macro, const char *arg, int *valuep);
+void shipout_int (struct obstack *obs, int val);
+
+#endif /* BUILTIN_H */
diff --git a/src/debug.c b/src/debug.c
new file mode 100644
index 00000000..ad1988d1
--- /dev/null
+++ b/src/debug.c
@@ -0,0 +1,421 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1991, 1992, 1993, 1994 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "m4.h"
+
+#include <sys/stat.h>
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/* File for debugging output. */
+FILE *debug = NULL;
+
+/* Obstack for trace messages. */
+static struct obstack trace;
+
+extern int expansion_level;
+
+static void debug_set_file _((FILE *));
+
+/*----------------------------------.
+| Initialise the debugging module. |
+`----------------------------------*/
+
+void
+debug_init (void)
+{
+ debug_set_file (stderr);
+ obstack_init (&trace);
+}
+
+/*-----------------------------------------------------------------.
+| Function to decode the debugging flags OPTS. Used by main while |
+| processing option -d, and by the builtin debugmode (). |
+`-----------------------------------------------------------------*/
+
+int
+debug_decode (const char *opts)
+{
+ int level;
+
+ if (opts == NULL || *opts == '\0')
+ level = DEBUG_TRACE_DEFAULT;
+ else
+ {
+ for (level = 0; *opts; opts++)
+ {
+ switch (*opts)
+ {
+ case 'a':
+ level |= DEBUG_TRACE_ARGS;
+ break;
+
+ case 'e':
+ level |= DEBUG_TRACE_EXPANSION;
+ break;
+
+ case 'q':
+ level |= DEBUG_TRACE_QUOTE;
+ break;
+
+ case 't':
+ level |= DEBUG_TRACE_ALL;
+ break;
+
+ case 'l':
+ level |= DEBUG_TRACE_LINE;
+ break;
+
+ case 'f':
+ level |= DEBUG_TRACE_FILE;
+ break;
+
+ case 'p':
+ level |= DEBUG_TRACE_PATH;
+ break;
+
+ case 'c':
+ level |= DEBUG_TRACE_CALL;
+ break;
+
+ case 'i':
+ level |= DEBUG_TRACE_INPUT;
+ break;
+
+ case 'x':
+ level |= DEBUG_TRACE_CALLID;
+ break;
+
+ case 'V':
+ level |= DEBUG_TRACE_VERBOSE;
+ break;
+
+ default:
+ return -1;
+ }
+ }
+ }
+
+ /* This is to avoid screwing up the trace output due to changes in the
+ debug_level. */
+
+ obstack_free (&trace, obstack_finish (&trace));
+
+ 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. |
+`------------------------------------------------------------------------*/
+
+static void
+debug_set_file (FILE *fp)
+{
+ struct stat stdout_stat, debug_stat;
+
+ if (debug != NULL && debug != stderr && debug != stdout)
+ fclose (debug);
+ debug = fp;
+
+ if (debug != NULL && debug != stdout)
+ {
+ if (fstat (fileno (stdout), &stdout_stat) < 0)
+ return;
+ if (fstat (fileno (debug), &debug_stat) < 0)
+ return;
+
+ if (stdout_stat.st_ino == debug_stat.st_ino
+ && stdout_stat.st_dev == debug_stat.st_dev)
+ {
+ if (debug != stderr)
+ fclose (debug);
+ debug = stdout;
+ }
+ }
+}
+
+/*-----------------------------------------------------------.
+| Serialize files. Used before executing a system command. |
+`-----------------------------------------------------------*/
+
+void
+debug_flush_files (void)
+{
+ fflush (stdout);
+ fflush (stderr);
+ if (debug != NULL && debug != stdout && debug != stderr)
+ fflush (debug);
+}
+
+/*-------------------------------------------------------------------------.
+| 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. |
+`-------------------------------------------------------------------------*/
+
+boolean
+debug_set_output (const char *name)
+{
+ FILE *fp;
+
+ if (name == NULL)
+ debug_set_file (stderr);
+ else if (*name == '\0')
+ debug_set_file (NULL);
+ else
+ {
+ fp = fopen (name, "a");
+ if (fp == NULL)
+ return FALSE;
+
+ debug_set_file (fp);
+ }
+ return TRUE;
+}
+
+/*-----------------------------------------------------------------------.
+| Print the header of a one-line debug message, starting by "m4 debug". |
+`-----------------------------------------------------------------------*/
+
+void
+debug_message_prefix (void)
+{
+ fprintf (debug, "m4 debug: ");
+ if (debug_level & DEBUG_TRACE_FILE)
+ fprintf (debug, "%s: ", current_file);
+ if (debug_level & DEBUG_TRACE_LINE)
+ fprintf (debug, "%d: ", current_line);
+}
+
+/* The rest 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. */
+
+/*---------------------------------------------------------------------.
+| Tracing output is formatted here, by a simplified printf-to-obstack |
+| function trace_format (). Understands only %S, %s, %d, %l (optional |
+| left quote) and %r (optional right quote). |
+`---------------------------------------------------------------------*/
+
+#if __STDC__
+static void
+trace_format (const char *fmt, ...)
+#else
+static void
+trace_format (...)
+#endif
+{
+#if ! __STDC__
+ const char *fmt;
+#endif
+ va_list args;
+ char ch;
+
+ int d;
+ char nbuf[32];
+ const char *s;
+ int slen;
+ int maxlen;
+
+#if __STDC__
+ va_start (args, fmt);
+#else
+ va_start (args);
+ fmt = va_arg (args, const char *);
+#endif
+
+ while (TRUE)
+ {
+ while ((ch = *fmt++) != '\0' && ch != '%')
+ obstack_1grow (&trace, ch);
+
+ if (ch == '\0')
+ break;
+
+ maxlen = 0;
+ switch (*fmt++)
+ {
+ case 'S':
+ maxlen = max_debug_argument_length;
+ /* fall through */
+
+ case 's':
+ s = va_arg (args, const char *);
+ break;
+
+ case 'l':
+ s = (debug_level & DEBUG_TRACE_QUOTE) ? lquote.string : "";
+ break;
+
+ case 'r':
+ s = (debug_level & DEBUG_TRACE_QUOTE) ? rquote.string : "";
+ break;
+
+ case 'd':
+ d = va_arg (args, int);
+ sprintf (nbuf, "%d", d);
+ s = nbuf;
+ break;
+
+ default:
+ s = "";
+ break;
+ }
+
+ slen = strlen (s);
+ if (maxlen == 0 || maxlen > slen)
+ obstack_grow (&trace, s, slen);
+ else
+ {
+ obstack_grow (&trace, s, maxlen);
+ obstack_grow (&trace, "...", 3);
+ }
+ }
+
+ va_end (args);
+}
+
+/*------------------------------------------------------------------.
+| Format the standard header attached to all tracing output lines. |
+`------------------------------------------------------------------*/
+
+static void
+trace_header (int id)
+{
+ trace_format ("m4trace:");
+ if (debug_level & DEBUG_TRACE_FILE)
+ trace_format ("%s:", current_file);
+ if (debug_level & DEBUG_TRACE_LINE)
+ trace_format ("%d:", current_line);
+ trace_format (" -%d- ", expansion_level);
+ if (debug_level & DEBUG_TRACE_CALLID)
+ trace_format ("id %d: ", id);
+}
+
+/*----------------------------------------------------.
+| Print current tracing line, and clear the obstack. |
+`----------------------------------------------------*/
+
+static void
+trace_flush (void)
+{
+ char *line;
+
+ obstack_1grow (&trace, '\0');
+ line = obstack_finish (&trace);
+ DEBUG_PRINT1 ("%s\n", line);
+ obstack_free (&trace, line);
+}
+
+/*-------------------------------------------------------------.
+| Do pre-argument-collction tracing for macro NAME. Used from |
+| expand_macro (). |
+`-------------------------------------------------------------*/
+
+void
+trace_prepre (const char *name, int id)
+{
+ trace_header (id);
+ trace_format ("%s ...", name);
+ trace_flush ();
+}
+
+/*-----------------------------------------------------------------------.
+| Format the parts of a trace line, that can be made before the macro is |
+| actually expanded. Used from expand_macro (). |
+`-----------------------------------------------------------------------*/
+
+void
+trace_pre (const char *name, int id, int argc, token_data **argv)
+{
+ int i;
+ const builtin *bp;
+
+ trace_header (id);
+ trace_format ("%s", name);
+
+ if (argc > 1 && (debug_level & DEBUG_TRACE_ARGS))
+ {
+ trace_format ("(");
+
+ for (i = 1; i < argc; i++)
+ {
+ if (i != 1)
+ trace_format (", ");
+
+ switch (TOKEN_DATA_TYPE (argv[i]))
+ {
+ case TOKEN_TEXT:
+ trace_format ("%l%S%r", TOKEN_DATA_TEXT (argv[i]));
+ break;
+
+ case TOKEN_FUNC:
+ bp = find_builtin_by_addr (TOKEN_DATA_FUNC (argv[i]));
+ if (bp == NULL)
+ {
+ M4ERROR ((warning_status, 0, "\
+INTERNAL ERROR: Builtin not found in builtin table! (trace_pre ())"));
+ abort ();
+ }
+ trace_format ("<%s>", bp->name);
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad token data type (trace_pre ())"));
+ abort ();
+ }
+
+ }
+ trace_format (")");
+ }
+
+ if (debug_level & DEBUG_TRACE_CALL)
+ {
+ trace_format (" -> ???");
+ trace_flush ();
+ }
+}
+
+/*-------------------------------------------------------------------.
+| Format the final part of a trace line and print it all. Used from |
+| expand_macro (). |
+`-------------------------------------------------------------------*/
+
+void
+trace_post (const char *name, int id, int argc, token_data **argv,
+ const char *expanded)
+{
+ if (debug_level & DEBUG_TRACE_CALL)
+ {
+ trace_header (id);
+ trace_format ("%s%s", name, (argc > 1) ? "(...)" : "");
+ }
+
+ if (expanded && (debug_level & DEBUG_TRACE_EXPANSION))
+ trace_format (" -> %l%S%r", expanded);
+ trace_flush ();
+}
diff --git a/src/eval.c b/src/eval.c
new file mode 100644
index 00000000..c6dc85f4
--- /dev/null
+++ b/src/eval.c
@@ -0,0 +1,774 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* This file contains the functions to evaluate integer expressions for
+ the "eval" macro. It is a little, fairly self-contained module, with
+ its own scanner, and a recursive descent parser. The only entry point
+ is evaluate (). */
+
+#include "m4.h"
+
+/* Evaluates token types. */
+
+typedef enum eval_token
+ {
+ ERROR,
+ PLUS, MINUS,
+ EXPONENT,
+ TIMES, DIVIDE, MODULO,
+ EQ, NOTEQ, GT, GTEQ, LS, LSEQ,
+ LSHIFT, RSHIFT,
+ LNOT, LAND, LOR,
+ NOT, AND, OR, XOR,
+ LEFTP, RIGHTP,
+ NUMBER, EOTEXT
+ }
+eval_token;
+
+/* Error types. */
+
+typedef enum eval_error
+ {
+ NO_ERROR,
+ MISSING_RIGHT,
+ SYNTAX_ERROR,
+ UNKNOWN_INPUT,
+ EXCESS_INPUT,
+ DIVIDE_ZERO,
+ MODULO_ZERO
+ }
+eval_error;
+
+static eval_error logical_or_term _((eval_token, eval_t *));
+static eval_error logical_and_term _((eval_token, eval_t *));
+static eval_error or_term _((eval_token, eval_t *));
+static eval_error xor_term _((eval_token, eval_t *));
+static eval_error and_term _((eval_token, eval_t *));
+static eval_error not_term _((eval_token, eval_t *));
+static eval_error logical_not_term _((eval_token, eval_t *));
+static eval_error cmp_term _((eval_token, eval_t *));
+static eval_error shift_term _((eval_token, eval_t *));
+static eval_error add_term _((eval_token, eval_t *));
+static eval_error mult_term _((eval_token, eval_t *));
+static eval_error exp_term _((eval_token, eval_t *));
+static eval_error unary_term _((eval_token, eval_t *));
+static eval_error simple_term _((eval_token, eval_t *));
+
+/*--------------------.
+| 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;
+
+static void
+eval_init_lex (const char *text)
+{
+ eval_text = text;
+ last_text = NULL;
+}
+
+static void
+eval_undo (void)
+{
+ eval_text = last_text;
+}
+
+/* VAL is numerical value, if any. */
+
+static eval_token
+eval_lex (eval_t *val)
+{
+ while (isspace (*eval_text))
+ eval_text++;
+
+ last_text = eval_text;
+
+ if (*eval_text == '\0')
+ return EOTEXT;
+
+ if (isdigit (*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 (*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;
+
+ (*val) = 0;
+ for (; *eval_text; eval_text++)
+ {
+ if (isdigit (*eval_text))
+ digit = *eval_text - '0';
+ else if (islower (*eval_text))
+ digit = *eval_text - 'a' + 10;
+ else if (isupper (*eval_text))
+ digit = *eval_text - 'A' + 10;
+ else
+ break;
+
+ if (digit >= base)
+ break;
+
+ (*val) = (*val) * base + digit;
+ }
+ return NUMBER;
+ }
+
+ switch (*eval_text++)
+ {
+ case '+':
+ return PLUS;
+ case '-':
+ return MINUS;
+ case '*':
+ if (*eval_text == '*')
+ {
+ eval_text++;
+ return EXPONENT;
+ }
+ else
+ return TIMES;
+ case '/':
+ return DIVIDE;
+ case '%':
+ return MODULO;
+ case '=':
+ if (*eval_text == '=')
+ eval_text++;
+ return EQ;
+ case '!':
+ if (*eval_text == '=')
+ {
+ eval_text++;
+ return NOTEQ;
+ }
+ else
+ return LNOT;
+ case '>':
+ if (*eval_text == '=')
+ {
+ eval_text++;
+ return GTEQ;
+ }
+ else if (*eval_text == '>')
+ {
+ eval_text++;
+ return RSHIFT;
+ }
+ else
+ return GT;
+ case '<':
+ if (*eval_text == '=')
+ {
+ eval_text++;
+ return LSEQ;
+ }
+ else if (*eval_text == '<')
+ {
+ eval_text++;
+ return LSHIFT;
+ }
+ else
+ return LS;
+ case '^':
+ return XOR;
+ case '~':
+ return NOT;
+ case '&':
+ if (*eval_text == '&')
+ {
+ eval_text++;
+ return LAND;
+ }
+ else
+ return AND;
+ case '|':
+ if (*eval_text == '|')
+ {
+ eval_text++;
+ return LOR;
+ }
+ else
+ return OR;
+ case '(':
+ return LEFTP;
+ case ')':
+ return RIGHTP;
+ default:
+ return ERROR;
+ }
+}
+
+/*---------------------------------------.
+| Main entry point, called from "eval". |
+`---------------------------------------*/
+
+boolean
+evaluate (const char *expr, eval_t *val)
+{
+ eval_token et;
+ eval_error err;
+
+ eval_init_lex (expr);
+ et = eval_lex (val);
+ err = logical_or_term (et, val);
+
+ if (err == NO_ERROR && *eval_text != '\0')
+ err = EXCESS_INPUT;
+
+ switch (err)
+ {
+ case NO_ERROR:
+ break;
+
+ case MISSING_RIGHT:
+ M4ERROR ((warning_status, 0,
+ "Bad expression in eval (missing right parenthesis): %s",
+ expr));
+ break;
+
+ case SYNTAX_ERROR:
+ M4ERROR ((warning_status, 0,
+ "Bad expression in eval: %s", expr));
+ break;
+
+ case UNKNOWN_INPUT:
+ M4ERROR ((warning_status, 0,
+ "Bad expression in eval (bad input): %s", expr));
+ break;
+
+ case EXCESS_INPUT:
+ M4ERROR ((warning_status, 0,
+ "Bad expression in eval (excess input): %s", expr));
+ break;
+
+ case DIVIDE_ZERO:
+ M4ERROR ((warning_status, 0,
+ "Divide by zero in eval: %s", expr));
+ break;
+
+ case MODULO_ZERO:
+ M4ERROR ((warning_status, 0,
+ "Modulo by zero in eval: %s", expr));
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad error code in evaluate ()"));
+ abort ();
+ }
+
+ return (boolean) (err != NO_ERROR);
+}
+
+/*---------------------------.
+| Recursive descent parser. |
+`---------------------------*/
+
+static eval_error
+logical_or_term (eval_token et, eval_t *v1)
+{
+ eval_t v2;
+ eval_error er;
+
+ if ((er = logical_and_term (et, v1)) != NO_ERROR)
+ return er;
+
+ while ((et = eval_lex (&v2)) == LOR)
+ {
+ et = eval_lex (&v2);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = logical_and_term (et, &v2)) != NO_ERROR)
+ return er;
+
+ *v1 = *v1 || v2;
+ }
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ eval_undo ();
+ return NO_ERROR;
+}
+
+static eval_error
+logical_and_term (eval_token et, eval_t *v1)
+{
+ eval_t v2;
+ eval_error er;
+
+ if ((er = or_term (et, v1)) != NO_ERROR)
+ return er;
+
+ while ((et = eval_lex (&v2)) == LAND)
+ {
+ et = eval_lex (&v2);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = or_term (et, &v2)) != NO_ERROR)
+ return er;
+
+ *v1 = *v1 && v2;
+ }
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ eval_undo ();
+ return NO_ERROR;
+}
+
+static eval_error
+or_term (eval_token et, eval_t *v1)
+{
+ eval_t v2;
+ eval_error er;
+
+ if ((er = xor_term (et, v1)) != NO_ERROR)
+ return er;
+
+ while ((et = eval_lex (&v2)) == OR)
+ {
+ et = eval_lex (&v2);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = xor_term (et, &v2)) != NO_ERROR)
+ return er;
+
+ *v1 = *v1 | v2;
+ }
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ eval_undo ();
+ return NO_ERROR;
+}
+
+static eval_error
+xor_term (eval_token et, eval_t *v1)
+{
+ eval_t v2;
+ eval_error er;
+
+ if ((er = and_term (et, v1)) != NO_ERROR)
+ return er;
+
+ while ((et = eval_lex (&v2)) == XOR)
+ {
+ et = eval_lex (&v2);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = and_term (et, &v2)) != NO_ERROR)
+ return er;
+
+ *v1 = *v1 ^ v2;
+ }
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ eval_undo ();
+ return NO_ERROR;
+}
+
+static eval_error
+and_term (eval_token et, eval_t *v1)
+{
+ eval_t v2;
+ eval_error er;
+
+ if ((er = not_term (et, v1)) != NO_ERROR)
+ return er;
+
+ while ((et = eval_lex (&v2)) == AND)
+ {
+ et = eval_lex (&v2);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = not_term (et, &v2)) != NO_ERROR)
+ return er;
+
+ *v1 = *v1 & v2;
+ }
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ eval_undo ();
+ return NO_ERROR;
+}
+
+static eval_error
+not_term (eval_token et, eval_t *v1)
+{
+ eval_error er;
+
+ if (et == NOT)
+ {
+ et = eval_lex (v1);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = not_term (et, v1)) != NO_ERROR)
+ return er;
+ *v1 = ~*v1;
+ }
+ else
+ if ((er = logical_not_term (et, v1)) != NO_ERROR)
+ return er;
+
+ return NO_ERROR;
+}
+
+static eval_error
+logical_not_term (eval_token et, eval_t *v1)
+{
+ eval_error er;
+
+ if (et == LNOT)
+ {
+ et = eval_lex (v1);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = logical_not_term (et, v1)) != NO_ERROR)
+ return er;
+ *v1 = !*v1;
+ }
+ else
+ if ((er = cmp_term (et, v1)) != NO_ERROR)
+ return er;
+
+ return NO_ERROR;
+}
+
+static eval_error
+cmp_term (eval_token et, eval_t *v1)
+{
+ eval_token op;
+ eval_t v2;
+ eval_error er;
+
+ if ((er = shift_term (et, v1)) != NO_ERROR)
+ return er;
+
+ while ((op = eval_lex (&v2)) == EQ || op == NOTEQ
+ || op == GT || op == GTEQ
+ || op == LS || op == LSEQ)
+ {
+
+ et = eval_lex (&v2);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = shift_term (et, &v2)) != NO_ERROR)
+ return er;
+
+ switch (op)
+ {
+ case EQ:
+ *v1 = *v1 == v2;
+ break;
+
+ case NOTEQ:
+ *v1 = *v1 != v2;
+ break;
+
+ case GT:
+ *v1 = *v1 > v2;
+ break;
+
+ case GTEQ:
+ *v1 = *v1 >= v2;
+ break;
+
+ case LS:
+ *v1 = *v1 < v2;
+ break;
+
+ case LSEQ:
+ *v1 = *v1 <= v2;
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad comparison operator in cmp_term ()"));
+ abort ();
+ }
+ }
+ if (op == ERROR)
+ return UNKNOWN_INPUT;
+
+ eval_undo ();
+ return NO_ERROR;
+}
+
+static eval_error
+shift_term (eval_token et, eval_t *v1)
+{
+ eval_token op;
+ eval_t v2;
+ eval_error er;
+
+ if ((er = add_term (et, v1)) != NO_ERROR)
+ return er;
+
+ while ((op = eval_lex (&v2)) == LSHIFT || op == RSHIFT)
+ {
+
+ et = eval_lex (&v2);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = add_term (et, &v2)) != NO_ERROR)
+ return er;
+
+ switch (op)
+ {
+ case LSHIFT:
+ *v1 = *v1 << v2;
+ break;
+
+ case RSHIFT:
+ *v1 = *v1 >> v2;
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad shift operator in shift_term ()"));
+ abort ();
+ }
+ }
+ if (op == ERROR)
+ return UNKNOWN_INPUT;
+
+ eval_undo ();
+ return NO_ERROR;
+}
+
+static eval_error
+add_term (eval_token et, eval_t *v1)
+{
+ eval_token op;
+ eval_t v2;
+ eval_error er;
+
+ if ((er = mult_term (et, v1)) != NO_ERROR)
+ return er;
+
+ while ((op = eval_lex (&v2)) == PLUS || op == MINUS)
+ {
+ et = eval_lex (&v2);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = mult_term (et, &v2)) != NO_ERROR)
+ return er;
+
+ if (op == PLUS)
+ *v1 = *v1 + v2;
+ else
+ *v1 = *v1 - v2;
+ }
+ if (op == ERROR)
+ return UNKNOWN_INPUT;
+
+ eval_undo ();
+ return NO_ERROR;
+}
+
+static eval_error
+mult_term (eval_token et, eval_t *v1)
+{
+ eval_token op;
+ eval_t v2;
+ eval_error er;
+
+ if ((er = exp_term (et, v1)) != NO_ERROR)
+ return er;
+
+ while ((op = eval_lex (&v2)) == TIMES || op == DIVIDE || op == MODULO)
+ {
+ et = eval_lex (&v2);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = exp_term (et, &v2)) != NO_ERROR)
+ return er;
+
+ switch (op)
+ {
+ case TIMES:
+ *v1 = *v1 * v2;
+ break;
+
+ case DIVIDE:
+ if (v2 == 0)
+ return DIVIDE_ZERO;
+ else
+ *v1 = *v1 / v2;
+ break;
+
+ case MODULO:
+ if (v2 == 0)
+ return MODULO_ZERO;
+ else
+ *v1 = *v1 % v2;
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad operator in mult_term ()"));
+ abort ();
+ }
+ }
+ if (op == ERROR)
+ return UNKNOWN_INPUT;
+
+ eval_undo ();
+ return NO_ERROR;
+}
+
+static eval_error
+exp_term (eval_token et, eval_t *v1)
+{
+ register eval_t result;
+ eval_t v2;
+ eval_error er;
+
+ if ((er = unary_term (et, v1)) != NO_ERROR)
+ return er;
+ result = *v1;
+
+ while ((et = eval_lex (&v2)) == EXPONENT)
+ {
+ et = eval_lex (&v2);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = exp_term (et, &v2)) != NO_ERROR)
+ return er;
+
+ result = 1;
+ while (v2-- > 0)
+ result *= *v1;
+ *v1 = result;
+ }
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ eval_undo ();
+ return NO_ERROR;
+}
+
+static eval_error
+unary_term (eval_token et, eval_t *v1)
+{
+ eval_token et2 = et;
+ eval_error er;
+
+ if (et == PLUS || et == MINUS)
+ {
+ et2 = eval_lex (v1);
+ if (et2 == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = simple_term (et2, v1)) != NO_ERROR)
+ return er;
+
+ if (et == MINUS)
+ *v1 = -*v1;
+ }
+ else
+ if ((er = simple_term (et, v1)) != NO_ERROR)
+ return er;
+
+ return NO_ERROR;
+}
+
+static eval_error
+simple_term (eval_token et, eval_t *v1)
+{
+ eval_t v2;
+ eval_error er;
+
+ switch (et)
+ {
+ case LEFTP:
+ et = eval_lex (v1);
+ if (et == ERROR)
+ return UNKNOWN_INPUT;
+
+ if ((er = logical_or_term (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;
+
+ default:
+ return SYNTAX_ERROR;
+ }
+ return NO_ERROR;
+}
diff --git a/src/evalmp.c b/src/evalmp.c
new file mode 100644
index 00000000..5c48b8db
--- /dev/null
+++ b/src/evalmp.c
@@ -0,0 +1,27 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1998 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* This file is used to compile the gmp aware version of eval() */
+
+#include "m4.h"
+
+#ifdef WITH_GMP
+#define USE_GMP
+
+#include "eval.c"
+#endif
diff --git a/src/format.c b/src/format.c
new file mode 100644
index 00000000..f8107c05
--- /dev/null
+++ b/src/format.c
@@ -0,0 +1,744 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* printf like formatting for m4. */
+
+#include "m4.h"
+
+#ifdef HAVE_EFGCVT
+
+/* Various constants for floating point formatting. */
+#define MAXFIELD 128 /* size of buffer for formatted text */
+/* The following two are hardware dependant. */
+#define ECVTMAX 18 /* max number of significant digits for %e */
+#define FCVTMAX (18+38+4) /* max number of significant digits for %f */
+
+/* Externs used herein. */
+#if HAVE_EFGCVT <= 1
+extern char *ecvt (), *fcvt (), *gcvt ();
+#endif
+
+#ifndef STDC_HEADERS
+extern int atoi ();
+extern long atol ();
+extern double atof ();
+#endif /* STDC_HEADERS */
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+static char const digits[] = "0123456789abcdef";
+static char const Digits[] = "0123456789ABCDEF";
+
+/* STR has dimension MAXFIELD (?). */
+
+static char *
+ulong_to_str (register unsigned long val, char *str, int base,
+ const char *digits)
+{
+ register char *s = &str[MAXFIELD];
+
+ *--s = '\0';
+ do
+ {
+ *--s = digits[val % base];
+ val /= base;
+ }
+ while (val > 0);
+
+ return s;
+}
+
+/*-----------------------------------------.
+| Clear trailing zeroes, return argument. |
+`-----------------------------------------*/
+
+static char *
+clr0 (char *s)
+{
+ register char *t;
+
+ for (t = s + strlen (s); *--t == '0' && t > s;)
+ *t = '\0';
+ return s;
+}
+
+#endif /* HAVE_EFGCVT */
+
+/* Simple varargs substitute. */
+
+#define ARG_INT(argc, argv) \
+ ((argc == 0) ? 0 : \
+ (--argc, argv++, atoi (TOKEN_DATA_TEXT (argv[-1]))))
+
+#define ARG_UINT(argc, argv) \
+ ((argc == 0) ? 0 : \
+ (--argc, argv++, (unsigned int) atoi (TOKEN_DATA_TEXT (argv[-1]))))
+
+#define ARG_LONG(argc, argv) \
+ ((argc == 0) ? 0 : \
+ (--argc, argv++, atol (TOKEN_DATA_TEXT (argv[-1]))))
+
+#define ARG_ULONG(argc, argv) \
+ ((argc == 0) ? 0 : \
+ (--argc, argv++, (unsigned long) atol (TOKEN_DATA_TEXT (argv[-1]))))
+
+#define ARG_STR(argc, argv) \
+ ((argc == 0) ? "" : \
+ (--argc, argv++, TOKEN_DATA_TEXT (argv[-1])))
+
+#define ARG_DOUBLE(argc, argv) \
+ ((argc == 0) ? 0 : \
+ (--argc, argv++, atof (TOKEN_DATA_TEXT (argv[-1]))))
+
+
+/*------------------------------------------------------------------------.
+| 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. |
+`------------------------------------------------------------------------*/
+
+void
+format (struct obstack *obs, int argc, token_data **argv)
+{
+#ifdef HAVE_EFGCVT
+
+ const char *fmt; /* format control string */
+ int c; /* a simple character */
+ char fc; /* format code */
+
+ /* Flags. */
+ char flags; /* 1 iff treating flags */
+ char ljust; /* left justification */
+ char mandsign; /* mandatory sign */
+ char noplus; /* use space if no sign */
+ char alternate; /* use alternate form */
+ char zeropad; /* do zero padding */
+ char plus; /* plus-sign, according to mandatory and noplus */
+
+ /* Precision specifiers. */
+ int width; /* minimum field width */
+ int prec; /* precision */
+ int maxch; /* maximum no. of chars to print */
+ char lflag; /* long flag */
+ char hflag; /* short flag */
+
+ /* Different parts of each specification. */
+ char sign; /* wanted sign, iff any */
+ int ppad; /* pre-prefix zero padding */
+ const char *prefix; /* value prefix */
+ int lpad; /* zero padding on the left */
+ register char *s; /* ptr to formatted text */
+ int rpad; /* zero padding on the rigth*/
+ const char *suffix; /* value suffix */
+
+ /* Buffer and stuff. */
+ char str[MAXFIELD]; /* buffer for formatted text */
+ int length; /* length of str */
+ int padding; /* padding at the left or rigth */
+ register int i; /* an index */
+
+/* Length of trailing string in str. */
+#define LENGTH(s) (&str[MAXFIELD-1] - (s))
+#define HAS_SIGN (sign != '\0')
+
+ fmt = ARG_STR (argc, argv);
+ for (;;)
+ {
+ while ((c = *fmt++) != '%')
+ {
+ if (c == 0)
+ return;
+ obstack_1grow (obs, c);
+ }
+ if (*fmt == '%')
+ {
+ obstack_1grow (obs, '%');
+ fmt++;
+ continue;
+ }
+
+ /* Parse flags. */
+ flags = 1;
+ ljust = mandsign = noplus = alternate = zeropad = 0;
+ do
+ {
+ switch (*fmt)
+ {
+ case '-': /* left justification */
+ ljust = 1;
+ break;
+
+ case '+': /* mandatory sign */
+ mandsign = 1;
+ break;
+
+ case ' ': /* space instead of positive sign */
+ noplus = 1;
+ break;
+
+ case '0': /* zero padding */
+ zeropad = 1;
+ break;
+
+ case '#': /* alternate output */
+ alternate = 1;
+ break;
+
+ default:
+ flags = 0;
+ break;
+ }
+ }
+ while (flags && fmt++);
+
+ plus = '\0'; /* what to use as a plus ??? */
+ if (mandsign)
+ plus = '+';
+ else if (noplus)
+ plus = ' ';
+
+ if (ljust)
+ zeropad = 0;
+
+ /* Minimum field width. */
+ width = -1;
+ if (*fmt == '*')
+ {
+ width = ARG_INT (argc, argv);
+ fmt++;
+ }
+ else if (isdigit (*fmt))
+ {
+ width = 0;
+ do
+ {
+ width = width * 10 + *fmt++ - '0';
+ }
+ while (isdigit (*fmt));
+ }
+
+ /* Maximum precision. */
+ prec = -1;
+ if (*fmt == '.')
+ {
+ if (*(++fmt) == '*')
+ {
+ prec = ARG_INT (argc, argv);
+ ++fmt;
+ }
+ else if (isdigit (*fmt))
+ {
+ prec = 0;
+ do
+ {
+ prec = prec * 10 + *fmt++ - '0';
+ }
+ while (isdigit (*fmt))
+ ;
+ }
+ }
+
+ /* Length modifiers. */
+ lflag = (*fmt == 'l');
+ hflag = (*fmt == 'h');
+ if (lflag || hflag)
+ fmt++;
+
+ sign = '\0';
+ ppad = lpad = rpad = 0;
+ maxch = -1;
+ prefix = suffix = "";
+
+ switch (fc = *fmt++)
+ {
+
+ case '\0':
+ return;
+
+ case 'c':
+ c = ARG_INT (argc, argv);
+ str[0] = (unsigned char) c;
+ str[1] = '\0';
+ s = str;
+ break;
+
+ case 's':
+ s = ARG_STR (argc, argv);
+ maxch = prec;
+ break;
+
+ case 'd':
+ case 'i':
+ if (lflag)
+ {
+ long val = ARG_LONG (argc, argv);
+ if (val < 0)
+ {
+ val = -val; /* does not work for MINLONG */
+ sign = '-';
+ }
+ else
+ sign = plus;
+ s = ulong_to_str ((unsigned long) val, str, 10, digits);
+ }
+ else
+ {
+ int val = ARG_INT (argc, argv);
+ if (hflag)
+ val = (short) val;
+ if (val < 0)
+ {
+ val = -val; /* does not work for MININT */
+ sign = '-';
+ }
+ else
+ sign = plus;
+ s = ulong_to_str ((unsigned long) val, str, 10, digits);
+ }
+ if (zeropad)
+ lpad = width - LENGTH (s) - HAS_SIGN;
+ break;
+
+ case 'o':
+ if (lflag)
+ {
+ unsigned long val = ARG_ULONG (argc, argv);
+ s = ulong_to_str ((unsigned long) val, str, 8, digits);
+ }
+ else
+ {
+ unsigned int val = ARG_UINT (argc, argv);
+ if (hflag)
+ val = (unsigned short) val;
+ s = ulong_to_str ((unsigned long) val, str, 8, digits);
+ }
+ if (alternate)
+ prefix = "0";
+ if (zeropad)
+ lpad = width - LENGTH (s) - alternate;
+ break;
+
+ case 'x':
+ case 'X':
+ if (lflag)
+ {
+ unsigned long val = ARG_ULONG (argc, argv);
+ s = ulong_to_str ((unsigned long) val, str, 16,
+ (fc == 'x') ? digits : Digits);
+ }
+ else
+ {
+ unsigned int val = ARG_UINT (argc, argv);
+ if (hflag)
+ val = (unsigned short) val;
+ s = ulong_to_str ((unsigned long) val, str, 16,
+ (fc == 'x') ? digits : Digits);
+ }
+ if (alternate)
+ prefix = (fc == 'X') ? "0X" : "0x";
+ if (zeropad)
+ lpad = width - LENGTH (s) - 2*alternate;
+ break;
+
+ case 'u':
+ if (lflag)
+ {
+ unsigned long val = ARG_ULONG (argc, argv);
+ s = ulong_to_str ((unsigned long) val, str, 10, digits);
+ }
+ else
+ {
+ unsigned int val = ARG_UINT (argc, argv);
+ if (hflag)
+ val = (unsigned short) val;
+ s = ulong_to_str ((unsigned long) val, str, 10, digits);
+ }
+ if (zeropad)
+ lpad = width - LENGTH (s);
+ break;
+
+ case 'e':
+ case 'E':
+ {
+ char *t;
+ int sgn, decpt, exp, n;
+ double val = ARG_DOUBLE (argc, argv);
+
+ if (prec < 0)
+ prec = 6;
+ t = clr0 (ecvt (val, min (prec + 1, ECVTMAX), &decpt, &sgn));
+ sign = sgn ? '-' : plus;
+
+ n = prec;
+ s = str;
+ exp = (t[0] == '0' && t[1] == '\0') ? 0 : decpt - 1;
+
+ *s++ = *t++;
+ if (n > 0 || alternate)
+ *s++ = '.';
+ while (*t != '\0' && --n >= 0)
+ *s++ = *t++;
+ *s = '\0';
+ rpad = n;
+
+ sgn = 0;
+ if (exp < 0)
+ {
+ exp = -exp;
+ sgn = 1;
+ }
+ t = ulong_to_str ((unsigned long) exp, str, 10, digits);
+ if (exp < 10)
+ *--t = '0'; /* always at least two digits */
+ *--t = sgn ? '-' : '+';
+ *--t = fc;
+
+ if (zeropad)
+ {
+ lpad = width - HAS_SIGN - (s - str) - LENGTH (t);
+ if (rpad > 0)
+ lpad -= rpad;
+ }
+
+ suffix = t;
+ s = str;
+ }
+ break;
+
+ case 'f':
+ {
+ const char *t;
+ int sgn, decpt, n;
+ double val = ARG_DOUBLE (argc, argv);
+
+ if (prec < 0)
+ prec = 6;
+
+ /* FIXME: For the following line, Dave Anglin reports
+ ``warning: passing arg 1 of `clr0' discards `const' from
+ pointer target type''. I suspect fcvt might be declared
+ as returning const on some systems. Pouah! I should
+ revise this whole module, one of these days... */
+
+ t = clr0 (fcvt (val, min (prec, FCVTMAX), &decpt, &sgn));
+
+ sign = sgn ? '-' : plus;
+
+ n = prec;
+ s = str;
+
+ if (decpt <= 0)
+ {
+ prefix = (n > 0 || alternate) ? "0." : "0";
+ lpad = min (-decpt, prec);
+ n -= lpad;
+ }
+ else
+ {
+ while (--decpt >= 0)
+ *s++ = *t++;
+ if (n > 0 || alternate)
+ *s++ = '.';
+ }
+ while (*t && --n >= 0)
+ *s++ = *t++;
+
+ *s = '\0';
+ rpad = n;
+
+ if (zeropad)
+ ppad = width - HAS_SIGN - (prefix[1] ? 2 : 1) - lpad -
+ (s - str) - rpad;
+
+ s = str;
+ }
+ break;
+
+ default:
+ continue;
+ }
+
+ if (lpad < 0)
+ lpad = 0;
+ if (rpad < 0)
+ rpad = 0;
+ if (width < 0)
+ width = 0;
+
+ i = strlen (s);
+ if (maxch <= 0 || maxch > i)
+ maxch = i;
+
+ length = (HAS_SIGN + ppad + strlen (prefix) + lpad + maxch
+ + rpad + strlen (suffix));
+ padding = 0;
+ if (width != 0)
+ {
+ padding = width - length;
+ }
+
+ if (ljust == 0) /* left padding */
+ for (i = padding; --i >= 0;)
+ obstack_1grow (obs, ' ');
+ if (HAS_SIGN) /* sign */
+ obstack_1grow (obs, sign);
+ for (i = ppad; --i >= 0;) /* pre-prefix zero padding */
+ obstack_1grow (obs, '0');
+ for (; *prefix; ++prefix) /* prefix */
+ obstack_1grow (obs, *prefix);
+ for (i = lpad; --i >= 0;) /* left zero padding */
+ obstack_1grow (obs, '0');
+ for (i = maxch; --i >= 0; ++s) /* actual text */
+ obstack_1grow (obs, *s);
+ for (i = rpad; --i >= 0;) /* right zero padding */
+ obstack_1grow (obs, '0');
+ for (; *suffix; ++suffix) /* suffix */
+ obstack_1grow (obs, *suffix);
+ if (ljust != 0) /* right padding */
+ for (i = padding; --i >= 0;)
+ obstack_1grow (obs, ' ');
+ }
+
+#else /* not HAVE_EFGCVT */
+
+ char *fmt; /* format control string */
+ const char *fstart; /* beginning of current format spec */
+ int c; /* a simple character */
+
+ /* Flags. */
+ char flags; /* 1 iff treating flags */
+
+ /* Precision specifiers. */
+ int width; /* minimum field width */
+ int prec; /* precision */
+ char lflag; /* long flag */
+ char hflag; /* short flag */
+
+ /* Buffer and stuff. */
+ char str[256]; /* buffer for formatted text */
+ enum {INT, UINT, LONG, ULONG, DOUBLE, STR} datatype;
+
+ fmt = ARG_STR (argc, argv);
+ for (;;)
+ {
+ while ((c = *fmt++) != '%')
+ {
+ if (c == 0)
+ return;
+ obstack_1grow (obs, c);
+ }
+
+ fstart = fmt - 1;
+
+ if (*fmt == '%')
+ {
+ obstack_1grow (obs, '%');
+ fmt++;
+ continue;
+ }
+
+ /* Parse flags. */
+ flags = 1;
+ do
+ {
+ switch (*fmt)
+ {
+ case '-': /* left justification */
+ case '+': /* mandatory sign */
+ case ' ': /* space instead of positive sign */
+ case '0': /* zero padding */
+ case '#': /* alternate output */
+ break;
+
+ default:
+ flags = 0;
+ break;
+ }
+ }
+ while (flags && fmt++);
+
+ /* Minimum field width. */
+ width = -1;
+ if (*fmt == '*')
+ {
+ width = ARG_INT (argc, argv);
+ fmt++;
+ }
+ else if (isdigit (*fmt))
+ {
+ do
+ {
+ fmt++;
+ }
+ while (isdigit (*fmt));
+ }
+
+ /* Maximum precision. */
+ prec = -1;
+ if (*fmt == '.')
+ {
+ if (*(++fmt) == '*')
+ {
+ prec = ARG_INT (argc, argv);
+ ++fmt;
+ }
+ else if (isdigit (*fmt))
+ {
+ do
+ {
+ fmt++;
+ }
+ while (isdigit (*fmt));
+ }
+ }
+
+ /* Length modifiers. */
+ lflag = (*fmt == 'l');
+ hflag = (*fmt == 'h');
+ if (lflag || hflag)
+ fmt++;
+
+ switch (*fmt++)
+ {
+
+ case '\0':
+ return;
+
+ case 'c':
+ datatype = INT;
+ break;
+
+ case 's':
+ datatype = STR;
+ break;
+
+ case 'd':
+ case 'i':
+ if (lflag)
+ {
+ datatype = LONG;
+ }
+ else
+ {
+ datatype = INT;
+ }
+ break;
+
+ case 'o':
+ case 'x':
+ case 'X':
+ case 'u':
+ if (lflag)
+ {
+ datatype = ULONG;
+ }
+ else
+ {
+ datatype = UINT;
+ }
+ break;
+
+ case 'e':
+ case 'E':
+ case 'f':
+ datatype = DOUBLE;
+ break;
+
+ default:
+ continue;
+ }
+
+ c = *fmt;
+ *fmt = '\0';
+
+ switch(datatype)
+ {
+ case INT:
+ if (width != -1 && prec != -1)
+ sprintf (str, fstart, width, prec, ARG_INT(argc, argv));
+ else if (width != -1)
+ sprintf (str, fstart, width, ARG_INT(argc, argv));
+ else if (prec != -1)
+ sprintf (str, fstart, prec, ARG_INT(argc, argv));
+ else
+ sprintf (str, fstart, ARG_INT(argc, argv));
+ break;
+
+ case UINT:
+ if (width != -1 && prec != -1)
+ sprintf (str, fstart, width, prec, ARG_UINT(argc, argv));
+ else if (width != -1)
+ sprintf (str, fstart, width, ARG_UINT(argc, argv));
+ else if (prec != -1)
+ sprintf (str, fstart, prec, ARG_UINT(argc, argv));
+ else
+ sprintf (str, fstart, ARG_UINT(argc, argv));
+ break;
+
+ case LONG:
+ if (width != -1 && prec != -1)
+ sprintf (str, fstart, width, prec, ARG_LONG(argc, argv));
+ else if (width != -1)
+ sprintf (str, fstart, width, ARG_LONG(argc, argv));
+ else if (prec != -1)
+ sprintf (str, fstart, prec, ARG_LONG(argc, argv));
+ else
+ sprintf (str, fstart, ARG_LONG(argc, argv));
+ break;
+
+ case ULONG:
+ if (width != -1 && prec != -1)
+ sprintf (str, fstart, width, prec, ARG_ULONG(argc, argv));
+ else if (width != -1)
+ sprintf (str, fstart, width, ARG_ULONG(argc, argv));
+ else if (prec != -1)
+ sprintf (str, fstart, prec, ARG_ULONG(argc, argv));
+ else
+ sprintf (str, fstart, ARG_ULONG(argc, argv));
+ break;
+
+ case DOUBLE:
+ if (width != -1 && prec != -1)
+ sprintf (str, fstart, width, prec, ARG_DOUBLE(argc, argv));
+ else if (width != -1)
+ sprintf (str, fstart, width, ARG_DOUBLE(argc, argv));
+ else if (prec != -1)
+ sprintf (str, fstart, prec, ARG_DOUBLE(argc, argv));
+ else
+ sprintf (str, fstart, ARG_DOUBLE(argc, argv));
+ break;
+
+ case STR:
+ if (width != -1 && prec != -1)
+ sprintf (str, fstart, width, prec, ARG_STR(argc, argv));
+ else if (width != -1)
+ sprintf (str, fstart, width, ARG_STR(argc, argv));
+ else if (prec != -1)
+ sprintf (str, fstart, prec, ARG_STR(argc, argv));
+ else
+ sprintf (str, fstart, ARG_STR(argc, argv));
+ break;
+ }
+
+ *fmt = c;
+
+ obstack_grow (obs, str, strlen (str));
+ }
+
+#endif /* not HAVE_EFGCVT */
+}
diff --git a/src/freeze.c b/src/freeze.c
new file mode 100644
index 00000000..f17baff9
--- /dev/null
+++ b/src/freeze.c
@@ -0,0 +1,369 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* This module handles frozen files. */
+
+#include "m4.h"
+
+/*-------------------------------------------------------------------.
+| Destructively reverse a symbol list and return the reversed list. |
+`-------------------------------------------------------------------*/
+
+static symbol *
+reverse_symbol_list (symbol *sym)
+{
+ symbol *result;
+ symbol *next;
+
+ result = NULL;
+ while (sym)
+ {
+ next = SYMBOL_NEXT (sym);
+ SYMBOL_NEXT (sym) = result;
+ result = sym;
+ sym = next;
+ }
+ return result;
+}
+
+/*------------------------------------------------.
+| Produce a frozen state to the given file NAME. |
+`------------------------------------------------*/
+
+void
+produce_frozen_state (const char *name)
+{
+ FILE *file;
+ int h;
+ symbol *sym;
+ const builtin *bp;
+
+ if (file = fopen (name, "w"), !file)
+ {
+ M4ERROR ((warning_status, errno, name));
+ return;
+ }
+
+ /* Write a recognizable header. */
+
+ fprintf (file, "# This is a frozen state file generated by GNU %s %s\n",
+ PRODUCT, VERSION);
+ fprintf (file, "V1\n");
+
+ /* Dump quote delimiters. */
+
+ if (strcmp (lquote.string, DEF_LQUOTE) || strcmp (rquote.string, DEF_RQUOTE))
+ {
+ fprintf (file, "Q%d,%d\n", (int) lquote.length, (int) rquote.length);
+ fputs (lquote.string, file);
+ fputs (rquote.string, file);
+ fputc ('\n', file);
+ }
+
+ /* Dump comment delimiters. */
+
+ if (strcmp (bcomm.string, DEF_BCOMM) || strcmp (ecomm.string, DEF_ECOMM))
+ {
+ fprintf (file, "C%d,%d\n", (int) bcomm.length, (int) ecomm.length);
+ fputs (bcomm.string, file);
+ fputs (ecomm.string, file);
+ fputc ('\n', file);
+ }
+
+ /* Dump all symbols. */
+
+ for (h = 0; h < hash_table_size; h++)
+ {
+
+ /* 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. */
+
+ symtab[h] = reverse_symbol_list (symtab[h]);
+ for (sym = symtab[h]; sym; sym = SYMBOL_NEXT (sym))
+ {
+ switch (SYMBOL_TYPE (sym))
+ {
+ case TOKEN_TEXT:
+ fprintf (file, "T%d,%d\n",
+ (int) strlen (SYMBOL_NAME (sym)),
+ (int) strlen (SYMBOL_TEXT (sym)));
+ fputs (SYMBOL_NAME (sym), file);
+ fputs (SYMBOL_TEXT (sym), file);
+ fputc ('\n', file);
+ break;
+
+ case TOKEN_FUNC:
+ bp = find_builtin_by_addr (SYMBOL_FUNC (sym));
+ if (bp == NULL)
+ {
+ M4ERROR ((warning_status, 0, "\
+INTERNAL ERROR: Built-in not found in builtin table!"));
+ abort ();
+ }
+ fprintf (file, "F%d,%d\n",
+ (int) strlen (SYMBOL_NAME (sym)),
+ (int) strlen (bp->name));
+ fputs (SYMBOL_NAME (sym), file);
+ fputs (bp->name, file);
+ fputc ('\n', file);
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0, "\
+INTERNAL ERROR: Bad token data type in freeze_one_symbol ()"));
+ abort ();
+ break;
+ }
+ }
+
+ /* Reverse the bucket once more, putting it back as it was. */
+
+ symtab[h] = reverse_symbol_list (symtab[h]);
+ }
+
+ /* Let diversions be issued from output.c module, its cleaner to have this
+ piece of code there. */
+
+ freeze_diversions (file);
+
+ /* All done. */
+
+ fputs ("# End of frozen state file\n", file);
+ fclose (file);
+}
+
+/*----------------------------------------------------------------------.
+| Issue a message saying that some character is an EXPECTED character. |
+`----------------------------------------------------------------------*/
+
+static void
+issue_expect_message (int expected)
+{
+ if (expected == '\n')
+ M4ERROR ((EXIT_FAILURE, 0, "Expecting line feed in frozen file"));
+ else
+ M4ERROR ((EXIT_FAILURE, 0, "Expecting character `%c' in frozen file",
+ expected));
+}
+
+/*-------------------------------------------------.
+| Reload a frozen state from the given file NAME. |
+`-------------------------------------------------*/
+
+/* We are seeking speed, here. */
+
+void
+reload_frozen_state (const char *name)
+{
+ FILE *file;
+ int character;
+ int operation;
+ char *string[2];
+ int allocated[2];
+ int number[2];
+ const builtin *bp;
+
+#define GET_CHARACTER \
+ (character = getc (file))
+
+#define GET_NUMBER(Number) \
+ do \
+ { \
+ (Number) = 0; \
+ while (isdigit (character)) \
+ { \
+ (Number) = 10 * (Number) + character - '0'; \
+ GET_CHARACTER; \
+ } \
+ } \
+ while (0)
+
+#define VALIDATE(Expected) \
+ do \
+ { \
+ if (character != (Expected)) \
+ issue_expect_message ((Expected)); \
+ } \
+ while (0)
+
+ file = path_search (name);
+ if (file == NULL)
+ M4ERROR ((EXIT_FAILURE, errno, "Cannot open %s", name));
+
+ allocated[0] = 100;
+ string[0] = xmalloc ((size_t) allocated[0]);
+ allocated[1] = 100;
+ string[1] = xmalloc ((size_t) allocated[1]);
+
+ while (GET_CHARACTER, character != EOF)
+ switch (character)
+ {
+ default:
+ M4ERROR ((EXIT_FAILURE, 0, "Ill-formated frozen file"));
+
+ case '\n':
+
+ /* Skip empty lines. */
+
+ break;
+
+ case '#':
+
+ /* Comments are introduced by `#' at beginning of line, and are
+ ignored. */
+
+ while (character != EOF && character != '\n')
+ GET_CHARACTER;
+ VALIDATE ('\n');
+ break;
+
+ case 'C':
+ case 'D':
+ case 'F':
+ case 'T':
+ case 'Q':
+ operation = character;
+ GET_CHARACTER;
+
+ /* Get string lengths. Accept a negative diversion number. */
+
+ if (operation == 'D' && character == '-')
+ {
+ GET_CHARACTER;
+ GET_NUMBER (number[0]);
+ number[0] = -number[0];
+ }
+ else
+ GET_NUMBER (number[0]);
+ VALIDATE (',');
+ GET_CHARACTER;
+ GET_NUMBER (number[1]);
+ VALIDATE ('\n');
+
+ if (operation != 'D')
+ {
+
+ /* Get first string contents. */
+
+ if (number[0] + 1 > allocated[0])
+ {
+ free (string[0]);
+ allocated[0] = number[0] + 1;
+ string[0] = xmalloc ((size_t) allocated[0]);
+ }
+
+ if (number[0] > 0)
+ if (!fread (string[0], (size_t) number[0], 1, file))
+ M4ERROR ((EXIT_FAILURE, 0, "Premature end of frozen file"));
+
+ string[0][number[0]] = '\0';
+ }
+
+ /* Get second string contents. */
+
+ if (number[1] + 1 > allocated[1])
+ {
+ free (string[1]);
+ allocated[1] = number[1] + 1;
+ string[1] = xmalloc ((size_t) allocated[1]);
+ }
+
+ if (number[1] > 0)
+ if (!fread (string[1], (size_t) number[1], 1, file))
+ M4ERROR ((EXIT_FAILURE, 0, "Premature end of frozen file"));
+
+ string[1][number[1]] = '\0';
+ GET_CHARACTER;
+ VALIDATE ('\n');
+
+ /* Act according to operation letter. */
+
+ switch (operation)
+ {
+ case 'C':
+
+ /* Change comment strings. */
+
+ set_comment (string[0], string[1]);
+ break;
+
+ case 'D':
+
+ /* Select a diversion and add a string to it. */
+
+ make_diversion (number[0]);
+ if (number[1] > 0)
+ shipout_text (NULL, string[1], number[1]);
+ break;
+
+ case 'F':
+
+ /* Enter a macro having a builtin function as a definition. */
+
+ bp = find_builtin_by_name (string[1]);
+ if (bp)
+ define_builtin (string[0], bp, SYMBOL_PUSHDEF, 0);
+ else
+ M4ERROR ((warning_status, 0, "\
+`%s' from frozen file not found in builtin table!",
+ string[0]));
+ break;
+
+ case 'T':
+
+ /* Enter a macro having an expansion text as a definition. */
+
+ define_user_macro (string[0], string[1], SYMBOL_PUSHDEF);
+ break;
+
+ case 'Q':
+
+ /* Change quote strings. */
+
+ set_quotes (string[0], string[1]);
+ break;
+
+ default:
+
+ /* Cannot happen. */
+
+ break;
+ }
+ break;
+
+ case 'V':
+
+ /* Validate format version. Only `1' is acceptable for now. */
+
+ GET_CHARACTER;
+ VALIDATE ('1');
+ GET_CHARACTER;
+ VALIDATE ('\n');
+ break;
+
+ }
+
+ free (string[0]);
+ free (string[1]);
+ fclose (file);
+
+#undef GET_CHARACTER
+#undef GET_NUMBER
+#undef VALIDATE
+}
diff --git a/src/getopt.c b/src/getopt.c
new file mode 100644
index 00000000..efd82235
--- /dev/null
+++ b/src/getopt.c
@@ -0,0 +1,1051 @@
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+
+ Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
+ Free Software Foundation, Inc.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+# ifndef const
+# define const
+# endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include <gnu-versions.h>
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include <stdlib.h>
+# include <unistd.h>
+#endif /* GNU C library. */
+
+#ifdef VMS
+# include <unixlib.h>
+# if HAVE_STRING_H - 0
+# include <string.h>
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.
+ When compiling libc, the _ macro is predefined. */
+# ifdef HAVE_LIBINTL_H
+# include <libintl.h>
+# define _(msgid) gettext (msgid)
+# else
+# define _(msgid) (msgid)
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include <string.h>
+# define my_index strchr
+#else
+
+# if HAVE_STRING_H
+# include <string.h>
+# else
+# include <strings.h>
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+
+static int original_argc;
+static char *const *original_argv;
+
+/* Make sure the environment variable bash 2.0 puts in the environment
+ is valid for the getopt call we must make sure that the ARGV passed
+ to getopt is that one passed to the process. */
+static void
+__attribute__ ((unused))
+store_args_and_env (int argc, char *const *argv)
+{
+ /* XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+ original_argc = argc;
+ original_argv = argv;
+}
+# ifdef text_set_element
+text_set_element (__libc_subinit, store_args_and_env);
+# endif /* text_set_element */
+
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#ifdef _LIBC
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#ifdef _LIBC
+ if (posixly_correct == NULL
+ && argc == original_argc && argv == original_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ optarg = NULL;
+
+ if (optind == 0 || !__getopt_initialized)
+ {
+ if (optind == 0)
+ optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#ifdef _LIBC
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > optind)
+ last_nonopt = optind;
+ if (first_nonopt > optind)
+ first_nonopt = optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc && NONOPTION_P)
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ {
+ if (argv[optind - 1][1] == '-')
+ /* --option */
+ fprintf (stderr,
+ _("%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+ else
+ /* +option or -option */
+ fprintf (stderr,
+ _("%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+ }
+
+ nextchar += strlen (nextchar);
+
+ optopt = pfound->val;
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (opterr)
+ {
+ if (argv[optind][1] == '-')
+ /* --option */
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+ else
+ /* +option or -option */
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+ }
+ nextchar = (char *) "";
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (opterr)
+ {
+ if (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+ else
+ fprintf (stderr, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (opterr)
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (opterr)
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (opterr)
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (opterr)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/src/getopt.h b/src/getopt.h
new file mode 100644
index 00000000..12b7ad56
--- /dev/null
+++ b/src/getopt.h
@@ -0,0 +1,180 @@
+/* Declarations for getopt.
+ Copyright (C) 1989,90,91,92,93,94,96,97,98,99 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+ standalone, or this is the first header included in the source file.
+ If we are being used with glibc, we need to include <features.h>, but
+ that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
+ not defined, include <ctype.h>, which will pull in <features.h> for us
+ if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
+ doesn't flood the namespace with stuff the way some other headers do.) */
+#if !defined __GNU_LIBRARY__
+# include <ctype.h>
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+# if defined __STDC__ && __STDC__
+ const char *name;
+# else
+ char *name;
+# endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+#if defined __STDC__ && __STDC__
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int __argc, char *const *__argv, const char *__shortopts);
+# else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+extern int getopt_long_only (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int __argc, char *const *__argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only);
+# endif
+#else /* not __STDC__ */
+extern int getopt ();
+# ifndef __need_getopt
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations. */
+#undef __need_getopt
+
+#endif /* getopt.h */
diff --git a/src/getopt1.c b/src/getopt1.c
new file mode 100644
index 00000000..3d264f2d
--- /dev/null
+++ b/src/getopt1.c
@@ -0,0 +1,188 @@
+/* getopt_long and getopt_long_only entry points for GNU getopt.
+ Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "getopt.h"
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+#include <gnu-versions.h>
+#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+#define ELIDE_CODE
+#endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+#include <stdlib.h>
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+int
+getopt_long (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+}
+
+/* Like getopt_long, but '-' as well as '--' can indicate a long option.
+ If an option that starts with '-' (not '--') doesn't match a long option,
+ but does match a short option, it is parsed as a short option
+ instead. */
+
+int
+getopt_long_only (argc, argv, options, long_options, opt_index)
+ int argc;
+ char *const *argv;
+ const char *options;
+ const struct option *long_options;
+ int *opt_index;
+{
+ return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+}
+
+
+#endif /* Not ELIDE_CODE. */
+
+#ifdef TEST
+
+#include <stdio.h>
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+ int option_index = 0;
+ static struct option long_options[] =
+ {
+ {"add", 1, 0, 0},
+ {"append", 0, 0, 0},
+ {"delete", 1, 0, 0},
+ {"verbose", 0, 0, 0},
+ {"create", 0, 0, 0},
+ {"file", 1, 0, 0},
+ {0, 0, 0, 0}
+ };
+
+ c = getopt_long (argc, argv, "abc:d:0123456789",
+ long_options, &option_index);
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case 0:
+ printf ("option %s", long_options[option_index].name);
+ if (optarg)
+ printf (" with arg %s", optarg);
+ printf ("\n");
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case 'd':
+ printf ("option d with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff --git a/src/input.c b/src/input.c
new file mode 100644
index 00000000..8916fd3f
--- /dev/null
+++ b/src/input.c
@@ -0,0 +1,852 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* Handling of different input sources, and lexical analysis. */
+
+#include "m4.h"
+
+/* Unread input can be either files, that should be read (eg. included
+ files), strings, which should be rescanned (eg. macro expansion text),
+ or quoted macro definitions (as returned by the builtin "defn").
+ Unread input are organised in a stack, implemented with an obstack.
+ Each input source is described by a "struct input_block". The obstack
+ is "input_stack". The top of the input stack is "isp".
+
+ 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 "input_stack" is empty), input is switched
+ over to "wrapup_stack". To make this easier, all references to the
+ current input stack, whether it be "input_stack" or "wrapup_stack",
+ are done through a pointer "current_input", which points to either
+ "input_stack" or "wrapup_stack".
+
+ Pushing new input on the input stack is done by push_file (),
+ push_string (), push_wrapup () (for wrapup text), and push_macro ()
+ (for macro definitions). Because macro expansion needs direct access
+ to the current input obstack (for optimisation), push_string () are
+ split in two functions, push_string_init (), which returns a pointer
+ to the current input stack, and push_string_finish (), which return a
+ pointer to the final text. The input_block *next is used to manage
+ the coordination between the different push routines.
+
+ The current file and line number are stored in two global variables,
+ for use by the error handling functions in m4.c. Whenever a file
+ input_block is pushed, the current file name and line number is saved
+ in the input_block, and the two variables are reset to match the new
+ input file. */
+
+#ifdef ENABLE_CHANGEWORD
+#include "regex.h"
+#endif
+
+enum input_type
+{
+ INPUT_FILE,
+ INPUT_STRING,
+ INPUT_MACRO
+};
+
+typedef enum input_type input_type;
+
+struct input_block
+{
+ struct input_block *prev; /* previous input_block on the input stack */
+ input_type type; /* INPUT_FILE, INPUT_STRING or INPUT_MACRO */
+ union
+ {
+ struct
+ {
+ char *string; /* string value */
+ }
+ u_s;
+ struct
+ {
+ FILE *file; /* input file handle */
+ const char *name; /* name of PREVIOUS input file */
+ int lineno; /* current line number for do */
+ /* Yet another attack of "The curse of global variables" (sic) */
+ int out_lineno; /* current output line number do */
+ boolean advance_line; /* start_of_input_line from next_char () */
+ }
+ u_f;
+ struct
+ {
+ builtin_func *func; /* pointer to macros function */
+ boolean traced; /* TRUE iff builtin is traced */
+ }
+ u_m;
+ }
+ u;
+};
+
+typedef struct input_block input_block;
+
+
+/* Current input file name. */
+const char *current_file;
+
+/* Current input line number. */
+int current_line;
+
+/* Obstack for storing individual tokens. */
+static struct obstack token_stack;
+
+/* Normal input stack. */
+static struct obstack input_stack;
+
+/* Wrapup input stack. */
+static struct obstack wrapup_stack;
+
+/* Input or wrapup. */
+static struct obstack *current_input;
+
+/* Bottom of token_stack, for obstack_free. */
+static char *token_bottom;
+
+/* Pointer to top of current_input. */
+static input_block *isp;
+
+/* Pointer to top of wrapup_stack. */
+static input_block *wsp;
+
+/* Aux. for handling split push_string (). */
+static input_block *next;
+
+/* Flag for next_char () to increment current_line. */
+static boolean start_of_input_line;
+
+#define CHAR_EOF 256 /* character return on EOF */
+#define CHAR_MACRO 257 /* character return for MACRO token */
+
+/* Quote chars. */
+STRING rquote;
+STRING lquote;
+
+/* Comment chars. */
+STRING bcomm;
+STRING ecomm;
+
+#ifdef ENABLE_CHANGEWORD
+
+#define DEFAULT_WORD_REGEXP "[_a-zA-Z][_a-zA-Z0-9]*"
+
+static char *word_start;
+static struct re_pattern_buffer word_regexp;
+static int default_word_regexp;
+static struct re_registers regs;
+
+#endif /* ENABLE_CHANGEWORD */
+
+
+/*-------------------------------------------------------------------------.
+| push_file () pushes an input file on the input stack, saving the current |
+| file name and line number. If next is non-NULL, this push invalidates a |
+| call to push_string_init (), whose storage are consequentely released. |
+`-------------------------------------------------------------------------*/
+
+void
+push_file (FILE *fp, const char *title)
+{
+ input_block *i;
+
+ if (next != NULL)
+ {
+ obstack_free (current_input, next);
+ next = NULL;
+ }
+
+ if (debug_level & DEBUG_TRACE_INPUT)
+ DEBUG_MESSAGE1 ("input read from %s", title);
+
+ i = (input_block *) obstack_alloc (current_input,
+ sizeof (struct input_block));
+ i->type = INPUT_FILE;
+
+ i->u.u_f.name = current_file;
+ i->u.u_f.lineno = current_line;
+ i->u.u_f.out_lineno = output_current_line;
+ i->u.u_f.advance_line = start_of_input_line;
+ current_file = obstack_copy0 (current_input, title, strlen (title));
+ current_line = 1;
+ output_current_line = -1;
+
+ i->u.u_f.file = fp;
+ i->prev = isp;
+ isp = i;
+}
+
+/*-------------------------------------------------------------------------.
+| push_macro () pushes a builtin macros definition on the input stack. If |
+| next is non-NULL, this push invalidates a call to push_string_init (), |
+| whose storage are consequentely released. |
+`-------------------------------------------------------------------------*/
+
+void
+push_macro (builtin_func *func, boolean traced)
+{
+ input_block *i;
+
+ if (next != NULL)
+ {
+ obstack_free (current_input, next);
+ next = NULL;
+ }
+
+ i = (input_block *) obstack_alloc (current_input,
+ sizeof (struct input_block));
+ i->type = INPUT_MACRO;
+
+ i->u.u_m.func = func;
+ i->u.u_m.traced = traced;
+ i->prev = isp;
+ isp = i;
+}
+
+/*------------------------------------------------------------------.
+| First half of push_string (). The pointer next points to the new |
+| input_block. |
+`------------------------------------------------------------------*/
+
+struct obstack *
+push_string_init (void)
+{
+ if (next != NULL)
+ {
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Recursive push_string!"));
+ abort ();
+ }
+
+ next = (input_block *) obstack_alloc (current_input,
+ sizeof (struct input_block));
+ next->type = INPUT_STRING;
+ return current_input;
+}
+
+/*------------------------------------------------------------------------.
+| Last half of push_string (). If next is now NULL, a call to push_file |
+| () has invalidated the previous call to push_string_init (), so we just |
+| give up. If the new object is void, we do not push it. The function |
+| push_string_finish () returns a pointer to the finished object. This |
+| pointer is only for temporary use, since reading the next token might |
+| release the memory used for the object. |
+`------------------------------------------------------------------------*/
+
+const char *
+push_string_finish (void)
+{
+ const char *ret = NULL;
+
+ if (next == NULL)
+ return NULL;
+
+ if (obstack_object_size (current_input) > 0)
+ {
+ obstack_1grow (current_input, '\0');
+ next->u.u_s.string = obstack_finish (current_input);
+ next->prev = isp;
+ isp = next;
+ ret = isp->u.u_s.string; /* for immediate use only */
+ }
+ else
+ obstack_free (current_input, next); /* people might leave garbage on it. */
+ next = NULL;
+ return ret;
+}
+
+/*--------------------------------------------------------------------------.
+| The function push_wrapup () pushes a string on the wrapup stack. When |
+| he normal input stack gets empty, the wrapup stack will become the input |
+| stack, and push_string () and push_file () will operate on wrapup_stack. |
+| Push_wrapup should be done as push_string (), but this will suffice, as |
+| long as arguments to m4_m4wrap () are moderate in size. |
+`--------------------------------------------------------------------------*/
+
+void
+push_wrapup (const char *s)
+{
+ input_block *i = (input_block *) obstack_alloc (&wrapup_stack,
+ sizeof (struct input_block));
+ i->prev = wsp;
+ i->type = INPUT_STRING;
+ i->u.u_s.string = obstack_copy0 (&wrapup_stack, s, strlen (s));
+ wsp = i;
+}
+
+
+/*-------------------------------------------------------------------------.
+| The function pop_input () pops one level of input sources. If the |
+| popped input_block is a file, current_file and current_line are reset to |
+| the saved values before the memory for the input_block are released. |
+`-------------------------------------------------------------------------*/
+
+static void
+pop_input (void)
+{
+ input_block *tmp = isp->prev;
+
+ switch (isp->type)
+ {
+ case INPUT_STRING:
+ case INPUT_MACRO:
+ break;
+
+ case INPUT_FILE:
+ if (debug_level & DEBUG_TRACE_INPUT)
+ DEBUG_MESSAGE2 ("input reverted to %s, line %d",
+ isp->u.u_f.name, isp->u.u_f.lineno);
+
+ fclose (isp->u.u_f.file);
+ current_file = isp->u.u_f.name;
+ current_line = isp->u.u_f.lineno;
+ output_current_line = isp->u.u_f.out_lineno;
+ start_of_input_line = isp->u.u_f.advance_line;
+ if (tmp != NULL)
+ output_current_line = -1;
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Input stack botch in pop_input ()"));
+ abort ();
+ }
+ obstack_free (current_input, isp);
+ next = NULL; /* might be set in push_string_init () */
+
+ isp = tmp;
+}
+
+/*------------------------------------------------------------------------.
+| To switch input over to the wrapup stack, main () calls pop_wrapup (). |
+| Since wrapup text can install new wrapup text, pop_wrapup () returns |
+| FALSE when there is no wrapup text on the stack, and TRUE otherwise. |
+`------------------------------------------------------------------------*/
+
+boolean
+pop_wrapup (void)
+{
+ if (wsp == NULL)
+ return FALSE;
+
+ current_input = &wrapup_stack;
+ isp = wsp;
+ wsp = NULL;
+
+ return TRUE;
+}
+
+/*--------------------------------------------------------------------.
+| When a MACRO token is seen, next_token () uses init_macro_token () to |
+| retrieve the value of the function pointer. |
+`--------------------------------------------------------------------*/
+
+static void
+init_macro_token (token_data *td)
+{
+ if (isp->type != INPUT_MACRO)
+ {
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad call to init_macro_token ()"));
+ abort ();
+ }
+
+ TOKEN_DATA_TYPE (td) = TOKEN_FUNC;
+ TOKEN_DATA_FUNC (td) = isp->u.u_m.func;
+ TOKEN_DATA_FUNC_TRACED (td) = isp->u.u_m.traced;
+}
+
+
+/*------------------------------------------------------------------------.
+| Low level input is done a character at a time. The function peek_input |
+| () 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. |
+`------------------------------------------------------------------------*/
+
+int
+peek_input (void)
+{
+ register int ch;
+
+ while (1)
+ {
+ if (isp == NULL)
+ return CHAR_EOF;
+
+ switch (isp->type)
+ {
+ case INPUT_STRING:
+ ch = isp->u.u_s.string[0];
+ if (ch != '\0')
+ return ch;
+ break;
+
+ case INPUT_FILE:
+ ch = getc (isp->u.u_f.file);
+ if (ch != EOF)
+ {
+ ungetc (ch, isp->u.u_f.file);
+ return ch;
+ }
+ break;
+
+ case INPUT_MACRO:
+ return CHAR_MACRO;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Input stack botch in peek_input ()"));
+ abort ();
+ }
+ /* End of input source --- pop one level. */
+ pop_input ();
+ }
+}
+
+/*-------------------------------------------------------------------------.
+| The function next_char () is used to read and advance the input to the |
+| next character. It also 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. |
+`-------------------------------------------------------------------------*/
+
+static int
+next_char (void)
+{
+ register int ch;
+
+ if (start_of_input_line)
+ {
+ start_of_input_line = FALSE;
+ current_line++;
+ }
+
+ while (1)
+ {
+ if (isp == NULL)
+ return CHAR_EOF;
+
+ switch (isp->type)
+ {
+ case INPUT_STRING:
+ ch = *isp->u.u_s.string++;
+ if (ch != '\0')
+ return ch;
+ break;
+
+ case INPUT_FILE:
+ ch = getc (isp->u.u_f.file);
+ if (ch != EOF)
+ {
+ if (ch == '\n')
+ start_of_input_line = TRUE;
+ return ch;
+ }
+ break;
+
+ case INPUT_MACRO:
+ pop_input (); /* INPUT_MACRO input sources has only one
+ token */
+ return CHAR_MACRO;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Input stack botch in next_char ()"));
+ abort ();
+ }
+
+ /* End of input source --- pop one level. */
+ pop_input ();
+ }
+}
+
+/*------------------------------------------------------------------------.
+| skip_line () simply discards all immediately following characters, upto |
+| the first newline. It is only used from m4_dnl (). |
+`------------------------------------------------------------------------*/
+
+void
+skip_line (void)
+{
+ int ch;
+
+ while ((ch = next_char ()) != CHAR_EOF && ch != '\n')
+ ;
+}
+
+
+/*----------------------------------------------------------------------.
+| This function is for matching a string against a prefix of the input |
+| stream. If the string matches the input, the input is discarded, |
+| otherwise the characters read are pushed back again. The function is |
+| used only when multicharacter quotes or comment delimiters are used. |
+`----------------------------------------------------------------------*/
+
+static int
+match_input (const char *s)
+{
+ int n; /* number of characters matched */
+ int ch; /* input character */
+ const char *t;
+
+ ch = peek_input ();
+ if (ch != *s)
+ return 0; /* fail */
+ (void) next_char ();
+
+ if (s[1] == '\0')
+ return 1; /* short match */
+
+ for (n = 1, t = s++; (ch = peek_input ()) == *s++; n++)
+ {
+ (void) next_char ();
+ if (*s == '\0') /* long match */
+ return 1;
+ }
+
+ /* Failed, push back input. */
+ obstack_grow (push_string_init (), t, n);
+ push_string_finish ();
+ return 0;
+}
+
+/*------------------------------------------------------------------------.
+| The macro MATCH() is used to match a string against the input. The |
+| first character is handled inline, for speed. Hopefully, this will not |
+| hurt efficiency too much when single character quotes and comment |
+| delimiters are used. |
+`------------------------------------------------------------------------*/
+
+#define MATCH(ch, s) \
+ ((s)[0] == (ch) \
+ && (ch) != '\0' \
+ && ((s)[1] == '\0' \
+ || (match_input ((s) + 1) ? (ch) = peek_input (), 1 : 0)))
+
+
+/*----------------------------------------------------------.
+| Inititialise input stacks, and quote/comment characters. |
+`----------------------------------------------------------*/
+
+void
+input_init (void)
+{
+ current_file = "NONE";
+ current_line = 0;
+
+ obstack_init (&token_stack);
+ obstack_init (&input_stack);
+ obstack_init (&wrapup_stack);
+
+ current_input = &input_stack;
+
+ obstack_1grow (&token_stack, '\0');
+ token_bottom = obstack_finish (&token_stack);
+
+ isp = NULL;
+ wsp = NULL;
+ next = NULL;
+
+ start_of_input_line = FALSE;
+
+ lquote.string = xstrdup (DEF_LQUOTE);
+ lquote.length = strlen (lquote.string);
+ rquote.string = xstrdup (DEF_RQUOTE);
+ rquote.length = strlen (rquote.string);
+ bcomm.string = xstrdup (DEF_BCOMM);
+ bcomm.length = strlen (bcomm.string);
+ ecomm.string = xstrdup (DEF_ECOMM);
+ ecomm.length = strlen (ecomm.string);
+
+#ifdef ENABLE_CHANGEWORD
+ if (user_word_regexp)
+ set_word_regexp (user_word_regexp);
+ else
+ set_word_regexp (DEFAULT_WORD_REGEXP);
+#endif
+}
+
+
+/*--------------------------------------------------------------.
+| Functions for setting quotes and comment delimiters. Used by |
+| m4_changecom () and m4_changequote (). |
+`--------------------------------------------------------------*/
+
+void
+set_quotes (const char *lq, const char *rq)
+{
+ xfree (lquote.string);
+ xfree (rquote.string);
+
+ lquote.string = xstrdup (lq ? lq : DEF_LQUOTE);
+ lquote.length = strlen (lquote.string);
+ rquote.string = xstrdup (rq ? rq : DEF_RQUOTE);
+ rquote.length = strlen (rquote.string);
+}
+
+void
+set_comment (const char *bc, const char *ec)
+{
+ xfree (bcomm.string);
+ xfree (ecomm.string);
+
+ bcomm.string = xstrdup (bc ? bc : DEF_BCOMM);
+ bcomm.length = strlen (bcomm.string);
+ ecomm.string = xstrdup (ec ? ec : DEF_ECOMM);
+ ecomm.length = strlen (ecomm.string);
+}
+
+#ifdef ENABLE_CHANGEWORD
+
+void
+set_word_regexp (const char *regexp)
+{
+ int i;
+ char test[2];
+ const char *msg;
+
+ if (!strcmp (regexp, DEFAULT_WORD_REGEXP))
+ {
+ default_word_regexp = TRUE;
+ return;
+ }
+
+ default_word_regexp = FALSE;
+
+ msg = re_compile_pattern (regexp, strlen (regexp), &word_regexp);
+
+ if (msg != NULL)
+ {
+ M4ERROR ((warning_status, 0,
+ "Bad regular expression `%s': %s", regexp, msg));
+ return;
+ }
+
+ if (word_start == NULL)
+ word_start = xmalloc (256);
+
+ word_start[0] = '\0';
+ test[1] = '\0';
+ for (i = 1; i < 256; i++)
+ {
+ test[0] = i;
+ if (re_search (&word_regexp, test, 1, 0, 0, &regs) >= 0)
+ strcat (word_start, test);
+ }
+}
+
+#endif /* ENABLE_CHANGEWORD */
+
+
+/*-------------------------------------------------------------------------.
+| Parse and return a single token from the input stream. A token can |
+| either be TOKEN_EOF, if the input_stack is empty; it can be TOKEN_STRING |
+| for a quoted string; TOKEN_WORD for something that is a potential macro |
+| name; and TOKEN_SIMPLE for any single character that is not a part of |
+| any of the previous types. |
+| |
+| Next_token () return the token type, and passes back a pointer to the |
+| token data through TD. 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 TD is therefore subject to |
+| change the next time next_token () is called. |
+`-------------------------------------------------------------------------*/
+
+token_type
+next_token (token_data *td)
+{
+ int ch;
+ int quote_level;
+ token_type type;
+#ifdef ENABLE_CHANGEWORD
+ int startpos;
+ char *orig_text = 0;
+#endif
+
+ obstack_free (&token_stack, token_bottom);
+ obstack_1grow (&token_stack, '\0');
+ token_bottom = obstack_finish (&token_stack);
+
+ ch = peek_input ();
+ if (ch == CHAR_EOF)
+ {
+ return TOKEN_EOF;
+#ifdef DEBUG_INPUT
+ fprintf (stderr, "next_token -> EOF\n");
+#endif
+ }
+ if (ch == CHAR_MACRO)
+ {
+ init_macro_token (td);
+ (void) next_char ();
+ return TOKEN_MACDEF;
+ }
+
+ (void) next_char ();
+ if (MATCH (ch, bcomm.string))
+ {
+ obstack_grow (&token_stack, bcomm.string, bcomm.length);
+ while ((ch = next_char ()) != CHAR_EOF && !MATCH (ch, ecomm.string))
+ obstack_1grow (&token_stack, ch);
+ if (ch != CHAR_EOF)
+ obstack_grow (&token_stack, ecomm.string, ecomm.length);
+ type = TOKEN_STRING;
+ }
+#ifdef ENABLE_CHANGEWORD
+ else if (default_word_regexp && (isalpha (ch) || ch == '_'))
+#else
+ else if (isalpha (ch) || ch == '_')
+#endif
+ {
+ obstack_1grow (&token_stack, ch);
+ while ((ch = peek_input ()) != CHAR_EOF && (isalnum (ch) || ch == '_'))
+ {
+ obstack_1grow (&token_stack, ch);
+ (void) next_char ();
+ }
+ type = TOKEN_WORD;
+ }
+
+#ifdef ENABLE_CHANGEWORD
+
+ else if (!default_word_regexp && strchr (word_start, ch))
+ {
+ obstack_1grow (&token_stack, ch);
+ while (1)
+ {
+ ch = peek_input ();
+ if (ch == CHAR_EOF)
+ break;
+ obstack_1grow (&token_stack, ch);
+ startpos = re_search (&word_regexp, obstack_base (&token_stack),
+ obstack_object_size (&token_stack), 0, 0,
+ &regs);
+ if (startpos != 0 ||
+ regs.end [0] != obstack_object_size (&token_stack))
+ {
+ *(((char *) obstack_base (&token_stack)
+ + obstack_object_size (&token_stack)) - 1) = '\0';
+ break;
+ }
+ next_char ();
+ }
+
+ obstack_1grow (&token_stack, '\0');
+ orig_text = obstack_finish (&token_stack);
+
+ if (regs.start[1] != -1)
+ obstack_grow (&token_stack,orig_text + regs.start[1],
+ regs.end[1] - regs.start[1]);
+ else
+ obstack_grow (&token_stack, orig_text,regs.end[0]);
+
+ type = TOKEN_WORD;
+ }
+
+#endif /* ENABLE_CHANGEWORD */
+
+ else if (!MATCH (ch, lquote.string))
+ {
+ type = TOKEN_SIMPLE;
+ obstack_1grow (&token_stack, ch);
+ }
+ else
+ {
+ quote_level = 1;
+ while (1)
+ {
+ ch = next_char ();
+ if (ch == CHAR_EOF)
+ M4ERROR ((EXIT_FAILURE, 0,
+ "ERROR: EOF in string"));
+
+ if (MATCH (ch, rquote.string))
+ {
+ if (--quote_level == 0)
+ break;
+ obstack_grow (&token_stack, rquote.string, rquote.length);
+ }
+ else if (MATCH (ch, lquote.string))
+ {
+ quote_level++;
+ obstack_grow (&token_stack, lquote.string, lquote.length);
+ }
+ else
+ obstack_1grow (&token_stack, ch);
+ }
+ type = TOKEN_STRING;
+ }
+
+ obstack_1grow (&token_stack, '\0');
+
+ TOKEN_DATA_TYPE (td) = TOKEN_TEXT;
+ TOKEN_DATA_TEXT (td) = obstack_finish (&token_stack);
+#ifdef ENABLE_CHANGEWORD
+ if (orig_text == NULL)
+ orig_text = TOKEN_DATA_TEXT (td);
+ TOKEN_DATA_ORIG_TEXT (td) = orig_text;
+#endif
+#ifdef DEBUG_INPUT
+ fprintf (stderr, "next_token -> %d (%s)\n", type, TOKEN_DATA_TEXT (td));
+#endif
+ return type;
+}
+
+
+#ifdef DEBUG_INPUT
+
+static void
+print_token (const char *s, token_type t, token_data *td)
+{
+ fprintf (stderr, "%s: ", s);
+ switch (t)
+ { /* TOKSW */
+ case TOKEN_SIMPLE:
+ fprintf (stderr, "char:");
+ break;
+
+ case TOKEN_WORD:
+ fprintf (stderr, "word:");
+ break;
+
+ case TOKEN_STRING:
+ fprintf (stderr, "string:");
+ break;
+
+ case TOKEN_MACDEF:
+ fprintf (stderr, "macro: 0x%x\n", TOKEN_DATA_FUNC (td));
+ break;
+
+ case TOKEN_EOF:
+ fprintf (stderr, "eof\n");
+ break;
+ }
+ fprintf (stderr, "\t\"%s\"\n", TOKEN_DATA_TEXT (td));
+}
+
+static void
+lex_debug (void)
+{
+ token_type t;
+ token_data td;
+
+ while ((t = next_token (&td)) != NULL)
+ print_token ("lex", t, &td);
+}
+#endif
diff --git a/src/ltdl.c b/src/ltdl.c
new file mode 100644
index 00000000..9cb5887e
--- /dev/null
+++ b/src/ltdl.c
@@ -0,0 +1,1691 @@
+/* ltdl.c -- system independent dlopen wrapper
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+ Originally by Thomas Tanner <tanner@ffii.org>
+ This file is part of GNU Libtool.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+As a special exception to the GNU Library General Public License,
+if you distribute this file as part of a program that uses GNU libtool
+to create libraries and programs, you may include it under the same
+distribution terms that you use for the rest of that program.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA
+*/
+
+#define _LTDL_COMPILE_
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if HAVE_STRING_H
+#include <string.h>
+#endif
+
+#if HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
+#if HAVE_CTYPE_H
+#include <ctype.h>
+#endif
+
+#if HAVE_MALLOC_H
+#include <malloc.h>
+#endif
+
+#if HAVE_MEMORY_H
+#include <memory.h>
+#endif
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#if HAVE_STDIO_H
+#include <stdio.h>
+#endif
+
+#include "ltdl.h"
+
+#ifdef DLL_EXPORT
+# define LTDL_GLOBAL_DATA __declspec(dllexport)
+#else
+# define LTDL_GLOBAL_DATA
+#endif
+
+/* max. filename length */
+#ifndef LTDL_FILENAME_MAX
+#define LTDL_FILENAME_MAX 1024
+#endif
+
+#undef LTDL_READTEXT_MODE
+/* fopen() mode flags for reading a text file */
+#ifdef _WIN32
+#define LTDL_READTEXT_MODE "rt"
+#else
+#define LTDL_READTEXT_MODE "r"
+#endif
+
+#undef LTDL_SYMBOL_LENGTH
+/* This is the maximum symbol size that won't require malloc/free */
+#define LTDL_SYMBOL_LENGTH 128
+
+#undef LTDL_SYMBOL_OVERHEAD
+/* This accounts for the _LTX_ separator */
+#define LTDL_SYMBOL_OVERHEAD 5
+
+static const char objdir[] = LTDL_OBJDIR;
+#ifdef LTDL_SHLIB_EXT
+static const char shlib_ext[] = LTDL_SHLIB_EXT;
+#endif
+
+static const char unknown_error[] = "unknown error";
+static const char dlopen_not_supported_error[] = "dlopen support not available";
+static const char file_not_found_error[] = "file not found";
+static const char no_symbols_error[] = "no symbols defined";
+static const char cannot_open_error[] = "can't open the module";
+static const char cannot_close_error[] = "can't close the module";
+static const char symbol_error[] = "symbol not found";
+static const char memory_error[] = "not enough memory";
+static const char invalid_handle_error[] = "invalid handle";
+static const char buffer_overflow_error[] = "internal buffer overflow";
+static const char shutdown_error[] = "library already shutdown";
+
+#ifndef HAVE_PRELOADED_SYMBOLS
+/* If libtool won't define it, we'd better do */
+LTDL_GLOBAL_DATA const lt_dlsymlist lt_preloaded_symbols[1] = { { 0, 0 } };
+#endif
+
+static const char *last_error = 0;
+
+LTDL_GLOBAL_DATA lt_ptr_t (*lt_dlmalloc) LTDL_PARAMS((size_t size)) = (lt_ptr_t(*)LTDL_PARAMS((size_t)))malloc;
+LTDL_GLOBAL_DATA void (*lt_dlfree) LTDL_PARAMS((lt_ptr_t ptr)) = (void(*)LTDL_PARAMS((lt_ptr_t)))free;
+
+typedef struct lt_dltype_t {
+ struct lt_dltype_t *next;
+ const char *sym_prefix; /* prefix for symbols */
+ int (*mod_init) LTDL_PARAMS((void));
+ int (*mod_exit) LTDL_PARAMS((void));
+ int (*lib_open) LTDL_PARAMS((lt_dlhandle handle, const char *filename));
+ int (*lib_close) LTDL_PARAMS((lt_dlhandle handle));
+ lt_ptr_t (*find_sym) LTDL_PARAMS((lt_dlhandle handle, const char *symbol));
+} lt_dltype_t;
+
+#define LTDL_TYPE_TOP 0
+
+typedef struct lt_dlhandle_t {
+ struct lt_dlhandle_t *next;
+ lt_dltype_t *type; /* dlopening interface */
+ lt_dlinfo info;
+ int depcount; /* number of dependencies */
+ lt_dlhandle *deplibs; /* dependencies */
+ lt_ptr_t handle; /* system handle */
+ lt_ptr_t system; /* system specific data */
+ lt_ptr_t app_private; /* application private data */
+} lt_dlhandle_t;
+
+#undef strdup
+#define strdup xstrdup
+
+static inline char *
+strdup(str)
+ const char *str;
+{
+ char *tmp;
+
+ if (!str)
+ return 0;
+ tmp = (char*) lt_dlmalloc(strlen(str)+1);
+ if (tmp)
+ strcpy(tmp, str);
+ return tmp;
+}
+
+#if ! HAVE_STRCHR
+
+# if HAVE_INDEX
+
+# define strchr index
+
+# else
+
+# define strchr xstrchr
+
+static inline const char*
+strchr(str, ch)
+ const char *str;
+ int ch;
+{
+ const char *p;
+
+ for (p = str; *p != (char)ch && *p != '\0'; p++)
+ /*NOWORK*/;
+
+ return (*p == (char)ch) ? p : 0;
+}
+
+# endif
+
+#endif
+
+#if ! HAVE_STRRCHR
+
+# if HAVE_RINDEX
+
+# define strrchr rindex
+
+# else
+
+# define strrchr xstrrchr
+
+static inline const char*
+strrchr(str, ch)
+ const char *str;
+ int ch;
+{
+ const char *p;
+
+ for (p = str; *p != '\0'; p++)
+ /*NOWORK*/;
+
+ while (*p != (char)ch && p >= str)
+ p--;
+
+ return (*p == (char)ch) ? p : 0;
+}
+
+# endif
+
+#endif
+
+#if HAVE_LIBDL
+
+/* dynamic linking with dlopen/dlsym */
+
+#if HAVE_DLFCN_H
+# include <dlfcn.h>
+#endif
+
+#ifdef RTLD_GLOBAL
+# define LTDL_GLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LTDL_GLOBAL DL_GLOBAL
+# else
+# define LTDL_GLOBAL 0
+# endif
+#endif
+
+/* We may have to define LTDL_LAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LTDL_LAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LTDL_LAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LTDL_LAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LTDL_LAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LTDL_LAZY_OR_NOW DL_NOW
+# else
+# define LTDL_LAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+static int
+sys_dl_init LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_dl_exit LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_dl_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ handle->handle = dlopen(filename, LTDL_GLOBAL | LTDL_LAZY_OR_NOW);
+ if (!handle->handle) {
+#if HAVE_DLERROR
+ last_error = dlerror();
+#else
+ last_error = cannot_open_error;
+#endif
+ return 1;
+ }
+ return 0;
+}
+
+static int
+sys_dl_close (handle)
+ lt_dlhandle handle;
+{
+ if (dlclose(handle->handle) != 0) {
+#if HAVE_DLERROR
+ last_error = dlerror();
+#else
+ last_error = cannot_close_error;
+#endif
+ return 1;
+ }
+ return 0;
+}
+
+static lt_ptr_t
+sys_dl_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_ptr_t address = dlsym(handle->handle, symbol);
+
+ if (!address)
+#if HAVE_DLERROR
+ last_error = dlerror();
+#else
+ last_error = symbol_error;
+#endif
+ return address;
+}
+
+static
+lt_dltype_t
+#ifdef NEED_USCORE
+sys_dl = { LTDL_TYPE_TOP, "_", sys_dl_init, sys_dl_exit,
+ sys_dl_open, sys_dl_close, sys_dl_sym };
+#else
+sys_dl = { LTDL_TYPE_TOP, 0, sys_dl_init, sys_dl_exit,
+ sys_dl_open, sys_dl_close, sys_dl_sym };
+#endif
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &sys_dl
+
+#endif
+
+#if HAVE_SHL_LOAD
+
+/* dynamic linking with shl_load (HP-UX) (comments from gmodule) */
+
+#ifdef HAVE_DL_H
+#include <dl.h>
+#endif
+
+/* some flags are missing on some systems, so we provide
+ * harmless defaults.
+ *
+ * Mandatory:
+ * BIND_IMMEDIATE - Resolve symbol references when the library is loaded.
+ * BIND_DEFERRED - Delay code symbol resolution until actual reference.
+ *
+ * Optionally:
+ * BIND_FIRST - Place the library at the head of the symbol search order.
+ * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all unsatisfied
+ * symbols as fatal. This flag allows binding of unsatisfied code
+ * symbols to be deferred until use.
+ * [Perl: For certain libraries, like DCE, deferred binding often
+ * causes run time problems. Adding BIND_NONFATAL to BIND_IMMEDIATE
+ * still allows unresolved references in situations like this.]
+ * BIND_NOSTART - Do not call the initializer for the shared library when the
+ * library is loaded, nor on a future call to shl_unload().
+ * BIND_VERBOSE - Print verbose messages concerning possible unsatisfied symbols.
+ *
+ * hp9000s700/hp9000s800:
+ * BIND_RESTRICTED - Restrict symbols visible by the library to those present at
+ * library load time.
+ * DYNAMIC_PATH - Allow the loader to dynamically search for the library specified
+ * by the path argument.
+ */
+
+#ifndef DYNAMIC_PATH
+#define DYNAMIC_PATH 0
+#endif /* DYNAMIC_PATH */
+#ifndef BIND_RESTRICTED
+#define BIND_RESTRICTED 0
+#endif /* BIND_RESTRICTED */
+
+#define LTDL_BIND_FLAGS (BIND_IMMEDIATE | BIND_NONFATAL | DYNAMIC_PATH)
+
+static int
+sys_shl_init LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_shl_exit LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_shl_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ handle->handle = shl_load(filename, LTDL_BIND_FLAGS, 0L);
+ if (!handle->handle) {
+ last_error = cannot_open_error;
+ return 1;
+ }
+ return 0;
+}
+
+static int
+sys_shl_close (handle)
+ lt_dlhandle handle;
+{
+ if (shl_unload((shl_t) (handle->handle)) != 0) {
+ last_error = cannot_close_error;
+ return 1;
+ }
+ return 0;
+}
+
+static lt_ptr_t
+sys_shl_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_ptr_t address;
+
+ if (handle->handle && shl_findsym((shl_t*) &(handle->handle),
+ symbol, TYPE_UNDEFINED, &address) == 0)
+ if (address)
+ return address;
+ last_error = symbol_error;
+ return 0;
+}
+
+static
+lt_dltype_t
+sys_shl = { LTDL_TYPE_TOP, 0, sys_shl_init, sys_shl_exit,
+ sys_shl_open, sys_shl_close, sys_shl_sym };
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &sys_shl
+
+#endif
+
+#if HAVE_DLD
+
+/* dynamic linking with dld */
+
+#if HAVE_DLD_H
+#include <dld.h>
+#endif
+
+static int
+sys_dld_init LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_dld_exit LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_dld_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ handle->handle = strdup(filename);
+ if (!handle->handle) {
+ last_error = memory_error;
+ return 1;
+ }
+ if (dld_link(filename) != 0) {
+ last_error = cannot_open_error;
+ lt_dlfree(handle->handle);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+sys_dld_close (handle)
+ lt_dlhandle handle;
+{
+ if (dld_unlink_by_file((char*)(handle->handle), 1) != 0) {
+ last_error = cannot_close_error;
+ return 1;
+ }
+ lt_dlfree(handle->filename);
+ return 0;
+}
+
+static lt_ptr_t
+sys_dld_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_ptr_t address = dld_get_func(symbol);
+
+ if (!address)
+ last_error = symbol_error;
+ return address;
+}
+
+static
+lt_dltype_t
+sys_dld = { LTDL_TYPE_TOP, 0, sys_dld_init, sys_dld_exit,
+ sys_dld_open, sys_dld_close, sys_dld_sym };
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &sys_dld
+
+#endif
+
+#ifdef _WIN32
+
+/* dynamic linking for Win32 */
+
+#include <windows.h>
+
+static int
+sys_wll_init LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_wll_exit LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+/* Forward declaration; required to implement handle search below. */
+static lt_dlhandle handles;
+
+static int
+sys_wll_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ lt_dlhandle cur;
+ char *searchname = NULL;
+ char *ext = strrchr(filename, '.');
+
+ if (ext) {
+ /* FILENAME already has an extension. */
+ searchname = strdup(filename);
+ } else {
+ /* Append a `.' to stop Windows from adding an
+ implicit `.dll' extension. */
+ searchname = (char*)lt_dlmalloc(2+ strlen(filename));
+ strcpy(searchname, filename);
+ strcat(searchname, ".");
+ }
+
+ handle->handle = LoadLibrary(searchname);
+ lt_dlfree(searchname);
+
+ /* libltdl expects this function to fail if it is unable
+ to physically load the library. Sadly, LoadLibrary
+ will search the loaded libraries for a match and return
+ one of them if the path search load fails.
+
+ We check whether LoadLibrary is returning a handle to
+ an already loaded module, and simulate failure if we
+ find one. */
+ cur = handles;
+ while (cur) {
+ if (!cur->handle) {
+ cur = 0;
+ break;
+ }
+ if (cur->handle == handle->handle)
+ break;
+ cur = cur->next;
+ }
+
+ if (cur || !handle->handle) {
+ last_error = cannot_open_error;
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+sys_wll_close (handle)
+ lt_dlhandle handle;
+{
+ if (FreeLibrary(handle->handle) == 0) {
+ last_error = cannot_close_error;
+ return 1;
+ }
+ return 0;
+}
+
+static lt_ptr_t
+sys_wll_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_ptr_t address = GetProcAddress(handle->handle, symbol);
+
+ if (!address)
+ last_error = symbol_error;
+ return address;
+}
+
+static
+lt_dltype_t
+sys_wll = { LTDL_TYPE_TOP, 0, sys_wll_init, sys_wll_exit,
+ sys_wll_open, sys_wll_close, sys_wll_sym };
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &sys_wll
+
+#endif
+
+#ifdef __BEOS__
+
+/* dynamic linking for BeOS */
+
+#include <kernel/image.h>
+
+static int
+sys_bedl_init LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_bedl_exit LTDL_PARAMS((void))
+{
+ return 0;
+}
+
+static int
+sys_bedl_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ image_id image = 0;
+
+ if (filename) {
+ image = load_add_on(filename);
+ } else {
+ image_info info;
+ int32 cookie = 0;
+ if (get_next_image_info(0, &cookie, &info) == B_OK)
+ image = load_add_on(info.name);
+ }
+ if (image <= 0) {
+ last_error = cannot_open_error;
+ return 1;
+ }
+ handle->handle = (void*) image;
+ return 0;
+}
+
+static int
+sys_bedl_close (handle)
+ lt_dlhandle handle;
+{
+ if (unload_add_on((image_id)handle->handle) != B_OK) {
+ last_error = cannot_close_error;
+ return 1;
+ }
+ return 0;
+}
+
+static lt_ptr_t
+sys_bedl_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_ptr_t address = 0;
+ image_id image = (image_id)handle->handle;
+
+ if (get_image_symbol(image, symbol, B_SYMBOL_TYPE_ANY,
+ &address) != B_OK) {
+ last_error = symbol_error;
+ return 0;
+ }
+ return address;
+}
+
+static
+lt_dltype_t
+sys_bedl = { LTDL_TYPE_TOP, 0, sys_bedl_init, sys_bedl_exit,
+ sys_bedl_open, sys_bedl_close, sys_bedl_sym };
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &sys_bedl
+
+#endif
+
+/* emulate dynamic linking using preloaded_symbols */
+
+typedef struct lt_dlsymlists_t {
+ struct lt_dlsymlists_t *next;
+ const lt_dlsymlist *syms;
+} lt_dlsymlists_t;
+
+static const lt_dlsymlist *default_preloaded_symbols = 0;
+static lt_dlsymlists_t *preloaded_symbols = 0;
+
+static int
+presym_init LTDL_PARAMS((void))
+{
+ preloaded_symbols = 0;
+ if (default_preloaded_symbols)
+ return lt_dlpreload(default_preloaded_symbols);
+ return 0;
+}
+
+static int
+presym_free_symlists LTDL_PARAMS((void))
+{
+ lt_dlsymlists_t *lists = preloaded_symbols;
+
+ while (lists) {
+ lt_dlsymlists_t *tmp = lists;
+
+ lists = lists->next;
+ lt_dlfree(tmp);
+ }
+ preloaded_symbols = 0;
+ return 0;
+}
+
+static int
+presym_exit LTDL_PARAMS((void))
+{
+ presym_free_symlists();
+ return 0;
+}
+
+static int
+presym_add_symlist (preloaded)
+ const lt_dlsymlist *preloaded;
+{
+ lt_dlsymlists_t *tmp;
+ lt_dlsymlists_t *lists = preloaded_symbols;
+
+ while (lists) {
+ if (lists->syms == preloaded)
+ return 0;
+ lists = lists->next;
+ }
+
+ tmp = (lt_dlsymlists_t*) lt_dlmalloc(sizeof(lt_dlsymlists_t));
+ if (!tmp) {
+ last_error = memory_error;
+ return 1;
+ }
+ tmp->syms = preloaded;
+ tmp->next = 0;
+ if (!preloaded_symbols)
+ preloaded_symbols = tmp;
+ else {
+ /* append to the end */
+ lists = preloaded_symbols;
+ while (lists->next)
+ lists = lists->next;
+ lists->next = tmp;
+ }
+ return 0;
+}
+
+static int
+presym_open (handle, filename)
+ lt_dlhandle handle;
+ const char *filename;
+{
+ lt_dlsymlists_t *lists = preloaded_symbols;
+
+ if (!lists) {
+ last_error = no_symbols_error;
+ return 1;
+ }
+ if (!filename)
+ filename = "@PROGRAM@";
+ while (lists) {
+ const lt_dlsymlist *syms = lists->syms;
+
+ while (syms->name) {
+ if (!syms->address &&
+ strcmp(syms->name, filename) == 0) {
+ handle->handle = (lt_ptr_t) syms;
+ return 0;
+ }
+ syms++;
+ }
+ lists = lists->next;
+ }
+ last_error = file_not_found_error;
+ return 1;
+}
+
+static int
+presym_close (handle)
+ lt_dlhandle handle;
+{
+ /* Just to silence gcc -Wall */
+ handle = 0;
+ return 0;
+}
+
+static lt_ptr_t
+presym_sym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ lt_dlsymlist *syms = (lt_dlsymlist*)(handle->handle);
+
+ syms++;
+ while (syms->address) {
+ if (strcmp(syms->name, symbol) == 0)
+ return syms->address;
+ syms++;
+ }
+ last_error = symbol_error;
+ return 0;
+}
+
+static
+lt_dltype_t
+presym = { LTDL_TYPE_TOP, 0, presym_init, presym_exit,
+ presym_open, presym_close, presym_sym };
+
+#undef LTDL_TYPE_TOP
+#define LTDL_TYPE_TOP &presym
+
+static char *user_search_path = 0;
+static lt_dlhandle handles = 0;
+static int initialized = 0;
+
+static lt_dltype_t *types = LTDL_TYPE_TOP;
+#undef LTDL_TYPE_TOP
+
+int
+lt_dlinit LTDL_PARAMS((void))
+{
+ /* initialize libltdl */
+ lt_dltype_t **type = &types;
+ int typecount = 0;
+
+ if (initialized) { /* Initialize only at first call. */
+ initialized++;
+ return 0;
+ }
+ handles = 0;
+ user_search_path = 0; /* empty search path */
+
+ while (*type) {
+ if ((*type)->mod_init())
+ *type = (*type)->next; /* Remove it from the list */
+ else {
+ type = &(*type)->next; /* Keep it */
+ typecount++;
+ }
+ }
+ if (typecount == 0) {
+ last_error = dlopen_not_supported_error;
+ return 1;
+ }
+ last_error = 0;
+ initialized = 1;
+ return 0;
+}
+
+int
+lt_dlpreload (preloaded)
+ const lt_dlsymlist *preloaded;
+{
+ if (preloaded)
+ return presym_add_symlist(preloaded);
+ presym_free_symlists();
+ if (default_preloaded_symbols)
+ return lt_dlpreload(default_preloaded_symbols);
+ return 0;
+}
+
+int
+lt_dlpreload_default (preloaded)
+ const lt_dlsymlist *preloaded;
+{
+ default_preloaded_symbols = preloaded;
+ return 0;
+}
+
+int
+lt_dlexit LTDL_PARAMS((void))
+{
+ /* shut down libltdl */
+ lt_dltype_t *type = types;
+ int errors;
+
+ if (!initialized) {
+ last_error = shutdown_error;
+ return 1;
+ }
+ if (initialized != 1) { /* shut down only at last call. */
+ initialized--;
+ return 0;
+ }
+ /* close all modules */
+ errors = 0;
+ while (handles) {
+ /* FIXME: what if a module depends on another one? */
+ if (lt_dlclose(handles))
+ errors++;
+ }
+ initialized = 0;
+ while (type) {
+ if (type->mod_exit())
+ errors++;
+ type = type->next;
+ }
+ return errors;
+}
+
+static int
+tryall_dlopen (handle, filename)
+ lt_dlhandle *handle;
+ const char *filename;
+{
+ lt_dlhandle cur;
+ lt_dltype_t *type = types;
+ const char *saved_error = last_error;
+
+ /* check whether the module was already opened */
+ cur = handles;
+ while (cur) {
+ /* try to dlopen the program itself? */
+ if (!cur->info.filename && !filename)
+ break;
+ if (cur->info.filename && filename &&
+ strcmp(cur->info.filename, filename) == 0)
+ break;
+ cur = cur->next;
+ }
+ if (cur) {
+ cur->info.ref_count++;
+ *handle = cur;
+ return 0;
+ }
+
+ cur = *handle;
+ if (filename) {
+ cur->info.filename = strdup(filename);
+ if (!cur->info.filename) {
+ last_error = memory_error;
+ return 1;
+ }
+ } else
+ cur->info.filename = 0;
+ while (type) {
+ if (type->lib_open(cur, filename) == 0)
+ break;
+ type = type->next;
+ }
+ if (!type) {
+ if (cur->info.filename)
+ lt_dlfree(cur->info.filename);
+ return 1;
+ }
+ cur->type = type;
+ last_error = saved_error;
+ return 0;
+}
+
+static int
+find_module (handle, dir, libdir, dlname, old_name, installed)
+ lt_dlhandle *handle;
+ const char *dir;
+ const char *libdir;
+ const char *dlname;
+ const char *old_name;
+ int installed;
+{
+ int error;
+ char *filename;
+ /* try to open the old library first; if it was dlpreopened,
+ we want the preopened version of it, even if a dlopenable
+ module is available */
+ if (old_name && tryall_dlopen(handle, old_name) == 0)
+ return 0;
+ /* try to open the dynamic library */
+ if (dlname) {
+ /* try to open the installed module */
+ if (installed && libdir) {
+ filename = (char*)
+ lt_dlmalloc(strlen(libdir)+1+strlen(dlname)+1);
+ if (!filename) {
+ last_error = memory_error;
+ return 1;
+ }
+ sprintf (filename, "%s/%s", libdir, dlname);
+ error = tryall_dlopen(handle, filename) != 0;
+ lt_dlfree(filename);
+ if (!error)
+ return 0;
+ }
+ /* try to open the not-installed module */
+ if (!installed) {
+ filename = (char*)
+ lt_dlmalloc((dir ? strlen(dir) : 0)
+ + strlen(objdir) + strlen(dlname) + 1);
+ if (!filename) {
+ last_error = memory_error;
+ return 1;
+ }
+ if (dir)
+ strcpy(filename, dir);
+ else
+ *filename = 0;
+ strcat(filename, objdir);
+ strcat(filename, dlname);
+
+ error = tryall_dlopen(handle, filename) != 0;
+ lt_dlfree(filename);
+ if (!error)
+ return 0;
+ }
+ /* maybe it was moved to another directory */
+ {
+ filename = (char*)
+ lt_dlmalloc((dir ? strlen(dir) : 0)
+ + strlen(dlname) + 1);
+ if (dir)
+ strcpy(filename, dir);
+ else
+ *filename = 0;
+ strcat(filename, dlname);
+ error = tryall_dlopen(handle, filename) != 0;
+ lt_dlfree(filename);
+ if (!error)
+ return 0;
+ }
+ }
+ last_error = file_not_found_error;
+ return 1;
+}
+
+static char*
+canonicalize_path (path)
+ const char *path;
+{
+ char *canonical = NULL;
+
+ if (path && *path) {
+ char *ptr = strdup (path);
+ canonical = ptr;
+#ifdef LTDL_DIRSEP_CHAR
+ /* Avoid this overhead where '/' is the only separator. */
+ while (ptr = strchr (ptr, LTDL_DIRSEP_CHAR))
+ *ptr++ = '/';
+#endif
+ }
+
+ return canonical;
+}
+
+static lt_ptr_t
+find_file (basename, search_path, pdir, handle)
+ const char *basename;
+ const char *search_path;
+ char **pdir;
+ lt_dlhandle *handle;
+{
+ /* when handle != NULL search a library, otherwise a file */
+ /* return NULL on failure, otherwise the file/handle */
+
+ lt_ptr_t result = 0;
+ char *filename = 0;
+ int filenamesize = 0;
+ int lenbase = strlen(basename);
+ char *next = 0;
+
+ if (!search_path || !*search_path) {
+ last_error = file_not_found_error;
+ return 0;
+ }
+ next = canonicalize_path (search_path);
+ if (!next) {
+ last_error = memory_error;
+ goto cleanup;
+ }
+ while (next) {
+ int lendir;
+ char *cur = next;
+
+ next = strchr(cur, LTDL_PATHSEP_CHAR);
+ if (!next)
+ next = cur + strlen(cur);
+ lendir = next - cur;
+ if (*next == LTDL_PATHSEP_CHAR)
+ ++next;
+ else
+ next = 0;
+ if (lendir == 0)
+ continue;
+ if (lendir + 1 + lenbase >= filenamesize) {
+ if (filename)
+ lt_dlfree(filename);
+ filenamesize = lendir + 1 + lenbase + 1;
+ filename = (char*) lt_dlmalloc(filenamesize);
+ if (!filename) {
+ last_error = memory_error;
+ goto cleanup;
+ }
+ }
+ strncpy(filename, cur, lendir);
+ if (filename[lendir-1] != '/')
+ filename[lendir++] = '/';
+ strcpy(filename+lendir, basename);
+ if (handle) {
+ if (tryall_dlopen(handle, filename) == 0) {
+ result = (lt_ptr_t) handle;
+ goto cleanup;
+ }
+ } else {
+ FILE *file = fopen(filename, LTDL_READTEXT_MODE);
+ if (file) {
+ if (*pdir)
+ lt_dlfree(*pdir);
+ filename[lendir] = '\0';
+ *pdir = strdup(filename);
+ if (!*pdir) {
+ /* We could have even avoided the
+ strdup, but there would be some
+ memory overhead. */
+ *pdir = filename;
+ } else
+ filename = NULL;
+ result = (lt_ptr_t) file;
+ goto cleanup;
+ }
+ }
+ }
+ last_error = file_not_found_error;
+cleanup:
+ if (filename)
+ lt_dlfree(filename);
+ lt_dlfree(next);
+ return result;
+}
+
+static int
+load_deplibs(handle, deplibs)
+ lt_dlhandle handle;
+ const char *deplibs;
+{
+ /* FIXME: load deplibs */
+ handle->depcount = 0;
+ handle->deplibs = 0;
+ /* Just to silence gcc -Wall */
+ deplibs = 0;
+ return 0;
+}
+
+static int
+unload_deplibs(handle)
+ lt_dlhandle handle;
+{
+ /* FIXME: unload deplibs */
+ /* Just to silence gcc -Wall */
+ handle = 0;
+ return 0;
+}
+
+static inline int
+trim (dest, str)
+ char **dest;
+ const char *str;
+{
+ /* remove the leading and trailing "'" from str
+ and store the result in dest */
+ char *tmp;
+ const char *end = strrchr(str, '\'');
+ int len = strlen(str);
+
+ if (*dest)
+ lt_dlfree(*dest);
+ if (len > 3 && str[0] == '\'') {
+ tmp = (char*) lt_dlmalloc(end - str);
+ if (!tmp) {
+ last_error = memory_error;
+ return 1;
+ }
+ strncpy(tmp, &str[1], (end - str) - 1);
+ tmp[len-3] = '\0';
+ *dest = tmp;
+ } else
+ *dest = 0;
+ return 0;
+}
+
+static inline int
+free_vars( dlname, oldname, libdir, deplibs)
+ char *dlname;
+ char *oldname;
+ char *libdir;
+ char *deplibs;
+{
+ if (dlname)
+ lt_dlfree(dlname);
+ if (oldname)
+ lt_dlfree(oldname);
+ if (libdir)
+ lt_dlfree(libdir);
+ if (deplibs)
+ lt_dlfree(deplibs);
+ return 0;
+}
+
+lt_dlhandle
+lt_dlopen (filename)
+ const char *filename;
+{
+ lt_dlhandle handle = 0, newhandle;
+ const char *ext;
+ const char *saved_error = last_error;
+ char *canonical = 0, *basename = 0, *dir = 0, *name = 0;
+
+ if (!filename) {
+ handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
+ if (!handle) {
+ last_error = memory_error;
+ return 0;
+ }
+ handle->info.ref_count = 0;
+ handle->depcount = 0;
+ handle->deplibs = 0;
+ newhandle = handle;
+ if (tryall_dlopen(&newhandle, 0) != 0) {
+ lt_dlfree(handle);
+ return 0;
+ }
+ goto register_handle;
+ }
+ canonical = canonicalize_path (filename);
+ if (!canonical) {
+ last_error = memory_error;
+ if (handle)
+ lt_dlfree(handle);
+ return 0;
+ }
+ basename = strrchr(canonical, '/');
+ if (basename) {
+ basename++;
+ dir = (char*) lt_dlmalloc(basename - canonical + 1);
+ if (!dir) {
+ last_error = memory_error;
+ handle = 0;
+ goto cleanup;
+ }
+ strncpy(dir, canonical, basename - canonical);
+ dir[basename - canonical] = '\0';
+ } else
+ basename = canonical;
+ /* check whether we open a libtool module (.la extension) */
+ ext = strrchr(basename, '.');
+ if (ext && strcmp(ext, ".la") == 0) {
+ /* this seems to be a libtool module */
+ FILE *file;
+ int i;
+ char *dlname = 0, *old_name = 0;
+ char *libdir = 0, *deplibs = 0;
+ char *line;
+ int error = 0;
+ /* if we can't find the installed flag, it is probably an
+ installed libtool archive, produced with an old version
+ of libtool */
+ int installed = 1;
+
+ /* extract the module name from the file name */
+ name = (char*) lt_dlmalloc(ext - basename + 1);
+ if (!name) {
+ last_error = memory_error;
+ handle = 0;
+ goto cleanup;
+ }
+ /* canonicalize the module name */
+ for (i = 0; i < ext - basename; i++)
+ if (isalnum((int)(basename[i])))
+ name[i] = basename[i];
+ else
+ name[i] = '_';
+ name[ext - basename] = '\0';
+ /* now try to open the .la file */
+ file = fopen(filename, LTDL_READTEXT_MODE);
+ if (!file)
+ last_error = file_not_found_error;
+ if (!file && !dir) {
+ /* try other directories */
+ file = (FILE*) find_file(basename,
+ user_search_path,
+ &dir, 0);
+ if (!file)
+ file = (FILE*) find_file(basename,
+ getenv("LTDL_LIBRARY_PATH"),
+ &dir, 0);
+#ifdef LTDL_SHLIBPATH_VAR
+ if (!file)
+ file = (FILE*) find_file(basename,
+ getenv(LTDL_SHLIBPATH_VAR),
+ &dir, 0);
+#endif
+ }
+ if (!file) {
+ handle = 0;
+ goto cleanup;
+ }
+ line = (char*) lt_dlmalloc(LTDL_FILENAME_MAX);
+ if (!line) {
+ fclose(file);
+ last_error = memory_error;
+ handle = 0;
+ goto cleanup;
+ }
+ /* read the .la file */
+ while (!feof(file)) {
+ if (!fgets(line, LTDL_FILENAME_MAX, file))
+ break;
+ if (line[0] == '\n' || line[0] == '#')
+ continue;
+# undef STR_DLNAME
+# define STR_DLNAME "dlname="
+ if (strncmp(line, STR_DLNAME,
+ sizeof(STR_DLNAME) - 1) == 0)
+ error = trim(&dlname,
+ &line[sizeof(STR_DLNAME) - 1]);
+ else
+# undef STR_OLD_LIBRARY
+# define STR_OLD_LIBRARY "old_library="
+ if (strncmp(line, STR_OLD_LIBRARY,
+ sizeof(STR_OLD_LIBRARY) - 1) == 0)
+ error = trim(&old_name,
+ &line[sizeof(STR_OLD_LIBRARY) - 1]);
+ else
+# undef STR_LIBDIR
+# define STR_LIBDIR "libdir="
+ if (strncmp(line, STR_LIBDIR,
+ sizeof(STR_LIBDIR) - 1) == 0)
+ error = trim(&libdir,
+ &line[sizeof(STR_LIBDIR) - 1]);
+ else
+# undef STR_DL_DEPLIBS
+# define STR_DL_DEPLIBS "dl_dependency_libs="
+ if (strncmp(line, STR_DL_DEPLIBS,
+ sizeof(STR_DL_DEPLIBS) - 1) == 0)
+ error = trim(&deplibs,
+ &line[sizeof(STR_DL_DEPLIBS) - 1]);
+ else
+ if (strcmp(line, "installed=yes\n") == 0)
+ installed = 1;
+ else
+ if (strcmp(line, "installed=no\n") == 0)
+ installed = 0;
+ if (error)
+ break;
+ }
+ fclose(file);
+ lt_dlfree(line);
+ /* allocate the handle */
+ handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
+ if (!handle || error) {
+ if (handle)
+ lt_dlfree(handle);
+ if (!error)
+ last_error = memory_error;
+ free_vars(dlname, old_name, libdir, deplibs);
+ /* handle is already set to 0 */
+ goto cleanup;
+ }
+ handle->info.ref_count = 0;
+ if (load_deplibs(handle, deplibs) == 0) {
+ newhandle = handle;
+ /* find_module may replace newhandle */
+ if (find_module(&newhandle, dir, libdir,
+ dlname, old_name, installed)) {
+ unload_deplibs(handle);
+ error = 1;
+ }
+ } else
+ error = 1;
+ free_vars(dlname, old_name, libdir, deplibs);
+ if (error) {
+ lt_dlfree(handle);
+ handle = 0;
+ goto cleanup;
+ }
+ if (handle != newhandle)
+ unload_deplibs(handle);
+ } else {
+ /* not a libtool module */
+ handle = (lt_dlhandle) lt_dlmalloc(sizeof(lt_dlhandle_t));
+ if (!handle) {
+ last_error = memory_error;
+ /* handle is already set to 0 */
+ goto cleanup;
+ }
+ handle->info.ref_count = 0;
+ /* non-libtool modules don't have dependencies */
+ handle->depcount = 0;
+ handle->deplibs = 0;
+ newhandle = handle;
+ if (tryall_dlopen(&newhandle, filename)
+ && (dir
+ || (!find_file(basename, user_search_path,
+ 0, &newhandle)
+ && !find_file(basename,
+ getenv("LTDL_LIBRARY_PATH"),
+ 0, &newhandle)
+#ifdef LTDL_SHLIBPATH_VAR
+ && !find_file(basename,
+ getenv(LTDL_SHLIBPATH_VAR),
+ 0, &newhandle)
+#endif
+ ))) {
+ lt_dlfree(handle);
+ handle = 0;
+ goto cleanup;
+ }
+ }
+register_handle:
+ if (newhandle != handle) {
+ lt_dlfree(handle);
+ handle = newhandle;
+ }
+ if (!handle->info.ref_count) {
+ handle->info.ref_count = 1;
+ handle->app_private = 0;
+ handle->info.name = name;
+ handle->next = handles;
+ handles = handle;
+ name = 0; /* don't free this during `cleanup' */
+ }
+ last_error = saved_error;
+cleanup:
+ if (dir)
+ lt_dlfree(dir);
+ if (name)
+ lt_dlfree(name);
+ if (canonical)
+ lt_dlfree(canonical);
+ return handle;
+}
+
+lt_dlhandle
+lt_dlopenext (filename)
+ const char *filename;
+{
+ lt_dlhandle handle;
+ char *tmp;
+ int len;
+ const char *saved_error = last_error;
+
+ if (!filename)
+ return lt_dlopen(filename);
+ len = strlen(filename);
+ if (!len) {
+ last_error = file_not_found_error;
+ return 0;
+ }
+ /* try the normal file name */
+ handle = lt_dlopen(filename);
+ if (handle)
+ return handle;
+ /* try "filename.la" */
+ tmp = (char*) lt_dlmalloc(len+4);
+ if (!tmp) {
+ last_error = memory_error;
+ return 0;
+ }
+ strcpy(tmp, filename);
+ strcat(tmp, ".la");
+ handle = lt_dlopen(tmp);
+ if (handle) {
+ last_error = saved_error;
+ lt_dlfree(tmp);
+ return handle;
+ }
+#ifdef LTDL_SHLIB_EXT
+ /* try "filename.EXT" */
+ if (strlen(shlib_ext) > 3) {
+ lt_dlfree(tmp);
+ tmp = (char*) lt_dlmalloc(len + strlen(shlib_ext) + 1);
+ if (!tmp) {
+ last_error = memory_error;
+ return 0;
+ }
+ strcpy(tmp, filename);
+ } else
+ tmp[len] = '\0';
+ strcat(tmp, shlib_ext);
+ handle = lt_dlopen(tmp);
+ if (handle) {
+ last_error = saved_error;
+ lt_dlfree(tmp);
+ return handle;
+ }
+#endif
+ last_error = file_not_found_error;
+ lt_dlfree(tmp);
+ return 0;
+}
+
+int
+lt_dlclose (handle)
+ lt_dlhandle handle;
+{
+ lt_dlhandle cur, last;
+
+ /* check whether the handle is valid */
+ last = cur = handles;
+ while (cur && handle != cur) {
+ last = cur;
+ cur = cur->next;
+ }
+ if (!cur) {
+ last_error = invalid_handle_error;
+ return 1;
+ }
+ handle->info.ref_count--;
+ if (!handle->info.ref_count) {
+ int error;
+
+ if (handle != handles)
+ last->next = handle->next;
+ else
+ handles = handle->next;
+ error = handle->type->lib_close(handle);
+ error += unload_deplibs(handle);
+ if (handle->info.filename)
+ lt_dlfree(handle->info.filename);
+ if (handle->info.name)
+ lt_dlfree(handle->info.name);
+ lt_dlfree(handle);
+ return error;
+ }
+ return 0;
+}
+
+lt_ptr_t
+lt_dlsym (handle, symbol)
+ lt_dlhandle handle;
+ const char *symbol;
+{
+ int lensym;
+ char lsym[LTDL_SYMBOL_LENGTH];
+ char *sym;
+ lt_ptr_t address;
+
+ if (!handle) {
+ last_error = invalid_handle_error;
+ return 0;
+ }
+ if (!symbol) {
+ last_error = symbol_error;
+ return 0;
+ }
+ lensym = strlen(symbol);
+ if (handle->type->sym_prefix)
+ lensym += strlen(handle->type->sym_prefix);
+ if (handle->info.name)
+ lensym += strlen(handle->info.name);
+ if (lensym + LTDL_SYMBOL_OVERHEAD < LTDL_SYMBOL_LENGTH)
+ sym = lsym;
+ else
+ sym = (char*) lt_dlmalloc(lensym + LTDL_SYMBOL_OVERHEAD + 1);
+ if (!sym) {
+ last_error = buffer_overflow_error;
+ return 0;
+ }
+ if (handle->info.name) {
+ const char *saved_error = last_error;
+
+ /* this is a libtool module */
+ if (handle->type->sym_prefix) {
+ strcpy(sym, handle->type->sym_prefix);
+ strcat(sym, handle->info.name);
+ } else
+ strcpy(sym, handle->info.name);
+ strcat(sym, "_LTX_");
+ strcat(sym, symbol);
+ /* try "modulename_LTX_symbol" */
+ address = handle->type->find_sym(handle, sym);
+ if (address) {
+ if (sym != lsym)
+ lt_dlfree(sym);
+ return address;
+ }
+ last_error = saved_error;
+ }
+ /* otherwise try "symbol" */
+ if (handle->type->sym_prefix) {
+ strcpy(sym, handle->type->sym_prefix);
+ strcat(sym, symbol);
+ } else
+ strcpy(sym, symbol);
+ address = handle->type->find_sym(handle, sym);
+ if (sym != lsym)
+ lt_dlfree(sym);
+ return address;
+}
+
+const char *
+lt_dlerror LTDL_PARAMS((void))
+{
+ const char *error = last_error;
+
+ last_error = 0;
+ return error;
+}
+
+int
+lt_dladdsearchdir (search_dir)
+ const char *search_dir;
+{
+ if (!search_dir || !strlen(search_dir))
+ return 0;
+ if (!user_search_path) {
+ user_search_path = strdup(search_dir);
+ if (!user_search_path) {
+ last_error = memory_error;
+ return 1;
+ }
+ } else {
+ char *new_search_path = (char*)
+ lt_dlmalloc(strlen(user_search_path) +
+ strlen(search_dir) + 2); /* ':' + '\0' == 2 */
+ if (!new_search_path) {
+ last_error = memory_error;
+ return 1;
+ }
+ sprintf (new_search_path, "%s%c%s", user_search_path,
+ LTDL_PATHSEP_CHAR, search_dir);
+ lt_dlfree(user_search_path);
+ user_search_path = new_search_path;
+ }
+ return 0;
+}
+
+int
+lt_dlsetsearchpath (search_path)
+ const char *search_path;
+{
+ if (user_search_path)
+ lt_dlfree(user_search_path);
+ user_search_path = 0; /* reset the search path */
+ if (!search_path || !strlen(search_path))
+ return 0;
+ user_search_path = strdup(search_path);
+ if (!user_search_path)
+ return 1;
+ return 0;
+}
+
+const char *
+lt_dlgetsearchpath LTDL_PARAMS((void))
+{
+ return user_search_path;
+}
+
+int
+lt_dlsetdata (handle, data)
+ lt_dlhandle handle;
+ lt_ptr_t data;
+{
+ if (!handle) {
+ last_error = invalid_handle_error;
+ return 1;
+ }
+ handle->app_private = data;
+ return 0;
+}
+
+lt_ptr_t
+lt_dlgetdata (handle)
+ lt_dlhandle handle;
+{
+ if (!handle) {
+ last_error = invalid_handle_error;
+ return 0;
+ }
+ return handle->app_private;
+}
+
+const lt_dlinfo *
+lt_dlgetinfo (handle)
+ lt_dlhandle handle;
+{
+ if (!handle) {
+ last_error = invalid_handle_error;
+ return 0;
+ }
+ return &(handle->info);
+}
diff --git a/src/ltdl.h b/src/ltdl.h
new file mode 100644
index 00000000..0fafa207
--- /dev/null
+++ b/src/ltdl.h
@@ -0,0 +1,141 @@
+/* ltdl.h -- generic dlopen functions
+ Copyright (C) 1998-2000 Free Software Foundation, Inc.
+ Originally by Thomas Tanner <tanner@ffii.org>
+ This file is part of GNU Libtool.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+As a special exception to the GNU Library General Public License,
+if you distribute this file as part of a program that uses GNU libtool
+to create libraries and programs, you may include it under the same
+distribution terms that you use for the rest of that program.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free
+Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA
+*/
+
+/* Only include this header file once. */
+#ifndef _LTDL_H_
+#define _LTDL_H_ 1
+
+/* Canonicalise Windows and Cygwin recognition macros. */
+#ifdef __CYGWIN32__
+# ifndef __CYGWIN__
+# define __CYGWIN__ __CYGWIN32__
+# endif
+#endif
+#ifdef _WIN32
+# ifndef WIN32
+# define WIN32 _WIN32
+# endif
+#endif
+
+/* __BEGIN_DECLS should be used at the beginning of your declarations,
+ so that C++ compilers don't mangle their names. Use __END_DECLS at
+ the end of C declarations. */
+#undef __BEGIN_DECLS
+#undef __END_DECLS
+#ifdef __cplusplus
+# define __BEGIN_DECLS extern "C" {
+# define __END_DECLS }
+#else
+# define __BEGIN_DECLS /* empty */
+# define __END_DECLS /* empty */
+#endif
+
+/* LTDL_PARAMS is a macro used to wrap function prototypes, so that compilers
+ that don't understand ANSI C prototypes still work, and ANSI C
+ compilers can issue warnings about type mismatches. */
+#undef LTDL_PARAMS
+#undef lt_ptr_t
+#if defined (__STDC__) || defined (_AIX) || (defined (__mips) && defined (_SYSTYPE_SVR4)) || defined(WIN32) || defined(__cplusplus)
+# define LTDL_PARAMS(protos) protos
+# define lt_ptr_t void*
+#else
+# define LTDL_PARAMS(protos) ()
+# define lt_ptr_t char*
+#endif
+
+#ifdef WIN32
+# ifndef __CYGWIN__
+/* LTDL_DIRSEP_CHAR is accepted *in addition* to '/' as a directory
+ separator when it is set. */
+# define LTDL_DIRSEP_CHAR '\\'
+# define LTDL_PATHSEP_CHAR ';'
+# endif
+#endif
+#ifndef LTDL_PATHSEP_CHAR
+# define LTDL_PATHSEP_CHAR ':'
+#endif
+
+/* DLL building support on win32 hosts; mostly to workaround their
+ ridiculous implementation of data symbol exporting. */
+#ifndef LTDL_SCOPE
+# ifdef _WIN32
+# ifdef DLL_EXPORT /* defined by libtool (if required) */
+# define LTDL_SCOPE __declspec(dllexport)
+# endif
+# ifdef LIBLTDL_DLL_IMPORT /* define if linking with this dll */
+# define LTDL_SCOPE extern __declspec(dllimport)
+# endif
+# endif
+# ifndef LTDL_SCOPE /* static linking or !_WIN32 */
+# define LTDL_SCOPE extern
+# endif
+#endif
+
+#include <stdlib.h>
+
+#ifdef _LTDL_COMPILE_
+typedef struct lt_dlhandle_t *lt_dlhandle;
+#else
+typedef lt_ptr_t lt_dlhandle;
+#endif
+
+typedef struct {
+ const char *name;
+ lt_ptr_t address;
+} lt_dlsymlist;
+
+typedef struct {
+ char *filename; /* file name */
+ char *name; /* module name */
+ int ref_count; /* reference count */
+} lt_dlinfo;
+
+__BEGIN_DECLS
+extern int lt_dlinit LTDL_PARAMS((void));
+extern int lt_dlpreload LTDL_PARAMS((const lt_dlsymlist *preloaded));
+extern int lt_dlpreload_default LTDL_PARAMS((const lt_dlsymlist *preloaded));
+extern int lt_dlexit LTDL_PARAMS((void));
+extern lt_dlhandle lt_dlopen LTDL_PARAMS((const char *filename));
+extern lt_dlhandle lt_dlopenext LTDL_PARAMS((const char *filename));
+extern int lt_dlclose LTDL_PARAMS((lt_dlhandle handle));
+extern lt_ptr_t lt_dlsym LTDL_PARAMS((lt_dlhandle handle, const char *name));
+extern const char *lt_dlerror LTDL_PARAMS((void));
+extern int lt_dladdsearchdir LTDL_PARAMS((const char *search_dir));
+extern int lt_dlsetsearchpath LTDL_PARAMS((const char *search_path));
+extern const char *lt_dlgetsearchpath LTDL_PARAMS((void));
+extern int lt_dlsetdata LTDL_PARAMS((lt_dlhandle handle, lt_ptr_t data));
+extern lt_ptr_t lt_dlgetdata LTDL_PARAMS((lt_dlhandle handle));
+extern const lt_dlinfo *lt_dlgetinfo LTDL_PARAMS((lt_dlhandle handle));
+
+LTDL_SCOPE const lt_dlsymlist lt_preloaded_symbols[];
+#define LTDL_SET_PRELOADED_SYMBOLS() lt_dlpreload_default(lt_preloaded_symbols)
+
+LTDL_SCOPE lt_ptr_t (*lt_dlmalloc)LTDL_PARAMS((size_t size));
+LTDL_SCOPE void (*lt_dlfree)LTDL_PARAMS((lt_ptr_t ptr));
+
+__END_DECLS
+
+#endif /* !_LTDL_H_ */
diff --git a/src/m4.c b/src/m4.c
new file mode 100644
index 00000000..cdb1b74c
--- /dev/null
+++ b/src/m4.c
@@ -0,0 +1,493 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "m4.h"
+
+#include <getopt.h>
+#include <sys/signal.h>
+
+static void usage _((int));
+
+/* Operate interactively (-e). */
+static int interactive = 0;
+
+/* Enable sync output for /lib/cpp (-s). */
+int sync_output = 0;
+
+/* Debug (-d[flags]). */
+int debug_level = 0;
+
+/* Hash table size (should be a prime) (-Hsize). */
+int hash_table_size = HASHMAX;
+
+/* Disable GNU extensions (-G). */
+int no_gnu_extensions = 0;
+
+/* Prefix all builtin functions by `m4_'. */
+int prefix_all_builtins = 0;
+
+/* Max length of arguments in trace output (-lsize). */
+int max_debug_argument_length = 0;
+
+/* Suppress warnings about missing arguments. */
+int suppress_warnings = 0;
+
+/* If not zero, then value of exit status for warning diagnostics. */
+int warning_status = 0;
+
+/* Artificial limit for expansion_level in macro.c. */
+int nesting_limit = 250;
+
+#ifdef ENABLE_CHANGEWORD
+/* User provided regexp for describing m4 words. */
+const char *user_word_regexp = NULL;
+#endif
+
+/* Name of frozen file to digest after initialization. */
+const char *frozen_file_to_read = NULL;
+
+/* Name of frozen file to produce near completion. */
+const char *frozen_file_to_write = NULL;
+
+/* The name this program was run with. */
+const char *program_name;
+
+/* If non-zero, display usage information and exit. */
+static int show_help = 0;
+
+/* If non-zero, print the version on standard output and exit. */
+static int show_version = 0;
+
+struct macro_definition
+{
+ struct macro_definition *next;
+ int code; /* D, U or t */
+ const char *macro;
+};
+typedef struct macro_definition macro_definition;
+
+/* Error handling functions. */
+
+/*-------------------------------------------------------------------------.
+| Print source and line reference on standard error, as a prefix for error |
+| messages. Flush standard output first. |
+`-------------------------------------------------------------------------*/
+
+void
+reference_error (void)
+{
+ fflush (stdout);
+ fprintf (stderr, "%s:%d: ", current_file, current_line);
+}
+
+#ifdef USE_STACKOVF
+
+/*---------------------------------------.
+| Tell user stack overflowed and abort. |
+`---------------------------------------*/
+
+static void
+stackovf_handler (void)
+{
+ M4ERROR ((EXIT_FAILURE, 0,
+ "ERROR: Stack overflow. (Infinite define recursion?)"));
+}
+
+#endif /* USE_STACKOV */
+
+/* Memory allocation. */
+
+/*------------------------.
+| Failsafe free routine. |
+`------------------------*/
+
+void
+xfree (voidstar p)
+{
+ if (p != NULL)
+ free (p);
+}
+
+
+/*---------------------------------------------.
+| Print a usage message and exit with STATUS. |
+`---------------------------------------------*/
+
+static void
+usage (int status)
+{
+ if (status != EXIT_SUCCESS)
+ fprintf (stderr, "Try `%s --help' for more information.\n", program_name);
+ else
+ {
+ printf ("Usage: %s [OPTION]... [FILE]...\n", program_name);
+ 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\
+ -e, --interactive unbuffer output, ignore interrupts\n\
+ -E, --fatal-warnings stop execution after first warning\n\
+ -Q, --quiet, --silent suppress some warnings for builtins\n\
+ -P, --prefix-builtins force a `m4_' prefix to all builtins\n",
+ stdout);
+#ifdef ENABLE_CHANGEWORD
+ fputs ("\
+ -W, --word-regexp=REGEXP use REGEXP for macro name syntax\n",
+ stdout);
+#endif
+ fputs ("\
+\n\
+Preprocessor features:\n\
+ -I, --include=DIRECTORY search this directory second for includes\n\
+ -D, --define=NAME[=VALUE] enter NAME has having VALUE, or empty\n\
+ -U, --undefine=NAME delete builtin NAME\n\
+ -s, --synclines generate `#line NO \"FILE\"' lines\n",
+ stdout);
+ fputs ("\
+\n\
+Limits control:\n\
+ -G, --traditional suppress all GNU extensions\n\
+ -H, --hashsize=PRIME set symbol lookup hash table size\n\
+ -L, --nesting-limit=NUMBER change artificial nesting limit\n",
+ stdout);
+ fputs ("\
+\n\
+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);
+ fputs ("\
+\n\
+Debugging:\n\
+ -d, --debug=[FLAGS] set debug level (no FLAGS implies `aeq')\n\
+ -t, --trace=NAME trace NAME when it will be defined\n\
+ -l, --arglength=NUM restrict macro tracing size\n\
+ -o, --error-output=FILE redirect debug and trace output\n",
+ stdout);
+ fputs ("\
+\n\
+FLAGS is any of:\n\
+ t trace for all macro calls, not only traceon'ed\n\
+ a show actual arguments\n\
+ e show expansion\n\
+ q quote values as necessary, with a or e flag\n\
+ c show before collect, after collect and after call\n\
+ x add a unique macro call id, useful with c flag\n\
+ f say current input file name\n\
+ l say current input line number\n\
+ p show results of path searches\n\
+ i show changes in input files\n\
+ V shorthand for all of the above flags\n",
+ stdout);
+ fputs ("\
+\n\
+If no FILE or if FILE is `-', standard input is read.\n",
+ stdout);
+ }
+ exit (status);
+}
+
+/*--------------------------------------.
+| Decode options and launch execution. |
+`--------------------------------------*/
+
+static const struct option long_options[] =
+{
+ {"arglength", required_argument, NULL, 'l'},
+ {"debug", optional_argument, NULL, 'd'},
+ {"diversions", required_argument, NULL, 'N'},
+ {"error-output", required_argument, NULL, 'o'},
+ {"fatal-warnings", no_argument, NULL, 'E'},
+ {"freeze-state", required_argument, NULL, 'F'},
+ {"hashsize", required_argument, NULL, 'H'},
+ {"include", required_argument, NULL, 'I'},
+ {"interactive", no_argument, NULL, 'e'},
+ {"nesting-limit", required_argument, NULL, 'L'},
+ {"prefix-builtins", no_argument, NULL, 'P'},
+ {"quiet", no_argument, NULL, 'Q'},
+ {"reload-state", required_argument, NULL, 'R'},
+ {"silent", no_argument, NULL, 'Q'},
+ {"synclines", no_argument, NULL, 's'},
+ {"traditional", no_argument, NULL, 'G'},
+ {"word-regexp", required_argument, NULL, 'W'},
+
+ {"help", no_argument, &show_help, 1},
+ {"version", no_argument, &show_version, 1},
+
+ /* These are somewhat troublesome. */
+ { "define", required_argument, NULL, 'D' },
+ { "undefine", required_argument, NULL, 'U' },
+ { "trace", required_argument, NULL, 't' },
+
+ { 0, 0, 0, 0 },
+};
+
+#ifdef ENABLE_CHANGEWORD
+#define OPTSTRING "B:D:EF:GH:I:L:N:PQR:S:T:U:W:d::el:o:st:"
+#else
+#define OPTSTRING "B:D:EF:GH:I:L:N:PQR:S:T:U:d::el:o:st:"
+#endif
+
+int
+main (int argc, char *const *argv, char *const *envp)
+{
+ macro_definition *head; /* head of deferred argument list */
+ macro_definition *tail;
+ macro_definition *new;
+ int optchar; /* option character */
+
+ macro_definition *defines;
+ FILE *fp;
+
+ program_name = argv[0];
+
+ include_init ();
+ debug_init ();
+#ifdef USE_STACKOVF
+ setup_stackovf_trap (argv, envp, stackovf_handler);
+#endif
+
+ /* First, we decode the arguments, to size up tables and stuff. */
+
+ head = tail = NULL;
+
+ while (optchar = getopt_long (argc, argv, OPTSTRING, long_options, NULL),
+ optchar != EOF)
+ switch (optchar)
+ {
+ default:
+ usage (EXIT_FAILURE);
+
+ case 0:
+ break;
+
+ case 'B': /* compatibility junk */
+ case 'N':
+ case 'S':
+ case 'T':
+ break;
+
+ case 'D':
+ case 'U':
+ case 't':
+
+ /* Arguments that cannot be handled until later are accumulated. */
+
+ new = (macro_definition *) xmalloc (sizeof (macro_definition));
+ new->code = optchar;
+ new->macro = optarg;
+ new->next = NULL;
+
+ if (head == NULL)
+ head = new;
+ else
+ tail->next = new;
+ tail = new;
+
+ break;
+
+ case 'E':
+ warning_status = EXIT_FAILURE;
+ break;
+
+ case 'F':
+ frozen_file_to_write = optarg;
+ break;
+
+ case 'G':
+ no_gnu_extensions = 1;
+ break;
+
+ case 'H':
+ hash_table_size = atoi (optarg);
+ if (hash_table_size <= 0)
+ hash_table_size = HASHMAX;
+ break;
+
+ case 'I':
+ add_include_directory (optarg);
+ break;
+
+ case 'L':
+ nesting_limit = atoi (optarg);
+ break;
+
+ case 'P':
+ prefix_all_builtins = 1;
+ break;
+
+ case 'Q':
+ suppress_warnings = 1;
+ break;
+
+ case 'R':
+ frozen_file_to_read = optarg;
+ break;
+
+#ifdef ENABLE_CHANGEWORD
+ case 'W':
+ user_word_regexp = optarg;
+ break;
+#endif
+
+ case 'd':
+ debug_level = debug_decode (optarg);
+ if (debug_level < 0)
+ {
+ error (0, 0, "bad debug flags: `%s'", optarg);
+ debug_level = 0;
+ }
+ break;
+
+ case 'e':
+ interactive = 1;
+ break;
+
+ case 'l':
+ max_debug_argument_length = atoi (optarg);
+ if (max_debug_argument_length <= 0)
+ max_debug_argument_length = 0;
+ break;
+
+ case 'o':
+ if (!debug_set_output (optarg))
+ error (0, errno, optarg);
+ break;
+
+ case 's':
+ sync_output = 1;
+ break;
+ }
+
+ if (show_version)
+ {
+ printf ("GNU %s %s\n", PRODUCT, VERSION);
+ exit (EXIT_SUCCESS);
+ }
+
+ if (show_help)
+ usage (EXIT_SUCCESS);
+
+ defines = head;
+
+ /* Do the basic initialisations. */
+
+ input_init ();
+ output_init ();
+ symtab_init ();
+ include_env_init ();
+
+ if (frozen_file_to_read)
+ reload_frozen_state (frozen_file_to_read);
+ else
+ builtin_init ();
+
+ /* Handle deferred command line macro definitions. Must come after
+ initialisation of the symbol table. */
+
+ while (defines != NULL)
+ {
+ macro_definition *next;
+ char *macro_value;
+ symbol *sym;
+
+ switch (defines->code)
+ {
+ case 'D':
+ macro_value = strchr (defines->macro, '=');
+ if (macro_value == NULL)
+ macro_value = "";
+ else
+ *macro_value++ = '\0';
+ define_user_macro (defines->macro, macro_value, SYMBOL_INSERT);
+ break;
+
+ case 'U':
+ lookup_symbol (defines->macro, SYMBOL_DELETE);
+ break;
+
+ case 't':
+ sym = lookup_symbol (defines->macro, SYMBOL_INSERT);
+ SYMBOL_TRACED (sym) = TRUE;
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad code in deferred arguments"));
+ abort ();
+ }
+
+ next = defines->next;
+ xfree ((voidstar) defines);
+ defines = next;
+ }
+
+ /* Interactive mode means unbuffered output, and interrupts ignored. */
+
+ if (interactive)
+ {
+ signal (SIGINT, SIG_IGN);
+ setbuf (stdout, (char *) NULL);
+ }
+
+ /* Handle the various input files. Each file is pushed on the input,
+ and the input read. Wrapup text is handled separately later. */
+
+ if (optind == argc)
+ {
+ push_file (stdin, "stdin");
+ expand_input ();
+ }
+ else
+ for (; optind < argc; optind++)
+ {
+ if (strcmp (argv[optind], "-") == 0)
+ push_file (stdin, "stdin");
+ else
+ {
+ fp = path_search (argv[optind]);
+ if (fp == NULL)
+ {
+ error (0, errno, argv[optind]);
+ continue;
+ }
+ else
+ push_file (fp, argv[optind]);
+ }
+ expand_input ();
+ }
+#undef NEXTARG
+
+ /* Now handle wrapup text. */
+
+ while (pop_wrapup ())
+ expand_input ();
+
+ if (frozen_file_to_write)
+ produce_frozen_state (frozen_file_to_write);
+ else
+ {
+ make_diversion (0);
+ undivert_all ();
+ }
+
+ exit (EXIT_SUCCESS);
+}
diff --git a/src/m4.h b/src/m4.h
new file mode 100644
index 00000000..feb37573
--- /dev/null
+++ b/src/m4.h
@@ -0,0 +1,475 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* We use <config.h> instead of "config.h" so that a compilation
+ using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
+ (which it would do because it found this file in $srcdir). */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <sys/types.h>
+
+#if __STDC__
+# define voidstar void *
+#else
+# define voidstar char *
+#endif
+
+#ifdef PROTOTYPES
+# define _(Args) Args
+#else
+# define _(Args) ()
+#endif
+
+#include <stdio.h>
+#include <ctype.h>
+
+#include "obstack.h"
+
+/* An ANSI string.h and pre-ANSI memory.h might conflict. */
+
+#if defined (HAVE_STRING_H) || defined (STDC_HEADERS)
+# include <string.h>
+# if !defined (STDC_HEADERS) && defined (HAVE_MEMORY_H)
+# include <memory.h>
+# endif
+/* This is for obstack code -- should live in obstack.h. */
+# ifndef bcopy
+# define bcopy(S, D, N) memcpy ((D), (S), (N))
+# endif
+#else
+# include <strings.h>
+# ifndef memcpy
+# define memcpy(D, S, N) bcopy((S), (D), (N))
+# endif
+# ifndef strchr
+# define strchr(S, C) index ((S), (C))
+# endif
+# ifndef strrchr
+# define strrchr(S, C) rindex ((S), (C))
+# endif
+# ifndef bcopy
+void bcopy ();
+# endif
+#endif
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+#else /* not STDC_HEADERS */
+
+voidstar malloc ();
+voidstar realloc ();
+char *getenv ();
+double atof ();
+long strtol ();
+
+#endif /* STDC_HEADERS */
+
+/* Some systems do not define EXIT_*, even with STDC_HEADERS. */
+#ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+#endif
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#endif
+
+#include <errno.h>
+#ifndef errno
+extern int errno;
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+/* If FALSE is defined, we presume TRUE is defined too. In this case,
+ merely typedef boolean as being int. Or else, define these all. */
+#ifndef FALSE
+/* Do not use `enum boolean': this tag is used in SVR4 <sys/types.h>. */
+typedef enum { FALSE = 0, TRUE = 1 } boolean;
+#else
+typedef int boolean;
+#endif
+
+char *mktemp ();
+
+/* Various declarations. */
+
+struct string
+ {
+ char *string; /* characters of the string */
+ size_t length; /* length of the string */
+ };
+typedef struct string STRING;
+
+/* Memory allocation. */
+voidstar xmalloc _((unsigned int));
+voidstar xrealloc _((voidstar , unsigned int));
+void xfree _((voidstar));
+char *xstrdup _((const char *));
+#define obstack_chunk_alloc xmalloc
+#define obstack_chunk_free xfree
+
+/* Other library routines. */
+void error _((int, int, const char *, ...));
+
+/* Those must come first. */
+typedef void builtin_func ();
+typedef struct token_data token_data;
+
+/* File: m4.c --- global definitions. */
+
+/* Option flags. */
+extern int sync_output; /* -s */
+extern int debug_level; /* -d */
+extern int hash_table_size; /* -H */
+extern int no_gnu_extensions; /* -G */
+extern int prefix_all_builtins; /* -P */
+extern int max_debug_argument_length; /* -l */
+extern int suppress_warnings; /* -Q */
+extern int warning_status; /* -E */
+extern int nesting_limit; /* -L */
+#ifdef ENABLE_CHANGEWORD
+extern const char *user_word_regexp; /* -W */
+#endif
+
+/* Error handling. */
+#define M4ERROR(Arglist) \
+ (reference_error (), error Arglist)
+
+void reference_error _((void));
+
+#ifdef USE_STACKOVF
+void setup_stackovf_trap _((char *const *, char *const *,
+ void (*handler) (void)));
+#endif
+
+/* File: debug.c --- debugging and tracing function. */
+
+extern FILE *debug;
+
+/* The value of debug_level is a bitmask of the following. */
+
+/* a: show arglist in trace output */
+#define DEBUG_TRACE_ARGS 1
+/* e: show expansion in trace output */
+#define DEBUG_TRACE_EXPANSION 2
+/* q: quote args and expansion in trace output */
+#define DEBUG_TRACE_QUOTE 4
+/* t: trace all macros -- overrides trace{on,off} */
+#define DEBUG_TRACE_ALL 8
+/* l: add line numbers to trace output */
+#define DEBUG_TRACE_LINE 16
+/* f: add file name to trace output */
+#define DEBUG_TRACE_FILE 32
+/* p: trace path search of include files */
+#define DEBUG_TRACE_PATH 64
+/* c: show macro call before args collection */
+#define DEBUG_TRACE_CALL 128
+/* i: trace changes of input files */
+#define DEBUG_TRACE_INPUT 256
+/* x: add call id to trace output */
+#define DEBUG_TRACE_CALLID 512
+
+/* V: very verbose -- print everything */
+#define DEBUG_TRACE_VERBOSE 1023
+/* default flags -- equiv: aeq */
+#define DEBUG_TRACE_DEFAULT 7
+
+#define DEBUG_PRINT1(Fmt, Arg1) \
+ do \
+ { \
+ if (debug != NULL) \
+ fprintf (debug, Fmt, Arg1); \
+ } \
+ while (0)
+
+#define DEBUG_PRINT3(Fmt, Arg1, Arg2, Arg3) \
+ do \
+ { \
+ if (debug != NULL) \
+ fprintf (debug, Fmt, Arg1, Arg2, Arg3); \
+ } \
+ while (0)
+
+#define DEBUG_MESSAGE(Fmt) \
+ do \
+ { \
+ if (debug != NULL) \
+ { \
+ debug_message_prefix (); \
+ fprintf (debug, Fmt); \
+ putc ('\n', debug); \
+ } \
+ } \
+ while (0)
+
+#define DEBUG_MESSAGE1(Fmt, Arg1) \
+ do \
+ { \
+ if (debug != NULL) \
+ { \
+ debug_message_prefix (); \
+ fprintf (debug, Fmt, Arg1); \
+ putc ('\n', debug); \
+ } \
+ } \
+ while (0)
+
+#define DEBUG_MESSAGE2(Fmt, Arg1, Arg2) \
+ do \
+ { \
+ if (debug != NULL) \
+ { \
+ debug_message_prefix (); \
+ fprintf (debug, Fmt, Arg1, Arg2); \
+ putc ('\n', debug); \
+ } \
+ } \
+ while (0)
+
+void debug_init _((void));
+int debug_decode _((const char *));
+void debug_flush_files _((void));
+boolean debug_set_output _((const char *));
+void debug_message_prefix _((void));
+
+void trace_prepre _((const char *, int));
+void trace_pre _((const char *, int, int, token_data **));
+void trace_post _((const char *, int, int, token_data **, const char *));
+
+/* File: input.c --- lexical definitions. */
+
+/* Various different token types. */
+enum token_type
+{
+ TOKEN_EOF, /* end of file */
+ TOKEN_STRING, /* a quoted string */
+ TOKEN_WORD, /* an identifier */
+ TOKEN_SIMPLE, /* a single character */
+ TOKEN_MACDEF /* a macros definition (see "defn") */
+};
+
+/* The data for a token, a macro argument, and a macro definition. */
+enum token_data_type
+{
+ TOKEN_VOID,
+ TOKEN_TEXT,
+ TOKEN_FUNC
+};
+
+struct token_data
+{
+ enum token_data_type type;
+ union
+ {
+ struct
+ {
+ char *text;
+#ifdef ENABLE_CHANGEWORD
+ char *original_text;
+#endif
+ }
+ u_t;
+ struct
+ {
+ builtin_func *func;
+ boolean traced;
+ }
+ u_f;
+ }
+ u;
+};
+
+#define TOKEN_DATA_TYPE(Td) ((Td)->type)
+#define TOKEN_DATA_TEXT(Td) ((Td)->u.u_t.text)
+#ifdef ENABLE_CHANGEWORD
+# define TOKEN_DATA_ORIG_TEXT(Td) ((Td)->u.u_t.original_text)
+#endif
+#define TOKEN_DATA_FUNC(Td) ((Td)->u.u_f.func)
+#define TOKEN_DATA_FUNC_TRACED(Td) ((Td)->u.u_f.traced)
+
+typedef enum token_type token_type;
+typedef enum token_data_type token_data_type;
+
+void input_init _((void));
+int peek_input _((void));
+token_type next_token _((token_data *));
+void skip_line _((void));
+
+/* push back input */
+void push_file _((FILE *, const char *));
+void push_macro _((builtin_func *, boolean));
+struct obstack *push_string_init _((void));
+const char *push_string_finish _((void));
+void push_wrapup _((const char *));
+boolean pop_wrapup _((void));
+
+/* current input file, and line */
+extern const char *current_file;
+extern int current_line;
+
+/* left and right quote, begin and end comment */
+extern STRING bcomm, ecomm;
+extern STRING lquote, rquote;
+
+#define DEF_LQUOTE "`"
+#define DEF_RQUOTE "\'"
+#define DEF_BCOMM "#"
+#define DEF_ECOMM "\n"
+
+void set_quotes _((const char *, const char *));
+void set_comment _((const char *, const char *));
+#ifdef ENABLE_CHANGEWORD
+void set_word_regexp _((const char *));
+#endif
+
+/* File: output.c --- output functions. */
+extern int current_diversion;
+extern int output_current_line;
+
+void output_init _((void));
+void shipout_text _((struct obstack *, const char *, int));
+void make_diversion _((int));
+void insert_diversion _((int));
+void insert_file _((FILE *));
+void freeze_diversions _((FILE *));
+
+/* File symtab.c --- symbol table definitions. */
+
+/* Operation modes for lookup_symbol (). */
+enum symbol_lookup
+{
+ SYMBOL_LOOKUP,
+ SYMBOL_INSERT,
+ SYMBOL_DELETE,
+ SYMBOL_PUSHDEF,
+ SYMBOL_POPDEF
+};
+
+/* Symbol table entry. */
+struct symbol
+{
+ struct symbol *next;
+ boolean traced;
+ boolean shadowed;
+ boolean macro_args;
+ boolean blind_no_args;
+
+ char *name;
+ token_data data;
+};
+
+#define SYMBOL_NEXT(S) ((S)->next)
+#define SYMBOL_TRACED(S) ((S)->traced)
+#define SYMBOL_SHADOWED(S) ((S)->shadowed)
+#define SYMBOL_MACRO_ARGS(S) ((S)->macro_args)
+#define SYMBOL_BLIND_NO_ARGS(S) ((S)->blind_no_args)
+#define SYMBOL_NAME(S) ((S)->name)
+#define SYMBOL_TYPE(S) (TOKEN_DATA_TYPE (&(S)->data))
+#define SYMBOL_TEXT(S) (TOKEN_DATA_TEXT (&(S)->data))
+#define SYMBOL_FUNC(S) (TOKEN_DATA_FUNC (&(S)->data))
+
+typedef enum symbol_lookup symbol_lookup;
+typedef struct symbol symbol;
+typedef void hack_symbol ();
+
+#define HASHMAX 509 /* default, overridden by -Hsize */
+
+extern symbol **symtab;
+
+void symtab_init _((void));
+symbol *lookup_symbol _((const char *, symbol_lookup));
+void hack_all_symbols _((hack_symbol *, const char *));
+
+/* File: macro.c --- macro expansion. */
+
+void expand_input _((void));
+void call_macro _((symbol *, int, token_data **, struct obstack *));
+
+/* File: builtin.c --- builtins. */
+
+struct builtin
+{
+ const char *name;
+ boolean gnu_extension;
+ boolean groks_macro_args;
+ boolean blind_if_no_args;
+ builtin_func *func;
+};
+
+struct predefined
+{
+ const char *unix_name;
+ const char *gnu_name;
+ const char *func;
+};
+
+typedef struct builtin builtin;
+typedef struct predefined predefined;
+
+void builtin_init _((void));
+void define_builtin _((const char *, const builtin *, symbol_lookup, boolean));
+void define_user_macro _((const char *, const char *, symbol_lookup));
+void undivert_all _((void));
+void expand_user_macro _((struct obstack *, symbol *, int, token_data **));
+
+const builtin *find_builtin_by_addr _((builtin_func *));
+const builtin *find_builtin_by_name _((const char *));
+
+/* File: path.c --- path search for include files. */
+
+void include_init _((void));
+void include_env_init _((void));
+void add_include_directory _((const char *));
+FILE *path_search _((const char *));
+
+/* File: eval.c --- expression evaluation. */
+
+/* eval_t and unsigned_eval_t should be at least 32 bits. */
+typedef int eval_t;
+typedef unsigned int unsigned_eval_t;
+
+boolean evaluate _((const char *, eval_t *));
+
+/* File: format.c --- printf like formatting. */
+
+void format _((struct obstack *, int, token_data **));
+
+/* File: freeze.c --- frozen state files. */
+
+void produce_frozen_state _((const char *));
+void reload_frozen_state _((const char *));
+
+/* Debugging the memory allocator. */
+
+#ifdef WITH_DMALLOC
+# define DMALLOC_FUNC_CHECK
+# include <dmalloc.h>
+#endif
+
+/* Other debug stuff. */
+
+#ifdef DEBUG
+# define DEBUG_INPUT
+# define DEBUG_MACRO
+# define DEBUG_SYM
+# define DEBUG_INCL
+#endif
diff --git a/src/macro.c b/src/macro.c
new file mode 100644
index 00000000..16cfa6cf
--- /dev/null
+++ b/src/macro.c
@@ -0,0 +1,316 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* This file contains the functions, that performs the basic argument
+ parsing and macro expansion. */
+
+#include "m4.h"
+
+static void expand_macro _((symbol *));
+static void expand_token _((struct obstack *, token_type, token_data *));
+
+/* Current recursion level in expand_macro (). */
+int expansion_level = 0;
+
+/* The number of the current call of expand_macro (). */
+static int macro_call_id = 0;
+
+/*----------------------------------------------------------------------.
+| This function read all input, and expands each token, one at a time. |
+`----------------------------------------------------------------------*/
+
+void
+expand_input (void)
+{
+ token_type t;
+ token_data td;
+
+ while ((t = next_token (&td)) != TOKEN_EOF)
+ expand_token ((struct obstack *) NULL, t, &td);
+}
+
+
+/*------------------------------------------------------------------------.
+| Expand one token, according to its type. Potential macro names |
+| (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. |
+`------------------------------------------------------------------------*/
+
+static void
+expand_token (struct obstack *obs, token_type t, token_data *td)
+{
+ symbol *sym;
+
+ switch (t)
+ { /* TOKSW */
+ case TOKEN_EOF:
+ case TOKEN_MACDEF:
+ break;
+
+ case TOKEN_SIMPLE:
+ case TOKEN_STRING:
+ shipout_text (obs, TOKEN_DATA_TEXT (td), strlen (TOKEN_DATA_TEXT (td)));
+ break;
+
+ case TOKEN_WORD:
+ sym = lookup_symbol (TOKEN_DATA_TEXT (td), SYMBOL_LOOKUP);
+ if (sym == NULL || SYMBOL_TYPE (sym) == TOKEN_VOID
+ || (SYMBOL_TYPE (sym) == TOKEN_FUNC
+ && SYMBOL_BLIND_NO_ARGS (sym)
+ && peek_input () != '('))
+ {
+#ifdef ENABLE_CHANGEWORD
+ shipout_text (obs, TOKEN_DATA_ORIG_TEXT (td),
+ strlen (TOKEN_DATA_ORIG_TEXT (td)));
+#else
+ shipout_text (obs, TOKEN_DATA_TEXT (td),
+ strlen (TOKEN_DATA_TEXT (td)));
+#endif
+ }
+ else
+ expand_macro (sym);
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad token type in expand_token ()"));
+ abort ();
+ }
+}
+
+
+/*-------------------------------------------------------------------------.
+| 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, and reads and expands tokens, |
+| until it finds a comma or an right parenthesis at the same level of |
+| parentheses. It returns a flag indicating whether the argument read are |
+| the last for the active macro call. The argument are build on the |
+| obstack OBS, indirectly through expand_token (). |
+`-------------------------------------------------------------------------*/
+
+static boolean
+expand_argument (struct obstack *obs, token_data *argp)
+{
+ token_type t;
+ token_data td;
+ char *text;
+ int paren_level;
+
+ TOKEN_DATA_TYPE (argp) = TOKEN_VOID;
+
+ /* Skip leading white space. */
+ do
+ {
+ t = next_token (&td);
+ }
+ while (t == TOKEN_SIMPLE && isspace (*TOKEN_DATA_TEXT (&td)));
+
+ paren_level = 0;
+
+ while (1)
+ {
+
+ switch (t)
+ { /* TOKSW */
+ case TOKEN_SIMPLE:
+ text = TOKEN_DATA_TEXT (&td);
+ if ((*text == ',' || *text == ')') && paren_level == 0)
+ {
+
+ /* The argument MUST be finished, whether we want it or not. */
+ obstack_1grow (obs, '\0');
+ text = obstack_finish (obs);
+
+ if (TOKEN_DATA_TYPE (argp) == TOKEN_VOID)
+ {
+ TOKEN_DATA_TYPE (argp) = TOKEN_TEXT;
+ TOKEN_DATA_TEXT (argp) = text;
+ }
+ return (boolean) (*TOKEN_DATA_TEXT (&td) == ',');
+ }
+
+ if (*text == '(')
+ paren_level++;
+ else if (*text == ')')
+ paren_level--;
+ expand_token (obs, t, &td);
+ break;
+
+ case TOKEN_EOF:
+ M4ERROR ((EXIT_FAILURE, 0,
+ "ERROR: EOF in argument list"));
+ break;
+
+ case TOKEN_WORD:
+ case TOKEN_STRING:
+ expand_token (obs, t, &td);
+ break;
+
+ case TOKEN_MACDEF:
+ if (obstack_object_size (obs) == 0)
+ {
+ TOKEN_DATA_TYPE (argp) = TOKEN_FUNC;
+ TOKEN_DATA_FUNC (argp) = TOKEN_DATA_FUNC (&td);
+ TOKEN_DATA_FUNC_TRACED (argp) = TOKEN_DATA_FUNC_TRACED (&td);
+ }
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad token type in expand_argument ()"));
+ abort ();
+ }
+
+ t = next_token (&td);
+ }
+}
+
+/*-------------------------------------------------------------------------.
+| Collect all the arguments to a call of the macro SYM. The arguments are |
+| stored on the obstack ARGUMENTS and a table of pointers to the arguments |
+| on the obstack ARGPTR. |
+`-------------------------------------------------------------------------*/
+
+static void
+collect_arguments (symbol *sym, struct obstack *argptr,
+ struct obstack *arguments)
+{
+ int ch; /* lookahead for ( */
+ token_data td;
+ token_data *tdp;
+ boolean more_args;
+ boolean groks_macro_args = SYMBOL_MACRO_ARGS (sym);
+
+ TOKEN_DATA_TYPE (&td) = TOKEN_TEXT;
+ TOKEN_DATA_TEXT (&td) = SYMBOL_NAME (sym);
+ tdp = (token_data *) obstack_copy (arguments, (voidstar) &td, sizeof (td));
+ obstack_grow (argptr, (voidstar) &tdp, sizeof (tdp));
+
+ ch = peek_input ();
+ if (ch == '(')
+ {
+ next_token (&td); /* gobble parenthesis */
+ do
+ {
+ more_args = expand_argument (arguments, &td);
+
+ if (!groks_macro_args && TOKEN_DATA_TYPE (&td) == TOKEN_FUNC)
+ {
+ TOKEN_DATA_TYPE (&td) = TOKEN_TEXT;
+ TOKEN_DATA_TEXT (&td) = "";
+ }
+ tdp = (token_data *)
+ obstack_copy (arguments, (voidstar) &td, sizeof (td));
+ obstack_grow (argptr, (voidstar) &tdp, sizeof (tdp));
+ }
+ while (more_args);
+ }
+}
+
+
+/*------------------------------------------------------------------------.
+| The actual call of a macro is handled by call_macro (). call_macro () |
+| is passed a symbol SYM, whose type is used to call either a builtin |
+| function, or the user macro expansion function expand_user_macro () |
+| (lives in builtin.c). There are ARGC arguments to the call, stored in |
+| the ARGV table. The expansion is left on the obstack EXPANSION. Macro |
+| tracing is also handled here. |
+`------------------------------------------------------------------------*/
+
+void
+call_macro (symbol *sym, int argc, token_data **argv,
+ struct obstack *expansion)
+{
+ switch (SYMBOL_TYPE (sym))
+ {
+ case TOKEN_FUNC:
+ (*SYMBOL_FUNC (sym)) (expansion, argc, argv);
+ break;
+
+ case TOKEN_TEXT:
+ expand_user_macro (expansion, sym, argc, argv);
+ break;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Bad symbol type in call_macro ()"));
+ abort ();
+ }
+}
+
+/*-------------------------------------------------------------------------.
+| 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 call_macro () 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 (). |
+`-------------------------------------------------------------------------*/
+
+static void
+expand_macro (symbol *sym)
+{
+ struct obstack arguments;
+ struct obstack argptr;
+ token_data **argv;
+ int argc;
+ struct obstack *expansion;
+ const char *expanded;
+ boolean traced;
+ int my_call_id;
+
+ expansion_level++;
+ if (expansion_level > nesting_limit)
+ M4ERROR ((EXIT_FAILURE, 0,
+ "ERROR: Recursion limit of %d exceeded, use -L<N> to change it",
+ nesting_limit));
+
+ macro_call_id++;
+ my_call_id = macro_call_id;
+
+ traced = (boolean) ((debug_level & DEBUG_TRACE_ALL) || SYMBOL_TRACED (sym));
+
+ obstack_init (&argptr);
+ obstack_init (&arguments);
+
+ if (traced && (debug_level & DEBUG_TRACE_CALL))
+ trace_prepre (SYMBOL_NAME (sym), my_call_id);
+
+ collect_arguments (sym, &argptr, &arguments);
+
+ argc = obstack_object_size (&argptr) / sizeof (token_data *);
+ argv = (token_data **) obstack_finish (&argptr);
+
+ if (traced)
+ trace_pre (SYMBOL_NAME (sym), my_call_id, argc, argv);
+
+ expansion = push_string_init ();
+ call_macro (sym, argc, argv, expansion);
+ expanded = push_string_finish ();
+
+ if (traced)
+ trace_post (SYMBOL_NAME (sym), my_call_id, argc, argv, expanded);
+
+ --expansion_level;
+
+ obstack_free (&arguments, NULL);
+ obstack_free (&argptr, NULL);
+}
diff --git a/src/module.c b/src/module.c
new file mode 100644
index 00000000..fb42884c
--- /dev/null
+++ b/src/module.c
@@ -0,0 +1,206 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1998 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "m4.h"
+
+#ifdef WITH_MODULES
+
+#define DEBUG_MODULES
+#undef DEBUG_MODULES
+
+/*
+ * This file implements dynamic modules in GNU m4. A module is a
+ * compiled shared object, that can be linked into GNU m4 at run
+ * time. Information about creating modules is in ../modules/README.
+ *
+ * The current implementation uses dlopen(3). To enable this
+ * experimental feature give configure the `--with-modules' switch.
+ * This implementation is only tested on Linux.
+ *
+ * A m4 module need only define one external symbol, called
+ * `m4_macro_table'. This symbol should point to a table of `struct
+ * builtin' exactly as the one in builtin.c. This table is pushed on a
+ * list of builtin tables and each definition therein is added to the
+ * symbol table.
+ *
+ * The code implementing loadable modules is modest. It is divided
+ * between the files path.c (search in module path), builtin.c (user
+ * interface and support for multiple builtin tables) and this file (OS
+ * dependant routines).
+ *
+ * To load a module, use `loadmodule(modulename.so)', where .so is the
+ * normal extention for shared object files. The function
+ * `m4_loadmodule' calls module_load() in this file, which uses
+ * module_search() in path.c to find the module in the module search
+ * path. This path is initialised from the environment variable
+ * M4MODPATH, and cannot be modified in any way. Module_search()
+ * constructs absolute file names and calls module_try_load() in this
+ * file. This function returns NULL on failure and a non-NULL void* on
+ * success. If succesful module_search() returns the value of this
+ * void*, which is a handle for the vm segment mapped. Module_load()
+ * checks to see if the module is alreay loaded, and if not, retrives
+ * the symbol `m4_macro_table' and returns it's value to
+ * m4_loadmodule(). This pointer should be a builtin*, which is
+ * installed using install_builtin_table().
+ *
+ * When a module is loaded, the function "void m4_init_module(struct
+ * obstack *obs)" is called, if defined. Any non NULL return value of
+ * this function will be the expansion of "loadmodule". Before program
+ * exit, all modules are unloaded and the function "void
+ * m4_finish_module(void)" is called, if defined.
+ *
+ * There is no way to unload a module unless at program exit. It is
+ * safe to load the same module several times, it has no effect.
+ **/
+
+#include <dlfcn.h>
+
+/* This list is used to check for repeated loading of the same modules. */
+
+struct module_list {
+ struct module_list *next;
+ char *modname;
+ void *handle;
+};
+
+typedef struct module_list module_list;
+
+static module_list *modules;
+
+/*
+ * Initialisation. Currently the module search path in path.c is
+ * initialised from M4MODPATH. Only absolute path names are accepted to
+ * prevent the path search of the dlopen library from finding wrong
+ * files.
+ */
+void
+module_init (void)
+{
+ module_env_init ();
+}
+
+/*
+ * Attempt to load a module with a absolute file name. It is used as a
+ * callback from module_search() in path.c.
+ */
+voidstar
+module_try_load (const char *modname)
+{
+ return dlopen (modname, RTLD_NOW);
+}
+
+
+/*
+ * Load a module. Modname can be a absolute file name or, if relative,
+ * is is searched in the module path. Return value is the value of the
+ * symbol `m4_macro_table' in the module. The module is unloaded in
+ * case of error. The builtins from the module are installed in the
+ * symbol table by the caller, m4_loadmodule() in builtin.c.
+ */
+
+struct builtin *
+module_load (const char *modname, struct obstack *obs)
+{
+ void *handle;
+ struct module_list *list;
+
+ builtin *btab;
+ module_init_t *init_func;
+
+ handle = module_search(modname, module_try_load);
+ if (handle == NULL)
+ {
+ M4ERROR ((1, 0, _("Error: cannot find module `%s'"), modname));
+ }
+
+ for (list = modules; list != NULL; list = list->next)
+ if (list->handle == handle)
+ {
+#ifdef DEBUG_MODULES
+ DEBUG_MESSAGE1("module %s handle already seen", modname);
+#endif /* DEBUG_MODULES */
+ dlclose(handle);
+ return NULL;
+ }
+
+ btab = (builtin *) dlsym (handle, "m4_macro_table");
+ if (btab == NULL) {
+#ifdef DEBUG_MODULES
+ DEBUG_MESSAGE1("module %s no symbol m4_macro_table", modname);
+#endif /* DEBUG_MODULES */
+ dlclose(handle);
+ return NULL;
+ }
+
+ list = xmalloc (sizeof (struct module_list));
+ list->next = modules;
+ list->modname = xstrdup(modname);
+ list->handle = handle;
+ modules = list;
+
+#ifdef DEBUG_MODULES
+ DEBUG_MESSAGE1("module %s loaded ok", modname);
+#endif /* DEBUG_MODULES */
+
+ init_func = (module_init_t *) dlsym (handle, "m4_init_module");
+ if (init_func != NULL)
+ {
+ (*init_func)(obs);
+
+#ifdef DEBUG_MODULES
+ DEBUG_MESSAGE1("module %s init hook called", modname);
+#endif /* DEBUG_MODULES */
+ }
+
+ return btab;
+}
+
+void
+module_unload_all(void)
+{
+ struct module_list *next;
+ module_finish_t *finish_func;
+
+ while (modules != NULL)
+ {
+ finish_func = (module_finish_t *) dlsym (modules->handle,
+ "m4_finish_module");
+ if (finish_func != NULL)
+ {
+ (*finish_func)();
+
+#ifdef DEBUG_MODULES
+ DEBUG_MESSAGE1("module %s finish hook called", modules->modname);
+#endif /* DEBUG_MODULES */
+ }
+
+ dlclose(modules->handle);
+
+#ifdef DEBUG_MODULES
+ DEBUG_MESSAGE1("module %s unloaded", modules->modname);
+#endif /* DEBUG_MODULES */
+
+ next = modules->next;
+ xfree(modules);
+ modules = next;
+ }
+}
+
+
+
+#endif /* WITH_MODULES */
diff --git a/src/numb.c b/src/numb.c
new file mode 100644
index 00000000..8dfa077e
--- /dev/null
+++ b/src/numb.c
@@ -0,0 +1,418 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1995, 1998 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* This file contains the functions to evaluate integer or multiple
+ precision expressions for the "eval" macro.
+ */
+
+#include "m4.h"
+#include "numb.h"
+
+
+#ifdef WITH_GMP
+
+eval_t numb_ZERO;
+eval_t numb_ONE;
+
+static int numb_initialised = 0;
+
+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;
+}
+
+void
+numb_obstack(struct obstack *obs, const eval_t value,
+ const int radix, int min)
+{
+ const char *s;
+
+ mpz_t i;
+ mpz_init(i);
+
+ mpq_get_num(i,value);
+ s = mpz_get_str((char *)0, radix, i);
+
+ if (*s == '-')
+ {
+ obstack_1grow (obs, '-');
+ min--;
+ s++;
+ }
+ for (min -= strlen (s); --min >= 0;)
+ obstack_1grow (obs, '0');
+
+ obstack_grow (obs, s, strlen (s));
+
+ 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(mpz_t z, const eval_t q, const char *noisily)
+{
+ if (noisily && mpz_cmp_si(mpq_denref(q),(long)1)!=0) {
+ M4ERROR((warning_status, 0,
+ _("Loss of precision in eval: %s"),
+ noisily));
+ }
+ mpz_div(z,mpq_numref(q),mpq_denref(q));
+}
+
+static void
+mpz2mpq(eval_t q, const mpz_t z)
+{
+ mpq_set_si(q,(long)0,(unsigned long)1);
+ mpq_set_num(q,z);
+}
+
+void
+numb_divide(eval_t *x, const eval_t *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);
+}
+
+void
+numb_modulo(eval_t *x, const eval_t *y)
+{
+ mpz_t xx, yy, res;
+
+ /* x should be integral */
+ /* y should be integral */
+
+ mpz_init(xx);
+ mpq2mpz(xx,*x,NOISY);
+
+ mpz_init(yy);
+ mpq2mpz(yy,*y,NOISY);
+
+ mpz_init(res);
+ mpz_mod(res,xx,yy);
+
+ mpz_clear(xx);
+ mpz_clear(yy);
+
+ mpz2mpq(*x,res);
+ mpz_clear(res);
+}
+
+void
+numb_and(eval_t *x, const eval_t *y)
+{
+ mpz_t xx, yy, res;
+
+ /* x should be integral */
+ /* y should be integral */
+
+ mpz_init(xx);
+ mpq2mpz(xx,*x,NOISY);
+
+ mpz_init(yy);
+ mpq2mpz(yy,*y,NOISY);
+
+ mpz_init(res);
+ mpz_and(res,xx,yy);
+
+ mpz_clear(xx);
+ mpz_clear(yy);
+
+ mpz2mpq(*x,res);
+ mpz_clear(res);
+}
+
+void
+numb_ior(eval_t *x, const eval_t *y)
+{
+ mpz_t xx, yy, res;
+
+ /* x should be integral */
+ /* y should be integral */
+
+ mpz_init(xx);
+ mpq2mpz(xx,*x,NOISY);
+
+ mpz_init(yy);
+ mpq2mpz(yy,*y,NOISY);
+
+ mpz_init(res);
+ mpz_ior(res,xx,yy);
+
+ mpz_clear(xx);
+ mpz_clear(yy);
+
+ mpz2mpq(*x,res);
+ mpz_clear(res);
+}
+
+void
+numb_eor(eval_t *x, const eval_t *y)
+{
+ mpz_t xx, yy, res;
+
+ /* x should be integral */
+ /* y should be integral */
+
+ mpz_init(xx);
+ mpq2mpz(xx,*x,NOISY);
+
+ mpz_init(yy);
+ mpq2mpz(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);
+}
+
+void
+numb_not(eval_t *x)
+{
+ mpz_t xx, res;
+
+ /* x should be integral */
+
+ mpz_init(xx);
+ mpq2mpz(xx,*x,NOISY);
+
+ mpz_init(res);
+ mpz_com(res,xx);
+
+ mpz_clear(xx);
+
+ mpz2mpq(*x,res);
+ mpz_clear(res);
+}
+
+void
+numb_lshift(eval_t *x, const eval_t *y)
+{
+ mpz_t xx, yy, res;
+
+ /* x should be integral */
+ /* y should be integral */
+
+ mpz_init(xx);
+ mpq2mpz(xx,*x,NOISY);
+
+ mpz_init(yy);
+ mpq2mpz(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);
+}
+
+void
+numb_rshift(eval_t *x, const eval_t *y)
+{
+ mpz_t xx, yy, res;
+
+ /* x should be integral */
+ /* y should be integral */
+
+ mpz_init(xx);
+ mpq2mpz(xx,*x,NOISY);
+
+ mpz_init(yy);
+ mpq2mpz(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_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);
+}
+
+
+#else /* WITH_GMP */
+
+void
+numb_initialise(void)
+{
+ ;
+}
+
+
+/*------------------------------------------------------------------------.
+| The function ntoa () converts VALUE to a signed ascii representation in |
+| radix RADIX. |
+`------------------------------------------------------------------------*/
+
+/* Digits for number to ascii conversions. */
+static char const ntoa_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+static const char *
+ntoa (eval_t value, int radix)
+{
+ boolean negative;
+ ueval_t uvalue;
+ static char str[256];
+ register char *s = &str[sizeof str];
+
+ *--s = '\0';
+
+ if (value < 0)
+ {
+ negative = TRUE;
+ uvalue = (ueval_t) -value;
+ }
+ else
+ {
+ negative = FALSE;
+ uvalue = (ueval_t) value;
+ }
+
+ do
+ {
+ *--s = ntoa_digits[uvalue % radix];
+ uvalue /= radix;
+ }
+ while (uvalue > 0);
+
+ if (negative)
+ *--s = '-';
+ return s;
+}
+
+void
+numb_obstack(struct obstack *obs, const eval_t value,
+ const int radix, int min)
+{
+ const char *s = ntoa (value, radix);
+
+ if (*s == '-')
+ {
+ obstack_1grow (obs, '-');
+ min--;
+ s++;
+ }
+ for (min -= strlen (s); --min >= 0;)
+ obstack_1grow (obs, '0');
+
+ obstack_grow (obs, s, strlen (s));
+}
+
+
+#endif /* WITH_GMP */
+
+
+void
+numb_pow (eval_t *x, const eval_t *y)
+{
+ /* y should be integral */
+
+ eval_t ans, yy;
+
+ numb_init(ans);
+ numb_set_si(&ans,1);
+
+ numb_init(yy);
+ numb_set(yy,*y);
+
+ if (numb_negativep(yy)) {
+ numb_invert(*x);
+ numb_negate(yy);
+ }
+
+ while (numb_positivep(yy)) {
+ numb_times(ans,*x);
+ numb_decr(yy);
+ }
+ numb_set(*x,ans);
+
+ numb_fini(ans);
+ numb_fini(yy);
+}
diff --git a/src/numb.h b/src/numb.h
new file mode 100644
index 00000000..2fa02a58
--- /dev/null
+++ b/src/numb.h
@@ -0,0 +1,156 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "m4.h"
+
+#ifdef WITH_GMP
+#define NUMB_MP 1
+#endif
+
+#ifdef WITH_GMP
+#include "gmp.h"
+
+/* eval_t should be at least 32 bits. */
+typedef mpq_t eval_t;
+
+extern eval_t numb_ZERO;
+extern eval_t numb_ONE;
+
+#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: numb_ONE)
+#define numb_land(x,y) numb_set(x,numb_zerop(x)? numb_ZERO: y)
+
+#define reduce1(f1,x) \
+{ eval_t T; mpq_init(T); f1(T,x); mpq_set(x,T); mpq_clear(T); }
+#define reduce2(f2,x,y) \
+{ eval_t T; mpq_init(T); f2(T,(x),(y)); mpq_set((x),T); mpq_clear(T); }
+
+#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_decr(n) numb_minus(n,numb_ONE)
+
+
+
+void numb_divide(eval_t *x, const eval_t *y);
+void numb_modulo(eval_t *x, const eval_t *y);
+void numb_and(eval_t *x, const eval_t *y);
+void numb_ior(eval_t *x, const eval_t *y);
+void numb_eor(eval_t *x, const eval_t *y);
+void numb_not(eval_t *x);;
+void numb_lshift(eval_t *x, const eval_t *y);
+void numb_rshift(eval_t *x, const eval_t *y);
+void numb_pow (eval_t *x, const eval_t *y);
+
+
+
+
+#else /* not WITH_GMP */
+
+/* eval_t should be at least 32 bits. */
+/* use GNU long long int if available */
+#if defined(SIZEOF_LONG_LONG_INT) && SIZEOF_LONG_LONG_INT > 0
+typedef long long int eval_t;
+typedef unsigned long long int ueval_t;
+#else
+typedef long int eval_t;
+typedef unsigned long int ueval_t;
+#endif
+
+extern eval_t numb_ZERO;
+extern eval_t numb_ONE;
+
+#define int2numb(i) ((eval_t)(i))
+#define numb2int(n) ((n))
+
+#define numb_set(ans,x) ((ans) = x)
+#define numb_set_si(ans,si) (*(ans) = int2numb(si))
+
+#define numb_init(x) x=((eval_t)0)
+#define numb_fini(x)
+
+#define numb_decr(n) (n) -= 1
+
+#define numb_ZERO ((eval_t)0)
+#define numb_ONE ((eval_t)1)
+
+#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(x) (*(x) = int2numb(~numb2int(*(x))))
+#define numb_eor(x,y) (*(x) = int2numb(numb2int(*(x)) ^ numb2int(*(y))))
+#define numb_ior(x,y) (*(x) = int2numb(numb2int(*(x)) | numb2int(*(y))))
+#define numb_and(x,y) (*(x) = int2numb(numb2int(*(x)) & numb2int(*(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)))
+#define numb_ratio(x,y) ((x) = ((x) / ((y))))
+#define numb_divide(x,y) (*(x) = (*(x) / (*(y))))
+#define numb_modulo(x,y) (*(x) = (*(x) % *(y)))
+#define numb_invert(x) ((x) = 1 / (x))
+
+#define numb_lshift(x,y) (*(x) = (*(x) << *(y)))
+#define numb_rshift(x,y) (*(x) = (*(x) >> *(y)))
+
+void numb_pow (eval_t *x, const eval_t *y);
+
+#endif /* WITH_GMP */
+
+
+void numb_initialise __P((void));
+void numb_obstack __P((struct obstack *obs,
+ const eval_t value,
+ const int radix, int min));
diff --git a/src/output.c b/src/output.c
new file mode 100644
index 00000000..fdf8795b
--- /dev/null
+++ b/src/output.c
@@ -0,0 +1,590 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "m4.h"
+
+#include <sys/stat.h>
+
+/* 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)
+
+#ifdef HAVE_TMPFILE
+extern FILE *tmpfile ();
+#endif
+
+/* 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? */
+
+/* In a struct diversion, only one of file or buffer be may non-NULL,
+ depending on the fact output is diverted to a file or in memory
+ buffer. Further, if buffer is NULL, then pointer is NULL, size and
+ unused are zero. */
+
+struct diversion
+ {
+ FILE *file; /* diversion file on disk */
+ char *buffer; /* in-memory diversion buffer */
+ int size; /* usable size before reallocation */
+ int used; /* used length in characters */
+ };
+
+/* Table of diversions. */
+static struct diversion *diversion_table;
+
+/* Number of entries in diversion table. */
+static int diversions;
+
+/* Total size of all in-memory buffer sizes. */
+static int total_buffer_size;
+
+/* The number of the currently active diversion. This variable is
+ maintained for the `divnum' builtin function. */
+int current_diversion;
+
+/* Current output diversion, NULL if output is being currently discarded. */
+static struct diversion *output_diversion;
+
+/* Values of some output_diversion fields, cached out for speed. */
+static FILE *output_file; /* current value of (file) */
+static char *output_cursor; /* current value of (buffer + used) */
+static int output_unused; /* current value of (size - used) */
+
+/* Number of input line we are generating output for. */
+int output_current_line;
+
+/*------------------------.
+| Output initialisation. |
+`------------------------*/
+
+void
+output_init (void)
+{
+ diversion_table = (struct diversion *) xmalloc (sizeof (struct diversion));
+ diversions = 1;
+ diversion_table[0].file = stdout;
+ diversion_table[0].buffer = NULL;
+ diversion_table[0].size = 0;
+ diversion_table[0].used = 0;
+
+ total_buffer_size = 0;
+ current_diversion = 0;
+ output_diversion = diversion_table;
+ output_file = stdout;
+ output_cursor = NULL;
+ output_unused = 0;
+}
+
+#ifndef HAVE_TMPFILE
+
+#ifndef HAVE_MKSTEMP
+
+/* This implementation of mkstemp(3) does not avoid any races, but its
+ there. */
+
+#include <fcntl.h>
+
+static int
+mkstemp (const char *tmpl)
+{
+ mktemp (tmpl);
+ return open (tmpl, O_RDWR | O_TRUNC | O_CREAT, 0600);
+}
+
+#endif /* not HAVE_MKSTEMP */
+
+/* Implement tmpfile(3) for non-USG systems. */
+
+static FILE *
+tmpfile (void)
+{
+ char buf[32];
+ int fd;
+
+ strcpy (buf, "/tmp/m4XXXXXX");
+ fd = mkstemp (buf);
+ if (fd < 0)
+ return NULL;
+
+ unlink (buf);
+ return fdopen (fd, "w+");
+}
+
+#endif /* not HAVE_TMPFILE */
+
+/*-----------------------------------------------------------------------.
+| 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 (int length)
+{
+ int wanted_size;
+
+ /* 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 < 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)
+ {
+ struct diversion *selected_diversion;
+ int selected_used;
+ struct diversion *diversion;
+ int count;
+
+ /* 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;
+
+ for (diversion = diversion_table + 1;
+ diversion < diversion_table + diversions;
+ diversion++)
+ if (diversion->used > selected_used)
+ {
+ selected_diversion = diversion;
+ selected_used = diversion->used;
+ }
+
+ /* Create a temporary file, write the in-memory buffer of the
+ diversion to this file, then release the buffer. */
+
+ selected_diversion->file = tmpfile ();
+ if (selected_diversion->file == NULL)
+ M4ERROR ((EXIT_FAILURE, errno,
+ "ERROR: Cannot create temporary file for diversion"));
+
+ if (selected_diversion->used > 0)
+ {
+ count = fwrite (selected_diversion->buffer,
+ (size_t) selected_diversion->used,
+ 1,
+ selected_diversion->file);
+ if (count != 1)
+ M4ERROR ((EXIT_FAILURE, errno,
+ "ERROR: Cannot flush diversion to temporary file"));
+ }
+
+ /* Reclaim the buffer space for other diversions. */
+
+ free (selected_diversion->buffer);
+ total_buffer_size -= selected_diversion->size;
+
+ selected_diversion->buffer = NULL;
+ selected_diversion->size = 0;
+ selected_diversion->used = 0;
+ }
+
+ /* Reload output_file, just in case the flushed diversion was current. */
+
+ output_file = output_diversion->file;
+ if (output_file)
+ {
+
+ /* The flushed diversion was current indeed. */
+
+ output_cursor = NULL;
+ output_unused = 0;
+ }
+ else
+ {
+
+ /* The buffer may be safely reallocated. */
+
+ output_diversion->buffer
+ = xrealloc (output_diversion->buffer, (size_t) wanted_size);
+
+ total_buffer_size += wanted_size - output_diversion->size;
+ output_diversion->size = wanted_size;
+
+ output_cursor = output_diversion->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. |
+`------------------------------------------------------------------------*/
+
+#define OUTPUT_CHARACTER(Char) \
+ if (output_file) \
+ putc ((Char), output_file); \
+ else if (output_unused == 0) \
+ output_character_helper ((Char)); \
+ else \
+ (output_unused--, *output_cursor++ = (Char))
+
+static void
+output_character_helper (int character)
+{
+ make_room_for (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. |
+`------------------------------------------------------------------------*/
+
+static void
+output_text (const char *text, int length)
+{
+ int count;
+
+ if (!output_file && length > output_unused)
+ make_room_for (length);
+
+ if (output_file)
+ {
+ count = fwrite (text, length, 1, output_file);
+ if (count != 1)
+ M4ERROR ((EXIT_FAILURE, errno, "ERROR: Copying inserted file"));
+ }
+ else
+ {
+ memcpy (output_cursor, text, (size_t) length);
+ output_cursor += length;
+ output_unused -= length;
+ }
+}
+
+/*-------------------------------------------------------------------------.
+| Add some text into an obstack OBS, taken from TEXT, having LENGTH |
+| characters. If OBS is NULL, rather output the text to an external file |
+| or an in-memory diversion buffer. If OBS is NULL, and there is no |
+| output file, the text is discarded. |
+| |
+| If we are generating sync lines, the output have 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 lines generates several |
+| output lines, or when several input lines does not generate any output. |
+`-------------------------------------------------------------------------*/
+
+void
+shipout_text (struct obstack *obs, const char *text, int length)
+{
+ static boolean start_of_output_line = TRUE;
+ char line[20];
+ const char *cursor;
+
+ /* 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 == NULL)
+ return;
+
+ /* Output TEXT to a file, or in-memory diversion buffer. */
+
+ if (!sync_output)
+ 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:
+ output_text (text, length);
+ }
+ else
+ for (; length-- > 0; text++)
+ {
+ if (start_of_output_line)
+ {
+ start_of_output_line = FALSE;
+ output_current_line++;
+
+#ifdef DEBUG_OUTPUT
+ printf ("DEBUG: cur %d, cur out %d\n",
+ current_line, output_current_line);
+#endif
+
+ /* Output a `#line NUM' synchronisation directive if needed.
+ If output_current_line was previously given a negative
+ value (invalidated), rather output `#line NUM "FILE"'. */
+
+ if (output_current_line != current_line)
+ {
+ sprintf (line, "#line %d", current_line);
+ for (cursor = line; *cursor; cursor++)
+ OUTPUT_CHARACTER (*cursor);
+ if (output_current_line < 1)
+ {
+ OUTPUT_CHARACTER (' ');
+ OUTPUT_CHARACTER ('"');
+ for (cursor = current_file; *cursor; cursor++)
+ OUTPUT_CHARACTER (*cursor);
+ OUTPUT_CHARACTER ('"');
+ }
+ OUTPUT_CHARACTER ('\n');
+ output_current_line = current_line;
+ }
+ }
+ OUTPUT_CHARACTER (*text);
+ if (*text == '\n')
+ start_of_output_line = TRUE;
+ }
+}
+
+/* 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
+make_diversion (int divnum)
+{
+ struct diversion *diversion;
+
+ if (output_diversion)
+ {
+ output_diversion->file = output_file;
+ output_diversion->used = output_diversion->size - output_unused;
+ output_diversion = NULL;
+ output_file = NULL;
+ output_cursor = NULL;
+ output_unused = 0;
+ }
+
+ current_diversion = divnum;
+
+ if (divnum < 0)
+ return;
+
+ if (divnum >= diversions)
+ {
+ diversion_table = (struct diversion *)
+ xrealloc (diversion_table, (divnum + 1) * sizeof (struct diversion));
+ for (diversion = diversion_table + diversions;
+ diversion <= diversion_table + divnum;
+ diversion++)
+ {
+ diversion->file = NULL;
+ diversion->buffer = NULL;
+ diversion->size = 0;
+ diversion->used = 0;
+ }
+ diversions = divnum + 1;
+ }
+
+ output_diversion = diversion_table + divnum;
+ output_file = output_diversion->file;
+ output_cursor = output_diversion->buffer + output_diversion->used;
+ output_unused = output_diversion->size - output_diversion->used;
+ output_current_line = -1;
+}
+
+/*-------------------------------------------------------------------.
+| 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
+insert_file (FILE *file)
+{
+ char buffer[COPY_BUFFER_SIZE];
+ size_t length;
+
+ /* Optimize out inserting into a sink. */
+
+ if (!output_diversion)
+ return;
+
+ /* Insert output by big chunks. */
+
+ while (length = read (fileno (file), buffer, COPY_BUFFER_SIZE),
+ length != 0)
+ if (length == (size_t) -1)
+ M4ERROR ((EXIT_FAILURE, errno, "ERROR: Reading inserted file"));
+ else
+ output_text (buffer, length);
+}
+
+/*-------------------------------------------------------------------------.
+| 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
+insert_diversion (int divnum)
+{
+ struct diversion *diversion;
+
+ /* Do not care about unexisting diversions. */
+
+ if (divnum < 0 || divnum >= diversions)
+ return;
+
+ /* Also avoid undiverting into self. */
+
+ diversion = diversion_table + divnum;
+ if (diversion == output_diversion)
+ return;
+
+ /* Effectively undivert only if an output stream is active. */
+
+ if (output_diversion)
+ {
+ if (diversion->file)
+ {
+ rewind (diversion->file);
+ insert_file (diversion->file);
+ }
+ else if (diversion->buffer)
+ output_text (diversion->buffer, diversion->used);
+
+ output_current_line = -1;
+ }
+
+ /* Return all space used by the diversion. */
+
+ if (diversion->file)
+ {
+ fclose (diversion->file);
+ diversion->file = NULL;
+ }
+ else if (diversion->buffer)
+ {
+ free (diversion->buffer);
+ diversion->buffer = NULL;
+ diversion->size = 0;
+ diversion->used = 0;
+ }
+}
+
+/*-------------------------------------------------------------------------.
+| Get back all diversions. This is done just before exiting from main (), |
+| and from m4_undivert (), if called without arguments. |
+`-------------------------------------------------------------------------*/
+
+void
+undivert_all (void)
+{
+ int divnum;
+
+ for (divnum = 1; divnum < diversions; divnum++)
+ insert_diversion (divnum);
+}
+
+/*-------------------------------------------------------------.
+| Produce all diversion information in frozen format on FILE. |
+`-------------------------------------------------------------*/
+
+void
+freeze_diversions (FILE *file)
+{
+ int saved_number;
+ int last_inserted;
+ int divnum;
+ struct diversion *diversion;
+ struct stat file_stat;
+
+ saved_number = current_diversion;
+ last_inserted = 0;
+ make_diversion (0);
+ output_file = file; /* kludge in the frozen file */
+
+ for (divnum = 1; divnum < diversions; divnum++)
+ {
+ diversion = diversion_table + divnum;
+ if (diversion->file || diversion->buffer)
+ {
+ if (diversion->file)
+ {
+ fflush (diversion->file);
+ if (fstat (fileno (diversion->file), &file_stat) < 0)
+ M4ERROR ((EXIT_FAILURE, errno, "Cannot stat diversion"));
+ fprintf (file, "D%d,%d", divnum, (int) file_stat.st_size);
+ }
+ else
+ fprintf (file, "D%d,%d\n", divnum, diversion->used);
+
+ insert_diversion (divnum);
+ putc ('\n', file);
+
+ last_inserted = divnum;
+ }
+ }
+
+ /* Save the active diversion number, if not already. */
+
+ if (saved_number != last_inserted)
+ fprintf (file, "D%d,0\n\n", saved_number);
+}
+
diff --git a/src/path.c b/src/path.c
new file mode 100644
index 00000000..90bdc6de
--- /dev/null
+++ b/src/path.c
@@ -0,0 +1,151 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Handling of path search of included files via the builtins "include"
+ and "sinclude". */
+
+#include "m4.h"
+
+struct includes
+{
+ struct includes *next; /* next directory to search */
+ const char *dir; /* directory */
+ int len;
+};
+
+typedef struct includes includes;
+
+static includes *dir_list; /* the list of path directories */
+static includes *dir_list_end; /* the end of same */
+static int dir_max_length; /* length of longest directory name */
+
+
+void
+include_init (void)
+{
+ dir_list = NULL;
+ dir_list_end = NULL;
+ dir_max_length = 0;
+}
+
+void
+include_env_init (void)
+{
+ char *path;
+ char *path_end;
+
+ if (no_gnu_extensions)
+ return;
+
+ path = getenv ("M4PATH");
+ if (path == NULL)
+ return;
+
+ do
+ {
+ path_end = strchr (path, ':');
+ if (path_end)
+ *path_end = '\0';
+ add_include_directory (path);
+ path = path_end + 1;
+ }
+ while (path_end);
+}
+
+void
+add_include_directory (const char *dir)
+{
+ includes *incl;
+
+ if (no_gnu_extensions)
+ return;
+
+ if (*dir == '\0')
+ dir = ".";
+
+ incl = (includes *) xmalloc (sizeof (struct includes));
+ incl->next = NULL;
+ incl->len = strlen (dir);
+ incl->dir = xstrdup (dir);
+
+ if (incl->len > dir_max_length) /* remember len of longest directory */
+ dir_max_length = incl->len;
+
+ if (dir_list_end == NULL)
+ dir_list = incl;
+ else
+ dir_list_end->next = incl;
+ dir_list_end = incl;
+
+#ifdef DEBUG_INCL
+ fprintf (stderr, "add_include_directory (%s);\n", dir);
+#endif
+}
+
+FILE *
+path_search (const char *dir)
+{
+ FILE *fp;
+ includes *incl;
+ char *name; /* buffer for constructed name */
+
+ /* Look in current working directory first. */
+ fp = fopen (dir, "r");
+ if (fp != NULL)
+ return fp;
+
+ /* If file not found, and filename absolute, fail. */
+ if (*dir == '/' || no_gnu_extensions)
+ return NULL;
+
+ name = (char *) xmalloc (dir_max_length + 1 + strlen (dir) + 1);
+
+ for (incl = dir_list; incl != NULL; incl = incl->next)
+ {
+ strncpy (name, incl->dir, incl->len);
+ name[incl->len] = '/';
+ strcpy (name + incl->len + 1, dir);
+
+#ifdef DEBUG_INCL
+ fprintf (stderr, "path_search (%s) -- trying %s\n", dir, name);
+#endif
+
+ fp = fopen (name, "r");
+ if (fp != NULL)
+ {
+ if (debug_level & DEBUG_TRACE_PATH)
+ DEBUG_MESSAGE (("path search for `%s' found `%s'", dir, name));
+ break;
+ }
+ }
+ xfree (name);
+ return fp;
+}
+
+#ifdef DEBUG_INCL
+
+static int
+include_dump (void)
+{
+ includes *incl;
+
+ fprintf (stderr, "include_dump:\n");
+ for (incl = dir_list; incl != NULL; incl = incl->next)
+ fprintf (stderr, "\t%s\n", incl->dir);
+}
+
+#endif /* DEBUG_INCL */
diff --git a/src/stackovf.c b/src/stackovf.c
new file mode 100644
index 00000000..10d3851e
--- /dev/null
+++ b/src/stackovf.c
@@ -0,0 +1,392 @@
+/* Detect stack overflow (when getrlimit and sigaction or sigvec are available)
+ Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+ Jim Avera <jima@netcom.com>, October 1993.
+
+ 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/* 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 DEBUG_STACKOVF
+
+#include "m4.h" /* stdlib.h, xmalloc() */
+
+#include <assert.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <signal.h>
+
+#if HAVE_SIGINFO_H
+# include <siginfo.h>
+#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
+
+/* Giving a hand to ansi2knr... */
+typedef void (*handler_t) _((void));
+
+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)
+#define PARAM_NOSTACKOVF ((const char *) 2)
+
+static void
+process_sigsegv (int signo, const char *p)
+{
+ long diff;
+ diff = (p - stackend);
+
+#ifdef DEBUG_STKOVF
+ {
+ char buf[140];
+
+ sprintf (buf, "process_sigsegv: p=%#lx stackend=%#lx diff=%ld bot=%#lx\n",
+ (long) p, (long) stackend, (long) diff, (long) stackbot);
+ write (2, buf, strlen (buf));
+ }
+#endif
+
+ if (p != PARAM_NOSTACKOVF)
+ {
+ if ((long) sbrk (8192) == (long) -1)
+ {
+
+ /* sbrk failed. Assume the RLIMIT_VMEM prevents expansion even
+ if the stack limit has not been reached. */
+
+ write (2, "VMEM limit exceeded?\n", 21);
+ 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;
+
+ 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_SIGINFO_H
+
+/* SVR4. */
+
+static void
+sigsegv_handler (int signo, siginfo_t * ip)
+{
+ process_sigsegv
+ (signo, (ip != (siginfo_t *) 0
+ && ip->si_signo == SIGSEGV ? (char *) ip->si_addr : NULL));
+}
+
+#else /* not HAVE_SIGINFO_H */
+#if 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 */
+#endif /* not HAVE_SIGINFO */
+
+/* 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 can not 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;
+#else
+ struct sigvec vec;
+#endif
+
+ grows_upward = ((char *) argv < (char *) &stack_len);
+ arg0 = argv[0];
+ stackovf_handler = handler;
+
+ /* Calculate the approximate expected addr for a stack-ovf trap. */
+
+ if (getrlimit (RLIMIT_STACK, &rl) < 0)
+ error (1, 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) != (char *) 0; v++)
+ {
+ if (p < stackbot)
+ stackbot = p;
+ }
+ if ((char *) envp < stackbot)
+ stackbot = (char *) envp;
+ for (v = envp; (p = (char *) *v) != (char *) 0; v++)
+ {
+ if (p < stackbot)
+ stackbot = p;
+ }
+ stackend = stackbot + stack_len;
+ }
+ else
+ {
+
+ /* The stack grows "downward" (toward decreasing addresses). */
+
+ for (v = argv; (p = (char *) *v) != (char *) 0; v++)
+ {
+ if (p > stackbot)
+ stackbot = p;
+ }
+ if ((char *) envp > stackbot)
+ stackbot = (char *) envp;
+ for (v = envp; (p = (char *) *v) != (char *) 0; v++)
+ {
+ if (p > stackbot)
+ stackbot = p;
+ }
+ stackend = stackbot - stack_len;
+ }
+
+ /* Allocate a separate signal-handler stack. */
+
+#if HAVE_SIGALTSTACK && (defined(HAVE_SIGINFO_H) || !HAVE_SIGSTACK)
+
+ /* Use sigaltstack only if siginfo is available, unless there is no
+ choice. */
+
+ {
+ stack_t ss;
+
+ ss.ss_size = SIGSTKSZ;
+ ss.ss_sp = xmalloc ((unsigned) ss.ss_size);
+ ss.ss_flags = 0;
+ if (sigaltstack (&ss, (stack_t *) 0) < 0)
+ error (1, errno, "sigaltstack");
+ }
+
+#else /* not HAVE_SIGALTSTACK || not HAVE_SIGINFO_H && HAVE_SIGSTACK */
+#if HAVE_SIGSTACK
+
+ {
+ struct sigstack ss;
+ char *stackbuf = xmalloc (2 * SIGSTKSZ);
+
+ ss.ss_sp = stackbuf + SIGSTKSZ;
+ ss.ss_onstack = 0;
+ if (sigstack (&ss, NULL) < 0)
+ error (1, errno, "sigstack");
+ }
+
+#else /* not HAVE_SIGSTACK */
+
+Error - Do not know how to set up stack-ovf trap handler...
+
+#endif /* not HAVE_SIGSTACK */
+#endif /* not HAVE_SIGALTSTACK || not HAVE_SIGINFO_H && HAVE_SIGSTACK */
+
+ /* Arm the SIGSEGV signal handler. */
+
+#if HAVE_SIGACTION && defined(SA_ONSTACK)
+
+ sigaction (SIGSEGV, NULL, &act);
+ act.sa_handler = (RETSIGTYPE (*) _((int))) sigsegv_handler;
+ sigemptyset (&act.sa_mask);
+ act.sa_flags = (SA_ONSTACK
+#ifdef SA_RESETHAND
+ | SA_RESETHAND
+#endif
+#ifdef SA_SIGINFO
+ | SA_SIGINFO
+#endif
+ );
+ if (sigaction (SIGSEGV, &act, NULL) < 0)
+ error (1, errno, "sigaction");
+
+#else /* not HAVE_SIGACTION */
+#if HAVE_SIGVEC && defined(SV_ONSTACK)
+
+ vec.sv_handler = (RETSIGTYPE (*)_ ((int))) sigsegv_handler;
+ vec.sv_mask = 0;
+ vec.sv_flags = (SV_ONSTACK
+#ifdef SV_RESETHAND
+ | SV_RESETHAND
+#endif
+ );
+ if (sigvec (SIGSEGV, &vec, NULL) < 0)
+ error (1, errno, "sigvec");
+
+#else /* not HAVE_SIGVEC && defined(SV_ONSTACK) */
+
+Error - Do not know how to catch signals on an alternate stack...
+
+#endif /* HAVE_SIGVEC && defined(SV_ONSTACK) */
+#endif /* HAVE_SIGALTSTACK && defined(SA_ONSTACK) */
+
+}
diff --git a/src/symtab.c b/src/symtab.c
new file mode 100644
index 00000000..150a84bf
--- /dev/null
+++ b/src/symtab.c
@@ -0,0 +1,266 @@
+/* GNU m4 -- A simple macro processor
+ Copyright (C) 1989, 90, 91, 92, 93, 94 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 2, 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* This file handles all the low level work around the symbol table. The
+ symbol table is a simple chained hash table. Each symbol is described
+ by a struct symbol, which is placed in the hash table based upon the
+ symbol name. Symbols that hash to the same entry in the table are
+ kept on a list, sorted by name. As a special case, to facilitate the
+ "pushdef" and "popdef" builtins, a symbol can be several times in the
+ symbol table, one for each definition. Since the name is the same,
+ all the entries for the symbol will be on the same list, and will
+ also, because the list is sorted, be adjacent. All the entries for a
+ name are simply ordered on the list by age. The current definition
+ will then always be the first found. */
+
+#include "m4.h"
+
+/*----------------------------------------------------------------------.
+| Initialise the symbol table, by allocating the necessary storage, and |
+| zeroing all the entries. |
+`----------------------------------------------------------------------*/
+
+/* Pointer to symbol table. */
+symbol **symtab;
+
+void
+symtab_init (void)
+{
+ int i;
+ symbol **s;
+
+ s = symtab = (symbol **) xmalloc (hash_table_size * sizeof (symbol *));
+
+ for (i = hash_table_size; --i >= 0;)
+ *s++ = NULL;
+}
+
+/*--------------------------------------------------.
+| Return a hashvalue for a string, from GNU-emacs. |
+`--------------------------------------------------*/
+
+static int
+hash (const char *s)
+{
+ register int val = 0;
+
+ register const char *ptr = s;
+ register char ch;
+
+ while ((ch = *ptr++) != '\0')
+ {
+ if (ch >= 0140)
+ ch -= 40;
+ val = ((val << 3) + (val >> 28) + ch);
+ };
+ val = (val < 0) ? -val : val;
+ return val % hash_table_size;
+}
+
+/*--------------------------------------------.
+| Free all storage associated with a symbol. |
+`--------------------------------------------*/
+
+static void
+free_symbol (symbol *sym)
+{
+ if (SYMBOL_NAME (sym))
+ xfree (SYMBOL_NAME (sym));
+ if (SYMBOL_TYPE (sym) == TOKEN_TEXT)
+ xfree (SYMBOL_TEXT (sym));
+ xfree ((voidstar) sym);
+}
+
+/*------------------------------------------------------------------------.
+| Search in, and manipulation of the symbol table, are all done by |
+| lookup_symbol (). It basically hashes NAME to a list in the symbol |
+| table, and searched this list for the first occurence of a symbol with |
+| the name. |
+| |
+| The MODE parameter determines what lookup_symbol () will do. It can |
+| either just do a lookup, do a lookup and insert if not present, do an |
+| insertion even if the name is already in the list, delete the first |
+| occurrence of the name on the list or delete all occurences of the name |
+| on the list. |
+`------------------------------------------------------------------------*/
+
+symbol *
+lookup_symbol (const char *name, symbol_lookup mode)
+{
+ int h, cmp = 1;
+ symbol *sym, *prev;
+ symbol **spp;
+
+ h = hash (name);
+ sym = symtab[h];
+
+ for (prev = NULL; sym != NULL; prev = sym, sym = sym->next)
+ {
+ cmp = strcmp (SYMBOL_NAME (sym), name);
+ if (cmp >= 0)
+ break;
+ }
+
+ /* If just searching, return status of search. */
+
+ if (mode == SYMBOL_LOOKUP)
+ return cmp == 0 ? sym : NULL;
+
+ /* Symbol not found. */
+
+ spp = (prev != NULL) ? &prev->next : &symtab[h];
+
+ switch (mode)
+ {
+
+ case SYMBOL_INSERT:
+
+ /* Return the symbol, if the name was found in the table.
+ Otherwise, just insert the name, and return the new symbol. */
+
+ if (cmp == 0 && sym != NULL)
+ return sym;
+ /* Fall through. */
+
+ case SYMBOL_PUSHDEF:
+
+ /* Insert a name in the symbol table. If there is already a symbol
+ with the name, insert this in front of it, and mark the old
+ symbol as "shadowed". */
+
+ sym = (symbol *) xmalloc (sizeof (symbol));
+ SYMBOL_TYPE (sym) = TOKEN_VOID;
+ SYMBOL_TRACED (sym) = SYMBOL_SHADOWED (sym) = FALSE;
+ SYMBOL_NAME (sym) = xstrdup (name);
+
+ SYMBOL_NEXT (sym) = *spp;
+ (*spp) = sym;
+
+ if (mode == SYMBOL_PUSHDEF && cmp == 0)
+ {
+ SYMBOL_SHADOWED (SYMBOL_NEXT (sym)) = TRUE;
+ SYMBOL_TRACED (sym) = SYMBOL_TRACED (SYMBOL_NEXT (sym));
+ }
+ return sym;
+
+ case SYMBOL_DELETE:
+
+ /* Delete all occurences of symbols with NAME. */
+
+ if (cmp != 0 || sym == NULL)
+ return NULL;
+ do
+ {
+ *spp = SYMBOL_NEXT (sym);
+ free_symbol (sym);
+ sym = *spp;
+ }
+ while (sym != NULL && strcmp (name, SYMBOL_NAME (sym)) == 0);
+ return NULL;
+
+ case SYMBOL_POPDEF:
+
+ /* Delete the first occurence of a symbol with NAME. */
+
+ if (cmp != 0 || sym == NULL)
+ return NULL;
+ if (SYMBOL_NEXT (sym) != NULL && cmp == 0)
+ SYMBOL_SHADOWED (SYMBOL_NEXT (sym)) = FALSE;
+ *spp = SYMBOL_NEXT (sym);
+ free_symbol (sym);
+ return NULL;
+
+ default:
+ M4ERROR ((warning_status, 0,
+ "INTERNAL ERROR: Illegal mode to symbol_lookup ()"));
+ abort ();
+ }
+}
+
+/*----------------------------------------------------------------------.
+| The following function is used for the cases, where we want to do |
+| something to each and every symbol in the table. The function |
+| hack_all_symbols () traverses the symbol table, and calls a specified |
+| function FUNC for each symbol in the table. FUNC is called with a |
+| pointer to the symbol, and the DATA argument. |
+`----------------------------------------------------------------------*/
+
+void
+hack_all_symbols (hack_symbol *func, const char *data)
+{
+ int h;
+ symbol *sym;
+
+ for (h = 0; h < hash_table_size; h++)
+ {
+ for (sym = symtab[h]; sym != NULL; sym = SYMBOL_NEXT (sym))
+ (*func) (sym, data);
+ }
+}
+
+#ifdef DEBUG_SYM
+
+static void
+symtab_debug (void)
+{
+ token_type t;
+ token_data td;
+ const char *text;
+ symbol *s;
+ int delete;
+
+ while ((t = next_token (&td)) != NULL)
+ {
+ if (t != TOKEN_WORD)
+ continue;
+ text = TOKEN_DATA_TEXT (&td);
+ if (*text == '_')
+ {
+ delete = 1;
+ text++;
+ }
+ else
+ delete = 0;
+
+ s = lookup_symbol (text, SYMBOL_LOOKUP);
+
+ if (s == NULL)
+ printf ("Name `%s' is unknown\n", text);
+
+ if (delete)
+ (void) lookup_symbol (text, SYMBOL_DELETE);
+ else
+ (void) lookup_symbol (text, SYMBOL_INSERT);
+ }
+ hack_all_symbols (dump_symbol);
+}
+
+static void
+symtab_print_list (int i)
+{
+ symbol *sym;
+
+ printf ("Symbol dump #d:\n", i);
+ for (sym = symtab[i]; sym != NULL; sym = sym->next)
+ printf ("\tname %s, addr 0x%x, next 0x%x, flags%s%s\n",
+ SYMBOL_NAME (sym), sym, sym->next,
+ SYMBOL_TRACED (sym) ? " traced" : "",
+ SYMBOL_SHADOWED (sym) ? " shadowed" : "");
+}
+
+#endif /* DEBUG_SYM */
diff --git a/stamp-h.in b/stamp-h.in
new file mode 100644
index 00000000..aa5b9250
--- /dev/null
+++ b/stamp-h.in
@@ -0,0 +1 @@
+Sat Nov 5 22:45:51 EST 1994
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644
index 00000000..7aed6dc3
--- /dev/null
+++ b/tests/Makefile.am
@@ -0,0 +1,35 @@
+# The next line is needed by `./esyscmd.1.test'
+# Ty Coon, President of Vice
+# The previous line is needed by `./esyscmd.1.test'
+
+EXTRA_DIST = get-them foo incl.m4 stamp-TESTS $(TESTS) defs m4wrap.1.test
+
+TESTS = $(OTHER_TESTS) $(GENERATED_TESTS)
+
+GENERATED_TESTS = \
+ argument.1.test argument.2.test argument.3.test argument.4.test \
+ changeco.1.test changeco.2.test changequ.1.test changequ.2.test \
+ changequ.3.test changesy.1.test changesy.2.test changesy.3.test \
+ changesy.4.test changesy.5.test changesy.6.test changesy.7.test \
+ cleardiv.1.test cleardiv.2.test define.1.test define.2.test \
+ defn.1.test defn.2.test divert.1.test divert.2.test divnum.1.test \
+ dnl.1.test dumpdef.1.test errprint.1.test errprint.2.test \
+ esyscmd.1.test eval.1.test eval.2.test format.1.test ifdef.1.test \
+ ifelse.1.test ifelse.2.test include.1.test include.2.test \
+ include.3.test incr.1.test index.1.test indir.1.test len.1.test \
+ loops.1.test loops.2.test m4exit.1.test patsubst.1.test \
+ patsubst.2.test pseudoar.1.test pseudoar.2.test pseudoar.3.test \
+ pseudoar.4.test pseudoar.5.test pushdef.1.test pushdef.2.test \
+ regexp.1.test regexp.2.test substr.1.test sysval.1.test trace.1.test \
+ translit.1.test undefine.1.test undivert.1.test undivert.2.test \
+ undivert.3.test
+
+OTHER_TESTS =
+
+all: stamp-TESTS
+
+stamp-TESTS: $(srcdir)/get-them $(top_srcdir)/doc/m4.texinfo
+ cd $(srcdir) \
+ && rm -f *.[0-9].test \
+ && AWK=$(AWK) $(srcdir)/get-them $(top_srcdir)/doc/m4.texinfo \
+ && > $@
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 00000000..e8f24129
--- /dev/null
+++ b/tests/Makefile.in
@@ -0,0 +1,235 @@
+# Makefile.in generated automatically by automake 1.3b from Makefile.am
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
+# This Makefile.in 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.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+# The next line is needed by `./esyscmd.1.test'
+# Ty Coon, President of Vice
+# The previous line is needed by `./esyscmd.1.test'
+
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+AWK = @AWK@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+CC = @CC@
+CPP = @CPP@
+DATADIRNAME = @DATADIRNAME@
+GENCAT = @GENCAT@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
+GT_NO = @GT_NO@
+GT_YES = @GT_YES@
+INCLUDE_LOCALE_H = @INCLUDE_LOCALE_H@
+INSTOBJEXT = @INSTOBJEXT@
+INTLDEPS = @INTLDEPS@
+INTLLIBS = @INTLLIBS@
+INTLOBJS = @INTLOBJS@
+MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+PACKAGE = @PACKAGE@
+PERL = @PERL@
+POFILES = @POFILES@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+STACKOVF = @STACKOVF@
+U = @U@
+USE_INCLUDED_LIBINTL = @USE_INCLUDED_LIBINTL@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+l = @l@
+
+EXTRA_DIST = get-them foo incl.m4 stamp-TESTS $(TESTS) defs m4wrap.1.test
+
+TESTS = $(OTHER_TESTS) $(GENERATED_TESTS)
+
+GENERATED_TESTS = \
+ argument.1.test argument.2.test argument.3.test argument.4.test \
+ changeco.1.test changeco.2.test changequ.1.test changequ.2.test \
+ changequ.3.test changesy.1.test changesy.2.test changesy.3.test \
+ changesy.4.test changesy.5.test changesy.6.test changesy.7.test \
+ cleardiv.1.test cleardiv.2.test define.1.test define.2.test \
+ defn.1.test defn.2.test divert.1.test divert.2.test divnum.1.test \
+ dnl.1.test dumpdef.1.test errprint.1.test errprint.2.test \
+ esyscmd.1.test eval.1.test eval.2.test format.1.test ifdef.1.test \
+ ifelse.1.test ifelse.2.test include.1.test include.2.test \
+ include.3.test incr.1.test index.1.test indir.1.test len.1.test \
+ loops.1.test loops.2.test m4exit.1.test patsubst.1.test \
+ patsubst.2.test pseudoar.1.test pseudoar.2.test pseudoar.3.test \
+ pseudoar.4.test pseudoar.5.test pushdef.1.test pushdef.2.test \
+ regexp.1.test regexp.2.test substr.1.test sysval.1.test trace.1.test \
+ translit.1.test undefine.1.test undivert.1.test undivert.2.test \
+ undivert.3.test
+
+OTHER_TESTS =
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../config.h
+CONFIG_CLEAN_FILES =
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP = --best
+all: Makefile
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps tests/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+tags: TAGS
+TAGS:
+
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = tests
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file; \
+ done
+check-TESTS: $(TESTS)
+ @failed=0; all=0; \
+ srcdir=$(srcdir); export srcdir; \
+ for tst in $(TESTS); do \
+ if test -f $$tst; then dir=.; \
+ else dir="$(srcdir)"; fi; \
+ if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \
+ all=`expr $$all + 1`; \
+ echo "PASS: $$tst"; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="$$failed of $$all tests failed"; \
+ fi; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0
+info:
+dvi:
+check: all
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+installcheck:
+install-exec:
+ @$(NORMAL_INSTALL)
+
+install-data:
+ @$(NORMAL_INSTALL)
+
+install: install-exec install-data all
+ @:
+
+uninstall:
+
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' INSTALL_SCRIPT='$(INSTALL_PROGRAM)' install
+installdirs:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean: mostlyclean-generic
+
+clean: clean-generic mostlyclean
+
+distclean: distclean-generic clean
+ -rm -f config.status
+
+maintainer-clean: maintainer-clean-generic distclean
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+.PHONY: tags distdir check-TESTS info dvi installcheck install-exec \
+install-data install uninstall all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+all: stamp-TESTS
+
+stamp-TESTS: $(srcdir)/get-them $(top_srcdir)/doc/m4.texinfo
+ cd $(srcdir) \
+ && rm -f *.[0-9].test \
+ && AWK=$(AWK) $(srcdir)/get-them $(top_srcdir)/doc/m4.texinfo \
+ && > $@
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/tests/argument.1.test b/tests/argument.1.test
new file mode 100755
index 00000000..9398608f
--- /dev/null
+++ b/tests/argument.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# argument.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1037
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`exch', `$2, $1')
+exch(arg1, arg2)
+EOF
+
+cat <<\EOF >ok
+
+arg2, arg1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/argument.2.test b/tests/argument.2.test
new file mode 100755
index 00000000..abd434f3
--- /dev/null
+++ b/tests/argument.2.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# argument.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1047
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`exch', `$2, $1')
+define(exch(``expansion text'', ``macro''))
+macro
+EOF
+
+cat <<\EOF >ok
+
+
+expansion text
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/argument.3.test b/tests/argument.3.test
new file mode 100755
index 00000000..0231981b
--- /dev/null
+++ b/tests/argument.3.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# argument.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1067
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', ``Macro name: $0'')
+test
+EOF
+
+cat <<\EOF >ok
+
+Macro name: test
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/argument.4.test b/tests/argument.4.test
new file mode 100755
index 00000000..a0c5cbfd
--- /dev/null
+++ b/tests/argument.4.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# argument.4.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1077
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `This is macro `foo'.')
+foo
+EOF
+
+cat <<\EOF >ok
+
+This is macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changeco.1.test b/tests/changeco.1.test
new file mode 100755
index 00000000..d1a60b0c
--- /dev/null
+++ b/tests/changeco.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# changeco.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1960
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`comment', `COMMENT')
+# A normal comment
+changecom(`/*', `*/')
+# Not a comment anymore
+But: /* this is a comment now */ while this is not a comment
+EOF
+
+cat <<\EOF >ok
+
+# A normal comment
+
+# Not a COMMENT anymore
+But: /* this is a comment now */ while this is not a COMMENT
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changeco.2.test b/tests/changeco.2.test
new file mode 100755
index 00000000..21854f26
--- /dev/null
+++ b/tests/changeco.2.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# changeco.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1981
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`comment', `COMMENT')
+changecom
+# Not a comment anymore
+EOF
+
+cat <<\EOF >ok
+
+
+# Not a COMMENT anymore
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changequ.1.test b/tests/changequ.1.test
new file mode 100755
index 00000000..4e6f1fa6
--- /dev/null
+++ b/tests/changequ.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# changequ.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1896
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changequote([, ])
+define([foo], [Macro [foo].])
+foo
+EOF
+
+cat <<\EOF >ok
+
+
+Macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changequ.2.test b/tests/changequ.2.test
new file mode 100755
index 00000000..45fd0dbe
--- /dev/null
+++ b/tests/changequ.2.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# changequ.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1908
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changequote([[, ]])
+define([[foo]], [[Macro [[[foo]]].]])
+foo
+EOF
+
+cat <<\EOF >ok
+
+
+Macro [foo].
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changequ.3.test b/tests/changequ.3.test
new file mode 100755
index 00000000..d9432142
--- /dev/null
+++ b/tests/changequ.3.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# changequ.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1920
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Macro `FOO'.')
+changequote(, )
+foo
+`foo'
+EOF
+
+cat <<\EOF >ok
+
+
+Macro `FOO'.
+`Macro `FOO'.'
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changesy.1.test b/tests/changesy.1.test
new file mode 100755
index 00000000..76512aae
--- /dev/null
+++ b/tests/changesy.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# changesy.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2126
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test.1', `TEST ONE')
+__file__
+changesyntax(`O_', `W.')
+__file__
+test.1
+EOF
+
+cat <<\EOF >ok
+
+in
+
+__file__
+TEST ONE
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changesy.2.test b/tests/changesy.2.test
new file mode 100755
index 00000000..d34dbb29
--- /dev/null
+++ b/tests/changesy.2.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# changesy.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2142
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `$#')
+test(a, b, c)
+changesyntax(`(<', `,|', `)>', `O(,)')
+test(a, b, c)
+test<a|b|c>
+EOF
+
+cat <<\EOF >ok
+
+3
+
+0(a, b, c)
+3
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changesy.3.test b/tests/changesy.3.test
new file mode 100755
index 00000000..15a51f77
--- /dev/null
+++ b/tests/changesy.3.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# changesy.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2159
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `$1$2$3')
+test(a, b, c)
+changesyntax(`O ')
+test(a, b, c)
+EOF
+
+cat <<\EOF >ok
+
+abc
+
+a b c
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changesy.4.test b/tests/changesy.4.test
new file mode 100755
index 00000000..5dcde934
--- /dev/null
+++ b/tests/changesy.4.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# changesy.4.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2178
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`@', `TEST')
+@
+changesyntax(`A@')
+@
+EOF
+
+cat <<\EOF >ok
+
+@
+
+TEST
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changesy.5.test b/tests/changesy.5.test
new file mode 100755
index 00000000..1156668f
--- /dev/null
+++ b/tests/changesy.5.test
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# changesy.5.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2202
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `TEST')
+changesyntax(`L<', `R>')
+<test>
+`test>
+changequote(<[>, `]')
+<test>
+[test]
+EOF
+
+cat <<\EOF >ok
+
+
+test
+test
+
+<TEST>
+test
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changesy.6.test b/tests/changesy.6.test
new file mode 100755
index 00000000..cae2ee23
--- /dev/null
+++ b/tests/changesy.6.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# changesy.6.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2224
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changesyntax(`({<', `)}>', `,;:', `O(,)')
+eval{2**4-1; 2 : 8>
+EOF
+
+cat <<\EOF >ok
+
+00001111
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/changesy.7.test b/tests/changesy.7.test
new file mode 100755
index 00000000..9d4b4b08
--- /dev/null
+++ b/tests/changesy.7.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# changesy.7.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2235
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `==$1==')
+changequote(`<<', `>>')
+changesyntax(<<L[>>, <<R]>>)
+test(<<testing]>>)
+test([testing>>])
+test([<<testing>>])
+EOF
+
+cat <<\EOF >ok
+
+
+
+==testing]==
+==testing>>==
+==<<testing>>==
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/cleardiv.1.test b/tests/cleardiv.1.test
new file mode 100755
index 00000000..40f09405
--- /dev/null
+++ b/tests/cleardiv.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# cleardiv.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2739
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert(-1)
+undivert
+EOF
+
+cat <<\EOF >ok
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/cleardiv.2.test b/tests/cleardiv.2.test
new file mode 100755
index 00000000..1f5df3ac
--- /dev/null
+++ b/tests/cleardiv.2.test
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# cleardiv.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2754
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`cleardivert',
+`pushdef(`_num', divnum)divert(-1)undivert($@)divert(_num)popdef(`_num')')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/define.1.test b/tests/define.1.test
new file mode 100755
index 00000000..cffdbacb
--- /dev/null
+++ b/tests/define.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# define.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 988
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello world.')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Hello world.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/define.2.test b/tests/define.2.test
new file mode 100755
index 00000000..e4df34eb
--- /dev/null
+++ b/tests/define.2.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# define.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1008
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`array', `defn(format(``array[%d]'', `$1'))')
+define(`array_set', `define(format(``array[%d]'', `$1'), `$2')')
+array_set(4, `array element no. 4')
+array_set(17, `array element no. 17')
+array(4)
+array(eval(10+7))
+EOF
+
+cat <<\EOF >ok
+
+
+
+
+array element no. 4
+array element no. 17
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/defn.1.test b/tests/defn.1.test
new file mode 100755
index 00000000..bf54769c
--- /dev/null
+++ b/tests/defn.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# defn.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1231
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`zap', defn(`undefine'))
+zap(`undefine')
+undefine(`zap')
+EOF
+
+cat <<\EOF >ok
+
+
+undefine(zap)
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/defn.2.test b/tests/defn.2.test
new file mode 100755
index 00000000..33ea48bd
--- /dev/null
+++ b/tests/defn.2.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# defn.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1251
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`string', `The macro dnl is very useful
+')
+string
+defn(`string')
+EOF
+
+cat <<\EOF >ok
+
+The macro
+The macro dnl is very useful
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/defs b/tests/defs
new file mode 100644
index 00000000..cf97e3b3
--- /dev/null
+++ b/tests/defs
@@ -0,0 +1,54 @@
+# -*- ksh -*-
+# Defines for GNU m4 testing environment.
+# Erick Branderhorst <Erick.Branderhorst@asml.nl>
+
+# Ensure $srcdir set correctly.
+test -f ${srcdir}/defs || {
+ echo "defs: installation error" 1>&2
+ exit 1
+}
+
+# If srcdir is relative, we need to modify it.
+case "$srcdir" in
+ /*)
+ ;;
+
+ *)
+ srcdir="../$srcdir"
+ ;;
+esac
+
+rm -rf testSubDir > /dev/null 2>&1
+mkdir testSubDir
+cd testSubDir
+
+# Build appropriate environment in test directory. Eg create
+# configure.in, touch all necessary files, etc.
+
+# nothing yet
+
+# See how redirections should work. User can set VERBOSE to see all
+# output.
+test -z "$VERBOSE" && {
+ exec > /dev/null 2>&1
+}
+
+# User can set MAKE to choose which make to use. Must use GNU make.
+test -z "$MAKE" && MAKE=make
+
+echo "=== Running test $0"
+
+# See how GNU m4 should be run. No options as default.
+test -z "$M4" && M4=../../src/m4
+
+# See how cmp should be run.
+test -z "$CMP" && CMP=cmp
+
+# Setting nls related vars. Override them in the test when needed.
+LANGUAGE=C
+export LANGUAGE
+LC_ALL=C
+export LC_ALL
+LANG=C
+export LANG
+
diff --git a/tests/divert.1.test b/tests/divert.1.test
new file mode 100755
index 00000000..3a2a82ac
--- /dev/null
+++ b/tests/divert.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# divert.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2581
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted.
+divert
+This text is not diverted.
+EOF
+
+cat <<\EOF >ok
+
+This text is not diverted.
+
+This text is diverted.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/divert.2.test b/tests/divert.2.test
new file mode 100755
index 00000000..2f22d845
--- /dev/null
+++ b/tests/divert.2.test
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# divert.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2601
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(-1)
+define(`foo', `Macro `foo'.')
+define(`bar', `Macro `bar'.')
+divert
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/divnum.1.test b/tests/divnum.1.test
new file mode 100755
index 00000000..c1c2638d
--- /dev/null
+++ b/tests/divnum.1.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# divnum.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2708
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+Initial divnum
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert
+EOF
+
+cat <<\EOF >ok
+Initial 0
+
+
+Diversion one: 1
+
+Diversion two: 2
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/dnl.1.test b/tests/dnl.1.test
new file mode 100755
index 00000000..ecfa0077
--- /dev/null
+++ b/tests/dnl.1.test
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# dnl.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1858
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
+foo
+EOF
+
+cat <<\EOF >ok
+Macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/dumpdef.1.test b/tests/dumpdef.1.test
new file mode 100755
index 00000000..45a21ddd
--- /dev/null
+++ b/tests/dumpdef.1.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# dumpdef.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1661
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello world.')
+dumpdef(`foo')
+dumpdef(`define')
+EOF
+
+cat <<\EOF >ok
+
+
+
+EOF
+
+cat <<\EOF >okerr
+foo: `Hello world.'
+define: <define>
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/errprint.1.test b/tests/errprint.1.test
new file mode 100755
index 00000000..b1d6145c
--- /dev/null
+++ b/tests/errprint.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# errprint.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3427
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+errprint(`Illegal arguments to forloop
+')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+Illegal arguments to forloop
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/errprint.2.test b/tests/errprint.2.test
new file mode 100755
index 00000000..8f44ca0a
--- /dev/null
+++ b/tests/errprint.2.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# errprint.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3452
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+errprint(`m4:'__file__:__line__: `Input error
+')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+m4:in:1: Input error
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/esyscmd.1.test b/tests/esyscmd.1.test
new file mode 100755
index 00000000..b32c6ced
--- /dev/null
+++ b/tests/esyscmd.1.test
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# esyscmd.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3316
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`vice', `esyscmd(grep Vice ../Makefile)')
+vice
+EOF
+
+cat <<\EOF >ok
+
+# Ty Coon, President of Vice
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/eval.1.test b/tests/eval.1.test
new file mode 100755
index 00000000..ef9a3ca3
--- /dev/null
+++ b/tests/eval.1.test
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# eval.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3200
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+eval(-3 * 5)
+eval(index(`Hello world', `llo') >= 0)
+define(`square', `eval(($1)**2)')
+square(9)
+square(square(5)+1)
+define(`foo', `666')
+eval(`foo'/6)
+eval(foo/6)
+EOF
+
+cat <<\EOF >ok
+-15
+1
+
+81
+676
+
+
+111
+EOF
+
+cat <<\EOF >okerr
+in:7: m4: Bad expression in eval: foo/6
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/eval.2.test b/tests/eval.2.test
new file mode 100755
index 00000000..374b7039
--- /dev/null
+++ b/tests/eval.2.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# eval.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3231
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+eval(666, 10)
+eval(666, 11)
+eval(666, 6)
+eval(666, 6, 10)
+eval(-666, 6, 10)
+EOF
+
+cat <<\EOF >ok
+666
+556
+3030
+0000003030
+-000003030
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/foo b/tests/foo
new file mode 100644
index 00000000..5716ca59
--- /dev/null
+++ b/tests/foo
@@ -0,0 +1 @@
+bar
diff --git a/tests/format.1.test b/tests/format.1.test
new file mode 100755
index 00000000..0434ff23
--- /dev/null
+++ b/tests/format.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# format.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3036
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `The brown fox jumped over the lazy dog')
+format(`The string "%s" is %d characters long', foo, len(foo))
+EOF
+
+cat <<\EOF >ok
+
+The string "The brown fox jumped over the lazy dog" is 38 characters long
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/argument.1.test b/tests/generated-tests/argument.1.test
new file mode 100755
index 00000000..25b1d819
--- /dev/null
+++ b/tests/generated-tests/argument.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/argument.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1030
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`exch', `$2, $1')
+exch(arg1, arg2)
+EOF
+
+cat <<\EOF >ok
+
+arg2, arg1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/argument.2.test b/tests/generated-tests/argument.2.test
new file mode 100755
index 00000000..c077ec2a
--- /dev/null
+++ b/tests/generated-tests/argument.2.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# generated-tests/argument.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1040
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`exch', `$2, $1')
+define(exch(``expansion text'', ``macro''))
+macro
+EOF
+
+cat <<\EOF >ok
+
+
+expansion text
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/argument.3.test b/tests/generated-tests/argument.3.test
new file mode 100755
index 00000000..2a514172
--- /dev/null
+++ b/tests/generated-tests/argument.3.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/argument.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1060
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', ``Macro name: $0'')
+test
+EOF
+
+cat <<\EOF >ok
+
+Macro name: test
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/argument.4.test b/tests/generated-tests/argument.4.test
new file mode 100755
index 00000000..2459f966
--- /dev/null
+++ b/tests/generated-tests/argument.4.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/argument.4.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1070
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `This is macro `foo'.')
+foo
+EOF
+
+cat <<\EOF >ok
+
+This is macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changeco.1.test b/tests/generated-tests/changeco.1.test
new file mode 100755
index 00000000..cc95cdbc
--- /dev/null
+++ b/tests/generated-tests/changeco.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# generated-tests/changeco.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1953
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`comment', `COMMENT')
+# A normal comment
+changecom(`/*', `*/')
+# Not a comment anymore
+But: /* this is a comment now */ while this is not a comment
+EOF
+
+cat <<\EOF >ok
+
+# A normal comment
+
+# Not a COMMENT anymore
+But: /* this is a comment now */ while this is not a COMMENT
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changeco.2.test b/tests/generated-tests/changeco.2.test
new file mode 100755
index 00000000..4e4fc01b
--- /dev/null
+++ b/tests/generated-tests/changeco.2.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# generated-tests/changeco.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1974
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`comment', `COMMENT')
+changecom
+# Not a comment anymore
+EOF
+
+cat <<\EOF >ok
+
+
+# Not a COMMENT anymore
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changequ.1.test b/tests/generated-tests/changequ.1.test
new file mode 100755
index 00000000..b66db9cf
--- /dev/null
+++ b/tests/generated-tests/changequ.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# generated-tests/changequ.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1889
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changequote([, ])
+define([foo], [Macro [foo].])
+foo
+EOF
+
+cat <<\EOF >ok
+
+
+Macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changequ.2.test b/tests/generated-tests/changequ.2.test
new file mode 100755
index 00000000..6ae416a9
--- /dev/null
+++ b/tests/generated-tests/changequ.2.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# generated-tests/changequ.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1901
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changequote([[, ]])
+define([[foo]], [[Macro [[[foo]]].]])
+foo
+EOF
+
+cat <<\EOF >ok
+
+
+Macro [foo].
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changequ.3.test b/tests/generated-tests/changequ.3.test
new file mode 100755
index 00000000..baed4cdb
--- /dev/null
+++ b/tests/generated-tests/changequ.3.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/changequ.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1913
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Macro `FOO'.')
+changequote(, )
+foo
+`foo'
+EOF
+
+cat <<\EOF >ok
+
+
+Macro `FOO'.
+`Macro `FOO'.'
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changesy.1.test b/tests/generated-tests/changesy.1.test
new file mode 100755
index 00000000..7e925d10
--- /dev/null
+++ b/tests/generated-tests/changesy.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# generated-tests/changesy.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2119
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test.1', `TEST ONE')
+__file__
+changesyntax(`O_', `W.')
+__file__
+test.1
+EOF
+
+cat <<\EOF >ok
+
+in
+
+__file__
+TEST ONE
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changesy.2.test b/tests/generated-tests/changesy.2.test
new file mode 100755
index 00000000..af4aa27c
--- /dev/null
+++ b/tests/generated-tests/changesy.2.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# generated-tests/changesy.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2135
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `$#')
+test(a, b, c)
+changesyntax(`(<', `,|', `)>', `O(,)')
+test(a, b, c)
+test<a|b|c>
+EOF
+
+cat <<\EOF >ok
+
+3
+
+0(a, b, c)
+3
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changesy.3.test b/tests/generated-tests/changesy.3.test
new file mode 100755
index 00000000..6229d772
--- /dev/null
+++ b/tests/generated-tests/changesy.3.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/changesy.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2152
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `$1$2$3')
+test(a, b, c)
+changesyntax(`O ')
+test(a, b, c)
+EOF
+
+cat <<\EOF >ok
+
+abc
+
+a b c
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changesy.4.test b/tests/generated-tests/changesy.4.test
new file mode 100755
index 00000000..64572a97
--- /dev/null
+++ b/tests/generated-tests/changesy.4.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/changesy.4.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2171
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`@', `TEST')
+@
+changesyntax(`A@')
+@
+EOF
+
+cat <<\EOF >ok
+
+@
+
+TEST
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changesy.5.test b/tests/generated-tests/changesy.5.test
new file mode 100755
index 00000000..83608521
--- /dev/null
+++ b/tests/generated-tests/changesy.5.test
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# generated-tests/changesy.5.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2195
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `TEST')
+changesyntax(`L<', `R>')
+<test>
+`test>
+changequote(<[>, `]')
+<test>
+[test]
+EOF
+
+cat <<\EOF >ok
+
+
+test
+test
+
+<TEST>
+test
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changesy.6.test b/tests/generated-tests/changesy.6.test
new file mode 100755
index 00000000..14066fec
--- /dev/null
+++ b/tests/generated-tests/changesy.6.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/changesy.6.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2217
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changesyntax(`({<', `)}>', `,;:', `O(,)')
+eval{2**4-1; 2 : 8>
+EOF
+
+cat <<\EOF >ok
+
+00001111
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changesy.7.test b/tests/generated-tests/changesy.7.test
new file mode 100755
index 00000000..9e70c202
--- /dev/null
+++ b/tests/generated-tests/changesy.7.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# generated-tests/changesy.7.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2228
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `==$1==')
+changequote(`<<', `>>')
+changesyntax(<<L[>>, <<R]>>)
+test(<<testing]>>)
+test([testing>>])
+test([<<testing>>])
+EOF
+
+cat <<\EOF >ok
+
+
+
+==testing]==
+==testing>>==
+==testing==
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/changesy.8.test b/tests/generated-tests/changesy.8.test
new file mode 100755
index 00000000..a087f85a
--- /dev/null
+++ b/tests/generated-tests/changesy.8.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# generated-tests/changesy.8.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2282
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `==$1==')
+changequote(`<<', `>>')
+changesyntax(<<L[>>, <<R]>>)
+test(<<testing]>>)
+test([testing>>])
+test([<<testing>>])
+EOF
+
+cat <<\EOF >ok
+
+
+
+==testing]==
+==testing>>==
+==testing==
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/cleardiv.1.test b/tests/generated-tests/cleardiv.1.test
new file mode 100755
index 00000000..c7dc0655
--- /dev/null
+++ b/tests/generated-tests/cleardiv.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# generated-tests/cleardiv.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2732
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert(-1)
+undivert
+EOF
+
+cat <<\EOF >ok
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/cleardiv.2.test b/tests/generated-tests/cleardiv.2.test
new file mode 100755
index 00000000..23324698
--- /dev/null
+++ b/tests/generated-tests/cleardiv.2.test
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# generated-tests/cleardiv.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2747
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`cleardivert',
+`pushdef(`_num', divnum)divert(-1)undivert($@)divert(_num)popdef(`_num')')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/define.1.test b/tests/generated-tests/define.1.test
new file mode 100755
index 00000000..eefece84
--- /dev/null
+++ b/tests/generated-tests/define.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/define.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 981
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello world.')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Hello world.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/define.2.test b/tests/generated-tests/define.2.test
new file mode 100755
index 00000000..1b18fe06
--- /dev/null
+++ b/tests/generated-tests/define.2.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# generated-tests/define.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1001
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`array', `defn(format(``array[%d]'', `$1'))')
+define(`array_set', `define(format(``array[%d]'', `$1'), `$2')')
+array_set(4, `array element no. 4')
+array_set(17, `array element no. 17')
+array(4)
+array(eval(10+7))
+EOF
+
+cat <<\EOF >ok
+
+
+
+
+array element no. 4
+array element no. 17
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/defn.1.test b/tests/generated-tests/defn.1.test
new file mode 100755
index 00000000..1922b358
--- /dev/null
+++ b/tests/generated-tests/defn.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# generated-tests/defn.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1224
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`zap', defn(`undefine'))
+zap(`undefine')
+undefine(`zap')
+EOF
+
+cat <<\EOF >ok
+
+
+undefine(zap)
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/defn.2.test b/tests/generated-tests/defn.2.test
new file mode 100755
index 00000000..0cac7363
--- /dev/null
+++ b/tests/generated-tests/defn.2.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/defn.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1244
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`string', `The macro dnl is very useful
+')
+string
+defn(`string')
+EOF
+
+cat <<\EOF >ok
+
+The macro
+The macro dnl is very useful
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/divert.1.test b/tests/generated-tests/divert.1.test
new file mode 100755
index 00000000..83d5d9a2
--- /dev/null
+++ b/tests/generated-tests/divert.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/divert.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2574
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted.
+divert
+This text is not diverted.
+EOF
+
+cat <<\EOF >ok
+
+This text is not diverted.
+
+This text is diverted.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/divert.2.test b/tests/generated-tests/divert.2.test
new file mode 100755
index 00000000..f5cd9f8c
--- /dev/null
+++ b/tests/generated-tests/divert.2.test
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# generated-tests/divert.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2594
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(-1)
+define(`foo', `Macro `foo'.')
+define(`bar', `Macro `bar'.')
+divert
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/divnum.1.test b/tests/generated-tests/divnum.1.test
new file mode 100755
index 00000000..ddcb689e
--- /dev/null
+++ b/tests/generated-tests/divnum.1.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# generated-tests/divnum.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2701
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+Initial divnum
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert
+EOF
+
+cat <<\EOF >ok
+Initial 0
+
+
+Diversion one: 1
+
+Diversion two: 2
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/dnl.1.test b/tests/generated-tests/dnl.1.test
new file mode 100755
index 00000000..b80528d5
--- /dev/null
+++ b/tests/generated-tests/dnl.1.test
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# generated-tests/dnl.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1851
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
+foo
+EOF
+
+cat <<\EOF >ok
+Macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/dumpdef.1.test b/tests/generated-tests/dumpdef.1.test
new file mode 100755
index 00000000..677a5974
--- /dev/null
+++ b/tests/generated-tests/dumpdef.1.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# generated-tests/dumpdef.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1654
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello world.')
+dumpdef(`foo')
+dumpdef(`define')
+EOF
+
+cat <<\EOF >ok
+
+
+
+EOF
+
+cat <<\EOF >okerr
+foo: `Hello world.'
+define: <define>
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/generated-tests/errprint.1.test b/tests/generated-tests/errprint.1.test
new file mode 100755
index 00000000..d89d95b8
--- /dev/null
+++ b/tests/generated-tests/errprint.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/errprint.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3420
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+errprint(`Illegal arguments to forloop
+')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+Illegal arguments to forloop
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/generated-tests/errprint.2.test b/tests/generated-tests/errprint.2.test
new file mode 100755
index 00000000..e7e6946b
--- /dev/null
+++ b/tests/generated-tests/errprint.2.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/errprint.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3445
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+errprint(`m4:'__file__:__line__: `Input error
+')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+m4:in:1: Input error
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/generated-tests/esyscmd.1.test b/tests/generated-tests/esyscmd.1.test
new file mode 100755
index 00000000..0f4135d5
--- /dev/null
+++ b/tests/generated-tests/esyscmd.1.test
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# generated-tests/esyscmd.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3309
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`vice', `esyscmd(grep Vice ../Makefile)')
+vice
+EOF
+
+cat <<\EOF >ok
+
+# Ty Coon, President of Vice
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/eval.1.test b/tests/generated-tests/eval.1.test
new file mode 100755
index 00000000..73fd306b
--- /dev/null
+++ b/tests/generated-tests/eval.1.test
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# generated-tests/eval.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3193
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+eval(-3 * 5)
+eval(index(`Hello world', `llo') >= 0)
+define(`square', `eval(($1)**2)')
+square(9)
+square(square(5)+1)
+define(`foo', `666')
+eval(`foo'/6)
+eval(foo/6)
+EOF
+
+cat <<\EOF >ok
+-15
+1
+
+81
+676
+
+
+111
+EOF
+
+cat <<\EOF >okerr
+in:7: m4: Bad expression in eval: foo/6
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/generated-tests/eval.2.test b/tests/generated-tests/eval.2.test
new file mode 100755
index 00000000..443672d1
--- /dev/null
+++ b/tests/generated-tests/eval.2.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# generated-tests/eval.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3224
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+eval(666, 10)
+eval(666, 11)
+eval(666, 6)
+eval(666, 6, 10)
+eval(-666, 6, 10)
+EOF
+
+cat <<\EOF >ok
+666
+556
+3030
+0000003030
+-000003030
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/format.1.test b/tests/generated-tests/format.1.test
new file mode 100755
index 00000000..52fc5029
--- /dev/null
+++ b/tests/generated-tests/format.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/format.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3029
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `The brown fox jumped over the lazy dog')
+format(`The string "%s" is %d characters long', foo, len(foo))
+EOF
+
+cat <<\EOF >ok
+
+The string "The brown fox jumped over the lazy dog" is 38 characters long
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/ifdef.1.test b/tests/generated-tests/ifdef.1.test
new file mode 100755
index 00000000..559745fa
--- /dev/null
+++ b/tests/generated-tests/ifdef.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# generated-tests/ifdef.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1434
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+define(`foo', `')
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+EOF
+
+cat <<\EOF >ok
+foo is not defined
+
+foo is defined
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/ifelse.1.test b/tests/generated-tests/ifelse.1.test
new file mode 100755
index 00000000..82b2770c
--- /dev/null
+++ b/tests/generated-tests/ifelse.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/ifelse.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1472
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifelse(`foo', `bar', `true')
+ifelse(`foo', `foo', `true')
+ifelse(`foo', `bar', `true', `false')
+ifelse(`foo', `foo', `true', `false')
+EOF
+
+cat <<\EOF >ok
+
+true
+false
+true
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/ifelse.2.test b/tests/generated-tests/ifelse.2.test
new file mode 100755
index 00000000..9181abd0
--- /dev/null
+++ b/tests/generated-tests/ifelse.2.test
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# generated-tests/ifelse.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1491
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifelse(foo, bar, `third', gnu, gnats, `sixth', `seventh')
+EOF
+
+cat <<\EOF >ok
+seventh
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/include.1.test b/tests/generated-tests/include.1.test
new file mode 100755
index 00000000..cd8274bd
--- /dev/null
+++ b/tests/generated-tests/include.1.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# generated-tests/include.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2448
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(`no-such-file')
+sinclude(`no-such-file')
+EOF
+
+cat <<\EOF >ok
+
+
+EOF
+
+cat <<\EOF >okerr
+in:1: m4: Cannot open no-such-file: No such file or directory
+EOF
+
+M4PATH=$srcdir $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/generated-tests/include.2.test b/tests/generated-tests/include.2.test
new file mode 100755
index 00000000..94446fd7
--- /dev/null
+++ b/tests/generated-tests/include.2.test
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# generated-tests/include.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2468
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `FOO')
+include(`incl.m4')
+EOF
+
+cat <<\EOF >ok
+
+Include file start
+FOO
+Include file end
+
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/include.3.test b/tests/generated-tests/include.3.test
new file mode 100755
index 00000000..1cb768d9
--- /dev/null
+++ b/tests/generated-tests/include.3.test
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# generated-tests/include.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2483
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`bar', include(`incl.m4'))
+This is `bar': >>>bar<<<
+EOF
+
+cat <<\EOF >ok
+
+This is bar: >>>Include file start
+foo
+Include file end
+<<<
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/incr.1.test b/tests/generated-tests/incr.1.test
new file mode 100755
index 00000000..f07ddf7c
--- /dev/null
+++ b/tests/generated-tests/incr.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/incr.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3099
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+incr(4)
+decr(7)
+EOF
+
+cat <<\EOF >ok
+5
+6
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/index.1.test b/tests/generated-tests/index.1.test
new file mode 100755
index 00000000..11768455
--- /dev/null
+++ b/tests/generated-tests/index.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/index.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2815
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+index(`gnus, gnats, and armadillos', `nat')
+index(`gnus, gnats, and armadillos', `dag')
+EOF
+
+cat <<\EOF >ok
+7
+-1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/indir.1.test b/tests/generated-tests/indir.1.test
new file mode 100755
index 00000000..c37cc49b
--- /dev/null
+++ b/tests/generated-tests/indir.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# generated-tests/indir.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1363
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`$$internal$macro', `Internal macro (name `$0')')
+$$internal$macro
+indir(`$$internal$macro')
+EOF
+
+cat <<\EOF >ok
+
+$$internal$macro
+Internal macro (name $$internal$macro)
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/len.1.test b/tests/generated-tests/len.1.test
new file mode 100755
index 00000000..dac41506
--- /dev/null
+++ b/tests/generated-tests/len.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/len.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2789
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+len()
+len(`abcdef')
+EOF
+
+cat <<\EOF >ok
+0
+6
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/loops.1.test b/tests/generated-tests/loops.1.test
new file mode 100755
index 00000000..880f95d9
--- /dev/null
+++ b/tests/generated-tests/loops.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# generated-tests/loops.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1528
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+shift
+shift(bar)
+shift(foo, bar, baz)
+EOF
+
+cat <<\EOF >ok
+
+
+bar,baz
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/loops.2.test b/tests/generated-tests/loops.2.test
new file mode 100755
index 00000000..7b537032
--- /dev/null
+++ b/tests/generated-tests/loops.2.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# generated-tests/loops.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1540
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`reverse', `ifelse($#, 0, , $#, 1, ``$1'',
+ `reverse(shift($@)), `$1'')')
+reverse
+reverse(foo)
+reverse(foo, bar, gnats, and gnus)
+EOF
+
+cat <<\EOF >ok
+
+
+foo
+and gnus, gnats, bar, foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/m4exit.1.test b/tests/generated-tests/m4exit.1.test
new file mode 100755
index 00000000..78aba0fd
--- /dev/null
+++ b/tests/generated-tests/m4exit.1.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# generated-tests/m4exit.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3468
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`fatal_error', `errprint(`m4: '__file__: __line__`: fatal error: $*
+')m4exit(1)')
+fatal_error(`This is a BAD one, buster')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+m4: in: 3: fatal error: This is a BAD one, buster
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/generated-tests/m4wrap.1.test b/tests/generated-tests/m4wrap.1.test
new file mode 100755
index 00000000..0f9419dd
--- /dev/null
+++ b/tests/generated-tests/m4wrap.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/m4wrap.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2389
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`cleanup', `This is the `cleanup' actions.
+')
+m4wrap(`cleanup')
+This is the first and last normal input line.
+EOF
+
+cat <<\EOF >ok
+
+
+This is the first and last normal input line.
+This is the cleanup actions.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/patsubst.1.test b/tests/generated-tests/patsubst.1.test
new file mode 100755
index 00000000..4f04ac25
--- /dev/null
+++ b/tests/generated-tests/patsubst.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# generated-tests/patsubst.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2977
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+patsubst(`GNUs not Unix', `^', `OBS: ')
+patsubst(`GNUs not Unix', `\<', `OBS: ')
+patsubst(`GNUs not Unix', `\w*', `(\&)')
+patsubst(`GNUs not Unix', `\w+', `(\&)')
+patsubst(`GNUs not Unix', `[A-Z][a-z]+')
+EOF
+
+cat <<\EOF >ok
+OBS: GNUs not Unix
+OBS: GNUs OBS: not OBS: Unix
+(GNUs)() (not)() (Unix)
+(GNUs) (not) (Unix)
+GN not
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/patsubst.2.test b/tests/generated-tests/patsubst.2.test
new file mode 100755
index 00000000..d651a184
--- /dev/null
+++ b/tests/generated-tests/patsubst.2.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/patsubst.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2994
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
+define(`downcase', `translit(`$*', `A-Z', `a-z')')dnl
+define(`capitalize1',
+ `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')dnl
+define(`capitalize',
+ `patsubst(`$1', `\w+', `capitalize1(`\&')')')dnl
+capitalize(`GNUs not Unix')
+EOF
+
+cat <<\EOF >ok
+Gnus Not Unix
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/pseudoar.1.test b/tests/generated-tests/pseudoar.1.test
new file mode 100755
index 00000000..de5cabc2
--- /dev/null
+++ b/tests/generated-tests/pseudoar.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/pseudoar.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1094
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`nargs', `$#')
+nargs
+nargs()
+nargs(arg1, arg2, arg3)
+EOF
+
+cat <<\EOF >ok
+
+0
+1
+3
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/pseudoar.2.test b/tests/generated-tests/pseudoar.2.test
new file mode 100755
index 00000000..b8418771
--- /dev/null
+++ b/tests/generated-tests/pseudoar.2.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/pseudoar.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1108
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo', `$*')
+echo(arg1, arg2, arg3 , arg4)
+EOF
+
+cat <<\EOF >ok
+
+arg1,arg2,arg3 ,arg4
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/pseudoar.3.test b/tests/generated-tests/pseudoar.3.test
new file mode 100755
index 00000000..26f6ebb3
--- /dev/null
+++ b/tests/generated-tests/pseudoar.3.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/pseudoar.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1119
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo', `$@')
+echo(arg1, arg2, arg3 , arg4)
+EOF
+
+cat <<\EOF >ok
+
+arg1,arg2,arg3 ,arg4
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/pseudoar.4.test b/tests/generated-tests/pseudoar.4.test
new file mode 100755
index 00000000..8622426f
--- /dev/null
+++ b/tests/generated-tests/pseudoar.4.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# generated-tests/pseudoar.4.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1129
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo1', `$*')
+define(`echo2', `$@')
+define(`foo', `This is macro `foo'.')
+echo1(foo)
+echo2(foo)
+EOF
+
+cat <<\EOF >ok
+
+
+
+This is macro This is macro foo..
+This is macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/pseudoar.5.test b/tests/generated-tests/pseudoar.5.test
new file mode 100755
index 00000000..1ed05635
--- /dev/null
+++ b/tests/generated-tests/pseudoar.5.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/pseudoar.5.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1149
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `$$$ hello $$$')
+foo
+EOF
+
+cat <<\EOF >ok
+
+$$$ hello $$$
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/pushdef.1.test b/tests/generated-tests/pushdef.1.test
new file mode 100755
index 00000000..09d5f945
--- /dev/null
+++ b/tests/generated-tests/pushdef.1.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# generated-tests/pushdef.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1288
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Expansion one.')
+foo
+pushdef(`foo', `Expansion two.')
+foo
+popdef(`foo')
+foo
+popdef(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Expansion one.
+
+Expansion two.
+
+Expansion one.
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/pushdef.2.test b/tests/generated-tests/pushdef.2.test
new file mode 100755
index 00000000..091c27e1
--- /dev/null
+++ b/tests/generated-tests/pushdef.2.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# generated-tests/pushdef.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1312
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Expansion one.')
+foo
+pushdef(`foo', `Expansion two.')
+foo
+define(`foo', `Second expansion two.')
+foo
+undefine(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Expansion one.
+
+Expansion two.
+
+Second expansion two.
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/regexp.1.test b/tests/generated-tests/regexp.1.test
new file mode 100755
index 00000000..df471907
--- /dev/null
+++ b/tests/generated-tests/regexp.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/regexp.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2847
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+regexp(`GNUs not Unix', `\<[a-z]\w+')
+regexp(`GNUs not Unix', `\<Q\w*')
+EOF
+
+cat <<\EOF >ok
+5
+-1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/regexp.2.test b/tests/generated-tests/regexp.2.test
new file mode 100755
index 00000000..22cb99c6
--- /dev/null
+++ b/tests/generated-tests/regexp.2.test
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# generated-tests/regexp.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2859
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
+EOF
+
+cat <<\EOF >ok
+*** Unix *** nix ***
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/substr.1.test b/tests/generated-tests/substr.1.test
new file mode 100755
index 00000000..4ad45539
--- /dev/null
+++ b/tests/generated-tests/substr.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# generated-tests/substr.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2885
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+substr(`gnus, gnats, and armadillos', 6)
+substr(`gnus, gnats, and armadillos', 6, 5)
+EOF
+
+cat <<\EOF >ok
+gnats, and armadillos
+gnats
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/symbols.1.test b/tests/generated-tests/symbols.1.test
new file mode 100755
index 00000000..4414ee13
--- /dev/null
+++ b/tests/generated-tests/symbols.1.test
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# generated-tests/symbols.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1442
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+symbols(`ifndef', `ifdef', `define', `undef')
+EOF
+
+cat <<\EOF >ok
+define,ifdef
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/sysval.1.test b/tests/generated-tests/sysval.1.test
new file mode 100755
index 00000000..5cb177f1
--- /dev/null
+++ b/tests/generated-tests/sysval.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/sysval.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3340
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+syscmd(`false')
+ifelse(sysval, 0, zero, nonzero)
+syscmd(`true')
+sysval
+EOF
+
+cat <<\EOF >ok
+
+nonzero
+
+0
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/trace.1.test b/tests/generated-tests/trace.1.test
new file mode 100755
index 00000000..9acf3a12
--- /dev/null
+++ b/tests/generated-tests/trace.1.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# generated-tests/trace.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1699
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello World.')
+define(`echo', `$@')
+traceon(`foo', `echo')
+foo
+echo(gnus, and gnats)
+EOF
+
+cat <<\EOF >ok
+
+
+
+Hello World.
+gnus,and gnats
+EOF
+
+cat <<\EOF >okerr
+m4trace: -1- foo -> `Hello World.'
+m4trace: -1- echo(`gnus', `and gnats') -> ``gnus',`and gnats''
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/generated-tests/translit.1.test b/tests/generated-tests/translit.1.test
new file mode 100755
index 00000000..da6710c7
--- /dev/null
+++ b/tests/generated-tests/translit.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# generated-tests/translit.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2926
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+translit(`GNUs not Unix', `A-Z')
+translit(`GNUs not Unix', `a-z', `A-Z')
+translit(`GNUs not Unix', `A-Z', `z-a')
+EOF
+
+cat <<\EOF >ok
+s not nix
+GNUS NOT UNIX
+tmfs not fnix
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/undefine.1.test b/tests/generated-tests/undefine.1.test
new file mode 100755
index 00000000..bac0cd29
--- /dev/null
+++ b/tests/generated-tests/undefine.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# generated-tests/undefine.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1180
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+foo
+define(`foo', `expansion text')
+foo
+undefine(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+foo
+
+expansion text
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/undivert.1.test b/tests/generated-tests/undivert.1.test
new file mode 100755
index 00000000..18c904ba
--- /dev/null
+++ b/tests/generated-tests/undivert.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# generated-tests/undivert.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2625
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted.
+divert
+This text is not diverted.
+undivert(1)
+EOF
+
+cat <<\EOF >ok
+
+This text is not diverted.
+
+This text is diverted.
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/undivert.2.test b/tests/generated-tests/undivert.2.test
new file mode 100755
index 00000000..44485600
--- /dev/null
+++ b/tests/generated-tests/undivert.2.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# generated-tests/undivert.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2649
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted first.
+divert(0)undivert(1)dnl
+undivert(1)
+divert(1)
+This text is also diverted but not appended.
+divert(0)undivert(1)dnl
+EOF
+
+cat <<\EOF >ok
+
+This text is diverted first.
+
+
+This text is also diverted but not appended.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/generated-tests/undivert.3.test b/tests/generated-tests/undivert.3.test
new file mode 100755
index 00000000..a85a9d0c
--- /dev/null
+++ b/tests/generated-tests/undivert.3.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# generated-tests/undivert.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2675
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`bar', `BAR')
+undivert(`foo')
+include(`foo')
+EOF
+
+cat <<\EOF >ok
+
+bar
+
+BAR
+
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/argument.1.m4 b/tests/gentest/argument.1.m4
new file mode 100755
index 00000000..04909dc9
--- /dev/null
+++ b/tests/gentest/argument.1.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/argument.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1036
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`exch', `$2, $1')
+exch(arg1, arg2)
+EOF
+
+cat <<\EOF >ok
+
+arg2, arg1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/argument.1.test b/tests/gentest/argument.1.test
new file mode 100755
index 00000000..e8f48197
--- /dev/null
+++ b/tests/gentest/argument.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/argument.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1036
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`exch', `$2, $1')
+exch(arg1, arg2)
+EOF
+
+cat <<\EOF >ok
+
+arg2, arg1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/argument.2.m4 b/tests/gentest/argument.2.m4
new file mode 100755
index 00000000..59814143
--- /dev/null
+++ b/tests/gentest/argument.2.m4
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/argument.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1046
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`exch', `$2, $1')
+define(exch(``expansion text'', ``macro''))
+macro
+EOF
+
+cat <<\EOF >ok
+
+
+expansion text
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/argument.2.test b/tests/gentest/argument.2.test
new file mode 100755
index 00000000..3e2149b5
--- /dev/null
+++ b/tests/gentest/argument.2.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/argument.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1046
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`exch', `$2, $1')
+define(exch(``expansion text'', ``macro''))
+macro
+EOF
+
+cat <<\EOF >ok
+
+
+expansion text
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/argument.3.m4 b/tests/gentest/argument.3.m4
new file mode 100755
index 00000000..3dae6ca9
--- /dev/null
+++ b/tests/gentest/argument.3.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/argument.3.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1066
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', ``Macro name: $0'')
+test
+EOF
+
+cat <<\EOF >ok
+
+Macro name: test
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/argument.3.test b/tests/gentest/argument.3.test
new file mode 100755
index 00000000..5ffdafd4
--- /dev/null
+++ b/tests/gentest/argument.3.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/argument.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1066
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', ``Macro name: $0'')
+test
+EOF
+
+cat <<\EOF >ok
+
+Macro name: test
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/argument.4.m4 b/tests/gentest/argument.4.m4
new file mode 100755
index 00000000..39389759
--- /dev/null
+++ b/tests/gentest/argument.4.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/argument.4.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1076
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `This is macro `foo'.')
+foo
+EOF
+
+cat <<\EOF >ok
+
+This is macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/argument.4.test b/tests/gentest/argument.4.test
new file mode 100755
index 00000000..b28f5638
--- /dev/null
+++ b/tests/gentest/argument.4.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/argument.4.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1076
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `This is macro `foo'.')
+foo
+EOF
+
+cat <<\EOF >ok
+
+This is macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changeco.1.m4 b/tests/gentest/changeco.1.m4
new file mode 100755
index 00000000..533b931b
--- /dev/null
+++ b/tests/gentest/changeco.1.m4
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/changeco.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1959
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`comment', `COMMENT')
+# A normal comment
+changecom(`/*', `*/')
+# Not a comment anymore
+But: /* this is a comment now */ while this is not a comment
+EOF
+
+cat <<\EOF >ok
+
+# A normal comment
+
+# Not a COMMENT anymore
+But: /* this is a comment now */ while this is not a COMMENT
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changeco.1.test b/tests/gentest/changeco.1.test
new file mode 100755
index 00000000..08ad873d
--- /dev/null
+++ b/tests/gentest/changeco.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/changeco.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1959
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`comment', `COMMENT')
+# A normal comment
+changecom(`/*', `*/')
+# Not a comment anymore
+But: /* this is a comment now */ while this is not a comment
+EOF
+
+cat <<\EOF >ok
+
+# A normal comment
+
+# Not a COMMENT anymore
+But: /* this is a comment now */ while this is not a COMMENT
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changeco.2.m4 b/tests/gentest/changeco.2.m4
new file mode 100755
index 00000000..dfd0aa1d
--- /dev/null
+++ b/tests/gentest/changeco.2.m4
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/changeco.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1980
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`comment', `COMMENT')
+changecom
+# Not a comment anymore
+EOF
+
+cat <<\EOF >ok
+
+
+# Not a COMMENT anymore
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changeco.2.test b/tests/gentest/changeco.2.test
new file mode 100755
index 00000000..c265d1f5
--- /dev/null
+++ b/tests/gentest/changeco.2.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/changeco.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1980
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`comment', `COMMENT')
+changecom
+# Not a comment anymore
+EOF
+
+cat <<\EOF >ok
+
+
+# Not a COMMENT anymore
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changequ.1.m4 b/tests/gentest/changequ.1.m4
new file mode 100755
index 00000000..7022cec9
--- /dev/null
+++ b/tests/gentest/changequ.1.m4
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/changequ.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1895
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changequote([, ])
+define([foo], [Macro [foo].])
+foo
+EOF
+
+cat <<\EOF >ok
+
+
+Macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changequ.1.test b/tests/gentest/changequ.1.test
new file mode 100755
index 00000000..f0f64f69
--- /dev/null
+++ b/tests/gentest/changequ.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/changequ.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1895
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changequote([, ])
+define([foo], [Macro [foo].])
+foo
+EOF
+
+cat <<\EOF >ok
+
+
+Macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changequ.2.m4 b/tests/gentest/changequ.2.m4
new file mode 100755
index 00000000..5eba166b
--- /dev/null
+++ b/tests/gentest/changequ.2.m4
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/changequ.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1907
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changequote([[, ]])
+define([[foo]], [[Macro [[[foo]]].]])
+foo
+EOF
+
+cat <<\EOF >ok
+
+
+Macro [foo].
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changequ.2.test b/tests/gentest/changequ.2.test
new file mode 100755
index 00000000..0ec4ad14
--- /dev/null
+++ b/tests/gentest/changequ.2.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/changequ.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1907
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changequote([[, ]])
+define([[foo]], [[Macro [[[foo]]].]])
+foo
+EOF
+
+cat <<\EOF >ok
+
+
+Macro [foo].
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changequ.3.m4 b/tests/gentest/changequ.3.m4
new file mode 100755
index 00000000..6174e994
--- /dev/null
+++ b/tests/gentest/changequ.3.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/changequ.3.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1919
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Macro `FOO'.')
+changequote(, )
+foo
+`foo'
+EOF
+
+cat <<\EOF >ok
+
+
+Macro `FOO'.
+`Macro `FOO'.'
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changequ.3.test b/tests/gentest/changequ.3.test
new file mode 100755
index 00000000..83a8544f
--- /dev/null
+++ b/tests/gentest/changequ.3.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/changequ.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1919
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Macro `FOO'.')
+changequote(, )
+foo
+`foo'
+EOF
+
+cat <<\EOF >ok
+
+
+Macro `FOO'.
+`Macro `FOO'.'
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.1.m4 b/tests/gentest/changesy.1.m4
new file mode 100755
index 00000000..c608a21f
--- /dev/null
+++ b/tests/gentest/changesy.1.m4
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/changesy.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2125
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test.1', `TEST ONE')
+__file__
+changesyntax(`O_', `W.')
+__file__
+test.1
+EOF
+
+cat <<\EOF >ok
+
+in
+
+__file__
+TEST ONE
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.1.test b/tests/gentest/changesy.1.test
new file mode 100755
index 00000000..344bf506
--- /dev/null
+++ b/tests/gentest/changesy.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/changesy.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2125
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test.1', `TEST ONE')
+__file__
+changesyntax(`O_', `W.')
+__file__
+test.1
+EOF
+
+cat <<\EOF >ok
+
+in
+
+__file__
+TEST ONE
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.2.m4 b/tests/gentest/changesy.2.m4
new file mode 100755
index 00000000..55a99375
--- /dev/null
+++ b/tests/gentest/changesy.2.m4
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/changesy.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2141
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `$#')
+test(a, b, c)
+changesyntax(`(<', `,|', `)>', `O(,)')
+test(a, b, c)
+test<a|b|c>
+EOF
+
+cat <<\EOF >ok
+
+3
+
+0(a, b, c)
+3
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.2.test b/tests/gentest/changesy.2.test
new file mode 100755
index 00000000..544a8753
--- /dev/null
+++ b/tests/gentest/changesy.2.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/changesy.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2141
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `$#')
+test(a, b, c)
+changesyntax(`(<', `,|', `)>', `O(,)')
+test(a, b, c)
+test<a|b|c>
+EOF
+
+cat <<\EOF >ok
+
+3
+
+0(a, b, c)
+3
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.3.m4 b/tests/gentest/changesy.3.m4
new file mode 100755
index 00000000..8f86a03a
--- /dev/null
+++ b/tests/gentest/changesy.3.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/changesy.3.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2158
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `$1$2$3')
+test(a, b, c)
+changesyntax(`O ')
+test(a, b, c)
+EOF
+
+cat <<\EOF >ok
+
+abc
+
+a b c
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.3.test b/tests/gentest/changesy.3.test
new file mode 100755
index 00000000..79030e78
--- /dev/null
+++ b/tests/gentest/changesy.3.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/changesy.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2158
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `$1$2$3')
+test(a, b, c)
+changesyntax(`O ')
+test(a, b, c)
+EOF
+
+cat <<\EOF >ok
+
+abc
+
+a b c
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.4.m4 b/tests/gentest/changesy.4.m4
new file mode 100755
index 00000000..9ee5b7d1
--- /dev/null
+++ b/tests/gentest/changesy.4.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/changesy.4.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2177
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`@', `TEST')
+@
+changesyntax(`A@')
+@
+EOF
+
+cat <<\EOF >ok
+
+@
+
+TEST
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.4.test b/tests/gentest/changesy.4.test
new file mode 100755
index 00000000..7df01f9e
--- /dev/null
+++ b/tests/gentest/changesy.4.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/changesy.4.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2177
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`@', `TEST')
+@
+changesyntax(`A@')
+@
+EOF
+
+cat <<\EOF >ok
+
+@
+
+TEST
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.5.m4 b/tests/gentest/changesy.5.m4
new file mode 100755
index 00000000..2035d2b9
--- /dev/null
+++ b/tests/gentest/changesy.5.m4
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# gentest/changesy.5.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2201
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `TEST')
+changesyntax(`L<', `R>')
+<test>
+`test>
+changequote(<[>, `]')
+<test>
+[test]
+EOF
+
+cat <<\EOF >ok
+
+
+test
+test
+
+<TEST>
+test
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.5.test b/tests/gentest/changesy.5.test
new file mode 100755
index 00000000..25640e31
--- /dev/null
+++ b/tests/gentest/changesy.5.test
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# gentest/changesy.5.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2201
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `TEST')
+changesyntax(`L<', `R>')
+<test>
+`test>
+changequote(<[>, `]')
+<test>
+[test]
+EOF
+
+cat <<\EOF >ok
+
+
+test
+test
+
+<TEST>
+test
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.6.m4 b/tests/gentest/changesy.6.m4
new file mode 100755
index 00000000..88cac7a4
--- /dev/null
+++ b/tests/gentest/changesy.6.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/changesy.6.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2223
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changesyntax(`({<', `)}>', `,;:', `O(,)')
+eval{2**4-1; 2 : 8>
+EOF
+
+cat <<\EOF >ok
+
+00001111
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.6.test b/tests/gentest/changesy.6.test
new file mode 100755
index 00000000..91cfc80a
--- /dev/null
+++ b/tests/gentest/changesy.6.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/changesy.6.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2223
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+changesyntax(`({<', `)}>', `,;:', `O(,)')
+eval{2**4-1; 2 : 8>
+EOF
+
+cat <<\EOF >ok
+
+00001111
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.7.m4 b/tests/gentest/changesy.7.m4
new file mode 100755
index 00000000..7a366945
--- /dev/null
+++ b/tests/gentest/changesy.7.m4
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# gentest/changesy.7.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2234
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `==$1==')
+changequote(`<<', `>>')
+changesyntax(<<L[>>, <<R]>>)
+test(<<testing]>>)
+test([testing>>])
+test([<<testing>>])
+EOF
+
+cat <<\EOF >ok
+
+
+
+==testing]==
+==testing>>==
+==<<testing>>==
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/changesy.7.test b/tests/gentest/changesy.7.test
new file mode 100755
index 00000000..014c152f
--- /dev/null
+++ b/tests/gentest/changesy.7.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# gentest/changesy.7.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2234
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`test', `==$1==')
+changequote(`<<', `>>')
+changesyntax(<<L[>>, <<R]>>)
+test(<<testing]>>)
+test([testing>>])
+test([<<testing>>])
+EOF
+
+cat <<\EOF >ok
+
+
+
+==testing]==
+==testing>>==
+==testing==
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/cleardiv.1.m4 b/tests/gentest/cleardiv.1.m4
new file mode 100755
index 00000000..36cba76a
--- /dev/null
+++ b/tests/gentest/cleardiv.1.m4
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/cleardiv.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2738
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert(-1)
+undivert
+EOF
+
+cat <<\EOF >ok
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/cleardiv.1.test b/tests/gentest/cleardiv.1.test
new file mode 100755
index 00000000..d9883e43
--- /dev/null
+++ b/tests/gentest/cleardiv.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/cleardiv.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2738
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert(-1)
+undivert
+EOF
+
+cat <<\EOF >ok
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/cleardiv.2.m4 b/tests/gentest/cleardiv.2.m4
new file mode 100755
index 00000000..e44667a9
--- /dev/null
+++ b/tests/gentest/cleardiv.2.m4
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# gentest/cleardiv.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2753
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`cleardivert',
+`pushdef(`_num', divnum)divert(-1)undivert($@)divert(_num)popdef(`_num')')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/cleardiv.2.test b/tests/gentest/cleardiv.2.test
new file mode 100755
index 00000000..7e78d8a4
--- /dev/null
+++ b/tests/gentest/cleardiv.2.test
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# gentest/cleardiv.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2753
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`cleardivert',
+`pushdef(`_num', divnum)divert(-1)undivert($@)divert(_num)popdef(`_num')')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/define.1.m4 b/tests/gentest/define.1.m4
new file mode 100755
index 00000000..17f30775
--- /dev/null
+++ b/tests/gentest/define.1.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/define.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 987
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello world.')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Hello world.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/define.1.test b/tests/gentest/define.1.test
new file mode 100755
index 00000000..fb364668
--- /dev/null
+++ b/tests/gentest/define.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/define.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 987
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello world.')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Hello world.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/define.2.m4 b/tests/gentest/define.2.m4
new file mode 100755
index 00000000..62e2ea0e
--- /dev/null
+++ b/tests/gentest/define.2.m4
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# gentest/define.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1007
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`array', `defn(format(``array[%d]'', `$1'))')
+define(`array_set', `define(format(``array[%d]'', `$1'), `$2')')
+array_set(4, `array element no. 4')
+array_set(17, `array element no. 17')
+array(4)
+array(eval(10+7))
+EOF
+
+cat <<\EOF >ok
+
+
+
+
+array element no. 4
+array element no. 17
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/define.2.test b/tests/gentest/define.2.test
new file mode 100755
index 00000000..028642c3
--- /dev/null
+++ b/tests/gentest/define.2.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# gentest/define.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1007
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`array', `defn(format(``array[%d]'', `$1'))')
+define(`array_set', `define(format(``array[%d]'', `$1'), `$2')')
+array_set(4, `array element no. 4')
+array_set(17, `array element no. 17')
+array(4)
+array(eval(10+7))
+EOF
+
+cat <<\EOF >ok
+
+
+
+
+array element no. 4
+array element no. 17
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/defn.1.m4 b/tests/gentest/defn.1.m4
new file mode 100755
index 00000000..c3f06939
--- /dev/null
+++ b/tests/gentest/defn.1.m4
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/defn.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1230
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`zap', defn(`undefine'))
+zap(`undefine')
+undefine(`zap')
+EOF
+
+cat <<\EOF >ok
+
+
+undefine(zap)
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/defn.1.test b/tests/gentest/defn.1.test
new file mode 100755
index 00000000..868dc07e
--- /dev/null
+++ b/tests/gentest/defn.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/defn.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1230
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`zap', defn(`undefine'))
+zap(`undefine')
+undefine(`zap')
+EOF
+
+cat <<\EOF >ok
+
+
+undefine(zap)
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/defn.2.m4 b/tests/gentest/defn.2.m4
new file mode 100755
index 00000000..0422980b
--- /dev/null
+++ b/tests/gentest/defn.2.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/defn.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1250
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`string', `The macro dnl is very useful
+')
+string
+defn(`string')
+EOF
+
+cat <<\EOF >ok
+
+The macro
+The macro dnl is very useful
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/defn.2.test b/tests/gentest/defn.2.test
new file mode 100755
index 00000000..df1925d4
--- /dev/null
+++ b/tests/gentest/defn.2.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/defn.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1250
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`string', `The macro dnl is very useful
+')
+string
+defn(`string')
+EOF
+
+cat <<\EOF >ok
+
+The macro
+The macro dnl is very useful
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/divert.1.m4 b/tests/gentest/divert.1.m4
new file mode 100755
index 00000000..acfc17d7
--- /dev/null
+++ b/tests/gentest/divert.1.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/divert.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2580
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted.
+divert
+This text is not diverted.
+EOF
+
+cat <<\EOF >ok
+
+This text is not diverted.
+
+This text is diverted.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/divert.1.test b/tests/gentest/divert.1.test
new file mode 100755
index 00000000..f675ba00
--- /dev/null
+++ b/tests/gentest/divert.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/divert.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2580
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted.
+divert
+This text is not diverted.
+EOF
+
+cat <<\EOF >ok
+
+This text is not diverted.
+
+This text is diverted.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/divert.2.m4 b/tests/gentest/divert.2.m4
new file mode 100755
index 00000000..13075ff7
--- /dev/null
+++ b/tests/gentest/divert.2.m4
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# gentest/divert.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2600
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(-1)
+define(`foo', `Macro `foo'.')
+define(`bar', `Macro `bar'.')
+divert
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/divert.2.test b/tests/gentest/divert.2.test
new file mode 100755
index 00000000..87f745d7
--- /dev/null
+++ b/tests/gentest/divert.2.test
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# gentest/divert.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2600
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(-1)
+define(`foo', `Macro `foo'.')
+define(`bar', `Macro `bar'.')
+divert
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/divnum.1.m4 b/tests/gentest/divnum.1.m4
new file mode 100755
index 00000000..4f49f918
--- /dev/null
+++ b/tests/gentest/divnum.1.m4
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# gentest/divnum.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2707
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+Initial divnum
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert
+EOF
+
+cat <<\EOF >ok
+Initial 0
+
+
+Diversion one: 1
+
+Diversion two: 2
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/divnum.1.test b/tests/gentest/divnum.1.test
new file mode 100755
index 00000000..b1866d7b
--- /dev/null
+++ b/tests/gentest/divnum.1.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# gentest/divnum.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2707
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+Initial divnum
+divert(1)
+Diversion one: divnum
+divert(2)
+Diversion two: divnum
+divert
+EOF
+
+cat <<\EOF >ok
+Initial 0
+
+
+Diversion one: 1
+
+Diversion two: 2
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/dnl.1.m4 b/tests/gentest/dnl.1.m4
new file mode 100755
index 00000000..5d0d7632
--- /dev/null
+++ b/tests/gentest/dnl.1.m4
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# gentest/dnl.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1857
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
+foo
+EOF
+
+cat <<\EOF >ok
+Macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/dnl.1.test b/tests/gentest/dnl.1.test
new file mode 100755
index 00000000..f27916b3
--- /dev/null
+++ b/tests/gentest/dnl.1.test
@@ -0,0 +1,20 @@
+#!/bin/sh
+
+# gentest/dnl.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1857
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Macro `foo'.')dnl A very simple macro, indeed.
+foo
+EOF
+
+cat <<\EOF >ok
+Macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/dumpdef.1.m4 b/tests/gentest/dumpdef.1.m4
new file mode 100755
index 00000000..bc31e1df
--- /dev/null
+++ b/tests/gentest/dumpdef.1.m4
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# gentest/dumpdef.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1660
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello world.')
+dumpdef(`foo')
+dumpdef(`define')
+EOF
+
+cat <<\EOF >ok
+
+
+
+EOF
+
+cat <<\EOF >okerr
+foo: `Hello world.'
+define: <define>
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/dumpdef.1.test b/tests/gentest/dumpdef.1.test
new file mode 100755
index 00000000..c2a00ded
--- /dev/null
+++ b/tests/gentest/dumpdef.1.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# gentest/dumpdef.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1660
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello world.')
+dumpdef(`foo')
+dumpdef(`define')
+EOF
+
+cat <<\EOF >ok
+
+
+
+EOF
+
+cat <<\EOF >okerr
+foo: `Hello world.'
+define: <define>
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/errprint.1.m4 b/tests/gentest/errprint.1.m4
new file mode 100755
index 00000000..107ef789
--- /dev/null
+++ b/tests/gentest/errprint.1.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/errprint.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3426
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+errprint(`Illegal arguments to forloop
+')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+Illegal arguments to forloop
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/errprint.1.test b/tests/gentest/errprint.1.test
new file mode 100755
index 00000000..b703dd30
--- /dev/null
+++ b/tests/gentest/errprint.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/errprint.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3426
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+errprint(`Illegal arguments to forloop
+')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+Illegal arguments to forloop
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/errprint.2.m4 b/tests/gentest/errprint.2.m4
new file mode 100755
index 00000000..5259782d
--- /dev/null
+++ b/tests/gentest/errprint.2.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/errprint.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3451
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+errprint(`m4:'__file__:__line__: `Input error
+')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+m4:in:1: Input error
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/errprint.2.test b/tests/gentest/errprint.2.test
new file mode 100755
index 00000000..4ca64136
--- /dev/null
+++ b/tests/gentest/errprint.2.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/errprint.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3451
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+errprint(`m4:'__file__:__line__: `Input error
+')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+m4:in:1: Input error
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/esyscmd.1.m4 b/tests/gentest/esyscmd.1.m4
new file mode 100755
index 00000000..856620e4
--- /dev/null
+++ b/tests/gentest/esyscmd.1.m4
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# gentest/esyscmd.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3315
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`vice', `esyscmd(grep Vice ../Makefile)')
+vice
+EOF
+
+cat <<\EOF >ok
+
+# Ty Coon, President of Vice
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/esyscmd.1.test b/tests/gentest/esyscmd.1.test
new file mode 100755
index 00000000..8d609baf
--- /dev/null
+++ b/tests/gentest/esyscmd.1.test
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# gentest/esyscmd.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3315
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`vice', `esyscmd(grep Vice ../Makefile)')
+vice
+EOF
+
+cat <<\EOF >ok
+
+# Ty Coon, President of Vice
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/eval.1.m4 b/tests/gentest/eval.1.m4
new file mode 100755
index 00000000..b3d38cc3
--- /dev/null
+++ b/tests/gentest/eval.1.m4
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# gentest/eval.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3199
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+eval(-3 * 5)
+eval(index(`Hello world', `llo') >= 0)
+define(`square', `eval(($1)**2)')
+square(9)
+square(square(5)+1)
+define(`foo', `666')
+eval(`foo'/6)
+eval(foo/6)
+EOF
+
+cat <<\EOF >ok
+-15
+1
+
+81
+676
+
+
+111
+EOF
+
+cat <<\EOF >okerr
+in:7: m4: Bad expression in eval: foo/6
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/eval.1.test b/tests/gentest/eval.1.test
new file mode 100755
index 00000000..56f916c2
--- /dev/null
+++ b/tests/gentest/eval.1.test
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+# gentest/eval.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3199
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+eval(-3 * 5)
+eval(index(`Hello world', `llo') >= 0)
+define(`square', `eval(($1)**2)')
+square(9)
+square(square(5)+1)
+define(`foo', `666')
+eval(`foo'/6)
+eval(foo/6)
+EOF
+
+cat <<\EOF >ok
+-15
+1
+
+81
+676
+
+
+111
+EOF
+
+cat <<\EOF >okerr
+in:7: m4: Bad expression in eval: foo/6
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/eval.2.m4 b/tests/gentest/eval.2.m4
new file mode 100755
index 00000000..bd394eb4
--- /dev/null
+++ b/tests/gentest/eval.2.m4
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/eval.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3230
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+eval(666, 10)
+eval(666, 11)
+eval(666, 6)
+eval(666, 6, 10)
+eval(-666, 6, 10)
+EOF
+
+cat <<\EOF >ok
+666
+556
+3030
+0000003030
+-000003030
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/eval.2.test b/tests/gentest/eval.2.test
new file mode 100755
index 00000000..abc9fbb6
--- /dev/null
+++ b/tests/gentest/eval.2.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/eval.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3230
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+eval(666, 10)
+eval(666, 11)
+eval(666, 6)
+eval(666, 6, 10)
+eval(-666, 6, 10)
+EOF
+
+cat <<\EOF >ok
+666
+556
+3030
+0000003030
+-000003030
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/format.1.m4 b/tests/gentest/format.1.m4
new file mode 100755
index 00000000..ddfdb7f6
--- /dev/null
+++ b/tests/gentest/format.1.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/format.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3035
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `The brown fox jumped over the lazy dog')
+format(`The string "%s" is %d characters long', foo, len(foo))
+EOF
+
+cat <<\EOF >ok
+
+The string "The brown fox jumped over the lazy dog" is 38 characters long
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/format.1.test b/tests/gentest/format.1.test
new file mode 100755
index 00000000..84c50d0a
--- /dev/null
+++ b/tests/gentest/format.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/format.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3035
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `The brown fox jumped over the lazy dog')
+format(`The string "%s" is %d characters long', foo, len(foo))
+EOF
+
+cat <<\EOF >ok
+
+The string "The brown fox jumped over the lazy dog" is 38 characters long
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/ifdef.1.m4 b/tests/gentest/ifdef.1.m4
new file mode 100755
index 00000000..721608c0
--- /dev/null
+++ b/tests/gentest/ifdef.1.m4
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/ifdef.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1440
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+define(`foo', `')
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+EOF
+
+cat <<\EOF >ok
+foo is not defined
+
+foo is defined
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/ifdef.1.test b/tests/gentest/ifdef.1.test
new file mode 100755
index 00000000..fb9951c7
--- /dev/null
+++ b/tests/gentest/ifdef.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/ifdef.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1440
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+define(`foo', `')
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+EOF
+
+cat <<\EOF >ok
+foo is not defined
+
+foo is defined
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/ifelse.1.m4 b/tests/gentest/ifelse.1.m4
new file mode 100755
index 00000000..0d6fbcf0
--- /dev/null
+++ b/tests/gentest/ifelse.1.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/ifelse.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1478
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifelse(`foo', `bar', `true')
+ifelse(`foo', `foo', `true')
+ifelse(`foo', `bar', `true', `false')
+ifelse(`foo', `foo', `true', `false')
+EOF
+
+cat <<\EOF >ok
+
+true
+false
+true
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/ifelse.1.test b/tests/gentest/ifelse.1.test
new file mode 100755
index 00000000..851c3005
--- /dev/null
+++ b/tests/gentest/ifelse.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/ifelse.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1478
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifelse(`foo', `bar', `true')
+ifelse(`foo', `foo', `true')
+ifelse(`foo', `bar', `true', `false')
+ifelse(`foo', `foo', `true', `false')
+EOF
+
+cat <<\EOF >ok
+
+true
+false
+true
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/ifelse.2.m4 b/tests/gentest/ifelse.2.m4
new file mode 100755
index 00000000..0cf36999
--- /dev/null
+++ b/tests/gentest/ifelse.2.m4
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# gentest/ifelse.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1497
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifelse(foo, bar, `third', gnu, gnats, `sixth', `seventh')
+EOF
+
+cat <<\EOF >ok
+seventh
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/ifelse.2.test b/tests/gentest/ifelse.2.test
new file mode 100755
index 00000000..2573945b
--- /dev/null
+++ b/tests/gentest/ifelse.2.test
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# gentest/ifelse.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1497
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifelse(foo, bar, `third', gnu, gnats, `sixth', `seventh')
+EOF
+
+cat <<\EOF >ok
+seventh
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/include.1.m4 b/tests/gentest/include.1.m4
new file mode 100755
index 00000000..e2912c84
--- /dev/null
+++ b/tests/gentest/include.1.m4
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# gentest/include.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2454
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(`no-such-file')
+sinclude(`no-such-file')
+EOF
+
+cat <<\EOF >ok
+
+
+EOF
+
+cat <<\EOF >okerr
+in:1: m4: Cannot open no-such-file: No such file or directory
+EOF
+
+M4PATH=$srcdir $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/include.1.test b/tests/gentest/include.1.test
new file mode 100755
index 00000000..55e186eb
--- /dev/null
+++ b/tests/gentest/include.1.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# gentest/include.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2454
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(`no-such-file')
+sinclude(`no-such-file')
+EOF
+
+cat <<\EOF >ok
+
+
+EOF
+
+cat <<\EOF >okerr
+in:1: m4: Cannot open no-such-file: No such file or directory
+EOF
+
+M4PATH=$srcdir $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/include.2.m4 b/tests/gentest/include.2.m4
new file mode 100755
index 00000000..15a2ea64
--- /dev/null
+++ b/tests/gentest/include.2.m4
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# gentest/include.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2474
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `FOO')
+include(`incl.m4')
+EOF
+
+cat <<\EOF >ok
+
+Include file start
+FOO
+Include file end
+
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/include.2.test b/tests/gentest/include.2.test
new file mode 100755
index 00000000..9257157c
--- /dev/null
+++ b/tests/gentest/include.2.test
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# gentest/include.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2474
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `FOO')
+include(`incl.m4')
+EOF
+
+cat <<\EOF >ok
+
+Include file start
+FOO
+Include file end
+
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/include.3.m4 b/tests/gentest/include.3.m4
new file mode 100755
index 00000000..0f286a81
--- /dev/null
+++ b/tests/gentest/include.3.m4
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# gentest/include.3.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2489
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`bar', include(`incl.m4'))
+This is `bar': >>>bar<<<
+EOF
+
+cat <<\EOF >ok
+
+This is bar: >>>Include file start
+foo
+Include file end
+<<<
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/include.3.test b/tests/gentest/include.3.test
new file mode 100755
index 00000000..19c911b2
--- /dev/null
+++ b/tests/gentest/include.3.test
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# gentest/include.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2489
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`bar', include(`incl.m4'))
+This is `bar': >>>bar<<<
+EOF
+
+cat <<\EOF >ok
+
+This is bar: >>>Include file start
+foo
+Include file end
+<<<
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/incr.1.m4 b/tests/gentest/incr.1.m4
new file mode 100755
index 00000000..16035bd3
--- /dev/null
+++ b/tests/gentest/incr.1.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/incr.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3105
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+incr(4)
+decr(7)
+EOF
+
+cat <<\EOF >ok
+5
+6
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/incr.1.test b/tests/gentest/incr.1.test
new file mode 100755
index 00000000..d9da8faa
--- /dev/null
+++ b/tests/gentest/incr.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/incr.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3105
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+incr(4)
+decr(7)
+EOF
+
+cat <<\EOF >ok
+5
+6
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/index.1.m4 b/tests/gentest/index.1.m4
new file mode 100755
index 00000000..28771378
--- /dev/null
+++ b/tests/gentest/index.1.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/index.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2821
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+index(`gnus, gnats, and armadillos', `nat')
+index(`gnus, gnats, and armadillos', `dag')
+EOF
+
+cat <<\EOF >ok
+7
+-1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/index.1.test b/tests/gentest/index.1.test
new file mode 100755
index 00000000..2226ab97
--- /dev/null
+++ b/tests/gentest/index.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/index.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2821
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+index(`gnus, gnats, and armadillos', `nat')
+index(`gnus, gnats, and armadillos', `dag')
+EOF
+
+cat <<\EOF >ok
+7
+-1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/indir.1.m4 b/tests/gentest/indir.1.m4
new file mode 100755
index 00000000..e1714a5b
--- /dev/null
+++ b/tests/gentest/indir.1.m4
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/indir.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1369
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`$$internal$macro', `Internal macro (name `$0')')
+$$internal$macro
+indir(`$$internal$macro')
+EOF
+
+cat <<\EOF >ok
+
+$$internal$macro
+Internal macro (name $$internal$macro)
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/indir.1.test b/tests/gentest/indir.1.test
new file mode 100755
index 00000000..ddb86909
--- /dev/null
+++ b/tests/gentest/indir.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/indir.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1369
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`$$internal$macro', `Internal macro (name `$0')')
+$$internal$macro
+indir(`$$internal$macro')
+EOF
+
+cat <<\EOF >ok
+
+$$internal$macro
+Internal macro (name $$internal$macro)
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/len.1.m4 b/tests/gentest/len.1.m4
new file mode 100755
index 00000000..1fa71023
--- /dev/null
+++ b/tests/gentest/len.1.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/len.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2795
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+len()
+len(`abcdef')
+EOF
+
+cat <<\EOF >ok
+0
+6
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/len.1.test b/tests/gentest/len.1.test
new file mode 100755
index 00000000..8799457a
--- /dev/null
+++ b/tests/gentest/len.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/len.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2795
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+len()
+len(`abcdef')
+EOF
+
+cat <<\EOF >ok
+0
+6
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/loops.1.m4 b/tests/gentest/loops.1.m4
new file mode 100755
index 00000000..791e2560
--- /dev/null
+++ b/tests/gentest/loops.1.m4
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/loops.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1534
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+shift
+shift(bar)
+shift(foo, bar, baz)
+EOF
+
+cat <<\EOF >ok
+
+
+bar,baz
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/loops.1.test b/tests/gentest/loops.1.test
new file mode 100755
index 00000000..bf2b5264
--- /dev/null
+++ b/tests/gentest/loops.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/loops.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1534
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+shift
+shift(bar)
+shift(foo, bar, baz)
+EOF
+
+cat <<\EOF >ok
+
+
+bar,baz
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/loops.2.m4 b/tests/gentest/loops.2.m4
new file mode 100755
index 00000000..88c305f5
--- /dev/null
+++ b/tests/gentest/loops.2.m4
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# gentest/loops.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1546
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`reverse', `ifelse($#, 0, , $#, 1, ``$1'',
+ `reverse(shift($@)), `$1'')')
+reverse
+reverse(foo)
+reverse(foo, bar, gnats, and gnus)
+EOF
+
+cat <<\EOF >ok
+
+
+foo
+and gnus, gnats, bar, foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/loops.2.test b/tests/gentest/loops.2.test
new file mode 100755
index 00000000..5e38e47e
--- /dev/null
+++ b/tests/gentest/loops.2.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# gentest/loops.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1546
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`reverse', `ifelse($#, 0, , $#, 1, ``$1'',
+ `reverse(shift($@)), `$1'')')
+reverse
+reverse(foo)
+reverse(foo, bar, gnats, and gnus)
+EOF
+
+cat <<\EOF >ok
+
+
+foo
+and gnus, gnats, bar, foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/m4exit.1.m4 b/tests/gentest/m4exit.1.m4
new file mode 100755
index 00000000..7ba446b1
--- /dev/null
+++ b/tests/gentest/m4exit.1.m4
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# gentest/m4exit.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3474
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`fatal_error', `errprint(`m4: '__file__: __line__`: fatal error: $*
+')m4exit(1)')
+fatal_error(`This is a BAD one, buster')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+m4: in: 3: fatal error: This is a BAD one, buster
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/m4exit.1.test b/tests/gentest/m4exit.1.test
new file mode 100755
index 00000000..43a4b004
--- /dev/null
+++ b/tests/gentest/m4exit.1.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# gentest/m4exit.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3474
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`fatal_error', `errprint(`m4: '__file__: __line__`: fatal error: $*
+')m4exit(1)')
+fatal_error(`This is a BAD one, buster')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+m4: in: 3: fatal error: This is a BAD one, buster
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/m4wrap.1.m4 b/tests/gentest/m4wrap.1.m4
new file mode 100755
index 00000000..a8315641
--- /dev/null
+++ b/tests/gentest/m4wrap.1.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/m4wrap.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2395
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`cleanup', `This is the `cleanup' actions.
+')
+m4wrap(`cleanup')
+This is the first and last normal input line.
+EOF
+
+cat <<\EOF >ok
+
+
+This is the first and last normal input line.
+This is the cleanup actions.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/m4wrap.1.test b/tests/gentest/m4wrap.1.test
new file mode 100755
index 00000000..c6327beb
--- /dev/null
+++ b/tests/gentest/m4wrap.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/m4wrap.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2395
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`cleanup', `This is the `cleanup' actions.
+')
+m4wrap(`cleanup')
+This is the first and last normal input line.
+EOF
+
+cat <<\EOF >ok
+
+
+This is the first and last normal input line.
+This is the cleanup actions.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/patsubst.1.m4 b/tests/gentest/patsubst.1.m4
new file mode 100755
index 00000000..1b39ecba
--- /dev/null
+++ b/tests/gentest/patsubst.1.m4
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/patsubst.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2983
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+patsubst(`GNUs not Unix', `^', `OBS: ')
+patsubst(`GNUs not Unix', `\<', `OBS: ')
+patsubst(`GNUs not Unix', `\w*', `(\&)')
+patsubst(`GNUs not Unix', `\w+', `(\&)')
+patsubst(`GNUs not Unix', `[A-Z][a-z]+')
+EOF
+
+cat <<\EOF >ok
+OBS: GNUs not Unix
+OBS: GNUs OBS: not OBS: Unix
+(GNUs)() (not)() (Unix)
+(GNUs) (not) (Unix)
+GN not
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/patsubst.1.test b/tests/gentest/patsubst.1.test
new file mode 100755
index 00000000..6213ef87
--- /dev/null
+++ b/tests/gentest/patsubst.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/patsubst.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2983
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+patsubst(`GNUs not Unix', `^', `OBS: ')
+patsubst(`GNUs not Unix', `\<', `OBS: ')
+patsubst(`GNUs not Unix', `\w*', `(\&)')
+patsubst(`GNUs not Unix', `\w+', `(\&)')
+patsubst(`GNUs not Unix', `[A-Z][a-z]+')
+EOF
+
+cat <<\EOF >ok
+OBS: GNUs not Unix
+OBS: GNUs OBS: not OBS: Unix
+(GNUs)() (not)() (Unix)
+(GNUs) (not) (Unix)
+GN not
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/patsubst.2.m4 b/tests/gentest/patsubst.2.m4
new file mode 100755
index 00000000..f8644359
--- /dev/null
+++ b/tests/gentest/patsubst.2.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/patsubst.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3000
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
+define(`downcase', `translit(`$*', `A-Z', `a-z')')dnl
+define(`capitalize1',
+ `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')dnl
+define(`capitalize',
+ `patsubst(`$1', `\w+', `capitalize1(`\&')')')dnl
+capitalize(`GNUs not Unix')
+EOF
+
+cat <<\EOF >ok
+Gnus Not Unix
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/patsubst.2.test b/tests/gentest/patsubst.2.test
new file mode 100755
index 00000000..b31e4d80
--- /dev/null
+++ b/tests/gentest/patsubst.2.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/patsubst.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3000
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
+define(`downcase', `translit(`$*', `A-Z', `a-z')')dnl
+define(`capitalize1',
+ `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')dnl
+define(`capitalize',
+ `patsubst(`$1', `\w+', `capitalize1(`\&')')')dnl
+capitalize(`GNUs not Unix')
+EOF
+
+cat <<\EOF >ok
+Gnus Not Unix
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pseudoar.1.m4 b/tests/gentest/pseudoar.1.m4
new file mode 100755
index 00000000..29721fa1
--- /dev/null
+++ b/tests/gentest/pseudoar.1.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/pseudoar.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1100
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`nargs', `$#')
+nargs
+nargs()
+nargs(arg1, arg2, arg3)
+EOF
+
+cat <<\EOF >ok
+
+0
+1
+3
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pseudoar.1.test b/tests/gentest/pseudoar.1.test
new file mode 100755
index 00000000..50260e65
--- /dev/null
+++ b/tests/gentest/pseudoar.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/pseudoar.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1100
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`nargs', `$#')
+nargs
+nargs()
+nargs(arg1, arg2, arg3)
+EOF
+
+cat <<\EOF >ok
+
+0
+1
+3
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pseudoar.2.m4 b/tests/gentest/pseudoar.2.m4
new file mode 100755
index 00000000..47231cf4
--- /dev/null
+++ b/tests/gentest/pseudoar.2.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/pseudoar.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1114
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo', `$*')
+echo(arg1, arg2, arg3 , arg4)
+EOF
+
+cat <<\EOF >ok
+
+arg1,arg2,arg3 ,arg4
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pseudoar.2.test b/tests/gentest/pseudoar.2.test
new file mode 100755
index 00000000..ca939b81
--- /dev/null
+++ b/tests/gentest/pseudoar.2.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/pseudoar.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1114
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo', `$*')
+echo(arg1, arg2, arg3 , arg4)
+EOF
+
+cat <<\EOF >ok
+
+arg1,arg2,arg3 ,arg4
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pseudoar.3.m4 b/tests/gentest/pseudoar.3.m4
new file mode 100755
index 00000000..997641f3
--- /dev/null
+++ b/tests/gentest/pseudoar.3.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/pseudoar.3.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1125
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo', `$@')
+echo(arg1, arg2, arg3 , arg4)
+EOF
+
+cat <<\EOF >ok
+
+arg1,arg2,arg3 ,arg4
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pseudoar.3.test b/tests/gentest/pseudoar.3.test
new file mode 100755
index 00000000..b29b17fc
--- /dev/null
+++ b/tests/gentest/pseudoar.3.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/pseudoar.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1125
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo', `$@')
+echo(arg1, arg2, arg3 , arg4)
+EOF
+
+cat <<\EOF >ok
+
+arg1,arg2,arg3 ,arg4
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pseudoar.4.m4 b/tests/gentest/pseudoar.4.m4
new file mode 100755
index 00000000..68b7b6ef
--- /dev/null
+++ b/tests/gentest/pseudoar.4.m4
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/pseudoar.4.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1135
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo1', `$*')
+define(`echo2', `$@')
+define(`foo', `This is macro `foo'.')
+echo1(foo)
+echo2(foo)
+EOF
+
+cat <<\EOF >ok
+
+
+
+This is macro This is macro foo..
+This is macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pseudoar.4.test b/tests/gentest/pseudoar.4.test
new file mode 100755
index 00000000..81616f26
--- /dev/null
+++ b/tests/gentest/pseudoar.4.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/pseudoar.4.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1135
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo1', `$*')
+define(`echo2', `$@')
+define(`foo', `This is macro `foo'.')
+echo1(foo)
+echo2(foo)
+EOF
+
+cat <<\EOF >ok
+
+
+
+This is macro This is macro foo..
+This is macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pseudoar.5.m4 b/tests/gentest/pseudoar.5.m4
new file mode 100755
index 00000000..8c01d6f7
--- /dev/null
+++ b/tests/gentest/pseudoar.5.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/pseudoar.5.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1155
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `$$$ hello $$$')
+foo
+EOF
+
+cat <<\EOF >ok
+
+$$$ hello $$$
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pseudoar.5.test b/tests/gentest/pseudoar.5.test
new file mode 100755
index 00000000..e90de1fa
--- /dev/null
+++ b/tests/gentest/pseudoar.5.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/pseudoar.5.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1155
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `$$$ hello $$$')
+foo
+EOF
+
+cat <<\EOF >ok
+
+$$$ hello $$$
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pushdef.1.m4 b/tests/gentest/pushdef.1.m4
new file mode 100755
index 00000000..ac11f585
--- /dev/null
+++ b/tests/gentest/pushdef.1.m4
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# gentest/pushdef.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1294
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Expansion one.')
+foo
+pushdef(`foo', `Expansion two.')
+foo
+popdef(`foo')
+foo
+popdef(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Expansion one.
+
+Expansion two.
+
+Expansion one.
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pushdef.1.test b/tests/gentest/pushdef.1.test
new file mode 100755
index 00000000..d934f422
--- /dev/null
+++ b/tests/gentest/pushdef.1.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# gentest/pushdef.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1294
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Expansion one.')
+foo
+pushdef(`foo', `Expansion two.')
+foo
+popdef(`foo')
+foo
+popdef(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Expansion one.
+
+Expansion two.
+
+Expansion one.
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pushdef.2.m4 b/tests/gentest/pushdef.2.m4
new file mode 100755
index 00000000..07eb0c79
--- /dev/null
+++ b/tests/gentest/pushdef.2.m4
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# gentest/pushdef.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1318
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Expansion one.')
+foo
+pushdef(`foo', `Expansion two.')
+foo
+define(`foo', `Second expansion two.')
+foo
+undefine(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Expansion one.
+
+Expansion two.
+
+Second expansion two.
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/pushdef.2.test b/tests/gentest/pushdef.2.test
new file mode 100755
index 00000000..7d43770f
--- /dev/null
+++ b/tests/gentest/pushdef.2.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# gentest/pushdef.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1318
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Expansion one.')
+foo
+pushdef(`foo', `Expansion two.')
+foo
+define(`foo', `Second expansion two.')
+foo
+undefine(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Expansion one.
+
+Expansion two.
+
+Second expansion two.
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/regexp.1.m4 b/tests/gentest/regexp.1.m4
new file mode 100755
index 00000000..d27cf8e7
--- /dev/null
+++ b/tests/gentest/regexp.1.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/regexp.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2853
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+regexp(`GNUs not Unix', `\<[a-z]\w+')
+regexp(`GNUs not Unix', `\<Q\w*')
+EOF
+
+cat <<\EOF >ok
+5
+-1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/regexp.1.test b/tests/gentest/regexp.1.test
new file mode 100755
index 00000000..3427751e
--- /dev/null
+++ b/tests/gentest/regexp.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/regexp.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2853
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+regexp(`GNUs not Unix', `\<[a-z]\w+')
+regexp(`GNUs not Unix', `\<Q\w*')
+EOF
+
+cat <<\EOF >ok
+5
+-1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/regexp.2.m4 b/tests/gentest/regexp.2.m4
new file mode 100755
index 00000000..a75bdc6f
--- /dev/null
+++ b/tests/gentest/regexp.2.m4
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# gentest/regexp.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2865
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
+EOF
+
+cat <<\EOF >ok
+*** Unix *** nix ***
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/regexp.2.test b/tests/gentest/regexp.2.test
new file mode 100755
index 00000000..c3ff8894
--- /dev/null
+++ b/tests/gentest/regexp.2.test
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# gentest/regexp.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2865
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
+EOF
+
+cat <<\EOF >ok
+*** Unix *** nix ***
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/substr.1.m4 b/tests/gentest/substr.1.m4
new file mode 100755
index 00000000..6354c598
--- /dev/null
+++ b/tests/gentest/substr.1.m4
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/substr.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2891
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+substr(`gnus, gnats, and armadillos', 6)
+substr(`gnus, gnats, and armadillos', 6, 5)
+EOF
+
+cat <<\EOF >ok
+gnats, and armadillos
+gnats
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/substr.1.test b/tests/gentest/substr.1.test
new file mode 100755
index 00000000..964ab0eb
--- /dev/null
+++ b/tests/gentest/substr.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# gentest/substr.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2891
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+substr(`gnus, gnats, and armadillos', 6)
+substr(`gnus, gnats, and armadillos', 6, 5)
+EOF
+
+cat <<\EOF >ok
+gnats, and armadillos
+gnats
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/sysval.1.m4 b/tests/gentest/sysval.1.m4
new file mode 100755
index 00000000..f1ffeb7b
--- /dev/null
+++ b/tests/gentest/sysval.1.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/sysval.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3346
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+syscmd(`false')
+ifelse(sysval, 0, zero, non-zero)
+syscmd(`true')
+sysval
+EOF
+
+cat <<\EOF >ok
+
+non-zero
+
+0
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/sysval.1.test b/tests/gentest/sysval.1.test
new file mode 100755
index 00000000..6e101fd7
--- /dev/null
+++ b/tests/gentest/sysval.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/sysval.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3346
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+syscmd(`false')
+ifelse(sysval, 0, zero, non-zero)
+syscmd(`true')
+sysval
+EOF
+
+cat <<\EOF >ok
+
+non-zero
+
+0
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/trace.1.m4 b/tests/gentest/trace.1.m4
new file mode 100755
index 00000000..eae2a55e
--- /dev/null
+++ b/tests/gentest/trace.1.m4
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# gentest/trace.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1705
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello World.')
+define(`echo', `$@')
+traceon(`foo', `echo')
+foo
+echo(gnus, and gnats)
+EOF
+
+cat <<\EOF >ok
+
+
+
+Hello World.
+gnus,and gnats
+EOF
+
+cat <<\EOF >okerr
+m4trace: -1- foo -> `Hello World.'
+m4trace: -1- echo(`gnus', `and gnats') -> ``gnus',`and gnats''
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/trace.1.test b/tests/gentest/trace.1.test
new file mode 100755
index 00000000..ef1cb312
--- /dev/null
+++ b/tests/gentest/trace.1.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# gentest/trace.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1705
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello World.')
+define(`echo', `$@')
+traceon(`foo', `echo')
+foo
+echo(gnus, and gnats)
+EOF
+
+cat <<\EOF >ok
+
+
+
+Hello World.
+gnus,and gnats
+EOF
+
+cat <<\EOF >okerr
+m4trace: -1- foo -> `Hello World.'
+m4trace: -1- echo(`gnus', `and gnats') -> ``gnus',`and gnats''
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/gentest/translit.1.m4 b/tests/gentest/translit.1.m4
new file mode 100755
index 00000000..4ac2bd7a
--- /dev/null
+++ b/tests/gentest/translit.1.m4
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/translit.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2932
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+translit(`GNUs not Unix', `A-Z')
+translit(`GNUs not Unix', `a-z', `A-Z')
+translit(`GNUs not Unix', `A-Z', `z-a')
+EOF
+
+cat <<\EOF >ok
+s not nix
+GNUS NOT UNIX
+tmfs not fnix
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/translit.1.test b/tests/gentest/translit.1.test
new file mode 100755
index 00000000..e650bbdf
--- /dev/null
+++ b/tests/gentest/translit.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# gentest/translit.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2932
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+translit(`GNUs not Unix', `A-Z')
+translit(`GNUs not Unix', `a-z', `A-Z')
+translit(`GNUs not Unix', `A-Z', `z-a')
+EOF
+
+cat <<\EOF >ok
+s not nix
+GNUS NOT UNIX
+tmfs not fnix
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/undefine.1.m4 b/tests/gentest/undefine.1.m4
new file mode 100755
index 00000000..cd7db2ad
--- /dev/null
+++ b/tests/gentest/undefine.1.m4
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/undefine.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1186
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+foo
+define(`foo', `expansion text')
+foo
+undefine(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+foo
+
+expansion text
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/undefine.1.test b/tests/gentest/undefine.1.test
new file mode 100755
index 00000000..d196e530
--- /dev/null
+++ b/tests/gentest/undefine.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/undefine.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1186
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+foo
+define(`foo', `expansion text')
+foo
+undefine(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+foo
+
+expansion text
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/undivert.1.m4 b/tests/gentest/undivert.1.m4
new file mode 100755
index 00000000..db869a32
--- /dev/null
+++ b/tests/gentest/undivert.1.m4
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/undivert.1.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2631
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted.
+divert
+This text is not diverted.
+undivert(1)
+EOF
+
+cat <<\EOF >ok
+
+This text is not diverted.
+
+This text is diverted.
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/undivert.1.test b/tests/gentest/undivert.1.test
new file mode 100755
index 00000000..3d04dc8b
--- /dev/null
+++ b/tests/gentest/undivert.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# gentest/undivert.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2631
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted.
+divert
+This text is not diverted.
+undivert(1)
+EOF
+
+cat <<\EOF >ok
+
+This text is not diverted.
+
+This text is diverted.
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/undivert.2.m4 b/tests/gentest/undivert.2.m4
new file mode 100755
index 00000000..0663e0dd
--- /dev/null
+++ b/tests/gentest/undivert.2.m4
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# gentest/undivert.2.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2655
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted first.
+divert(0)undivert(1)dnl
+undivert(1)
+divert(1)
+This text is also diverted but not appended.
+divert(0)undivert(1)dnl
+EOF
+
+cat <<\EOF >ok
+
+This text is diverted first.
+
+
+This text is also diverted but not appended.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/undivert.2.test b/tests/gentest/undivert.2.test
new file mode 100755
index 00000000..6a84ecc4
--- /dev/null
+++ b/tests/gentest/undivert.2.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# gentest/undivert.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2655
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted first.
+divert(0)undivert(1)dnl
+undivert(1)
+divert(1)
+This text is also diverted but not appended.
+divert(0)undivert(1)dnl
+EOF
+
+cat <<\EOF >ok
+
+This text is diverted first.
+
+
+This text is also diverted but not appended.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/undivert.3.m4 b/tests/gentest/undivert.3.m4
new file mode 100755
index 00000000..d0b92cae
--- /dev/null
+++ b/tests/gentest/undivert.3.m4
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/undivert.3.m4 is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2681
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`bar', `BAR')
+undivert(`foo')
+include(`foo')
+EOF
+
+cat <<\EOF >ok
+
+bar
+
+BAR
+
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/gentest/undivert.3.test b/tests/gentest/undivert.3.test
new file mode 100755
index 00000000..f6d22551
--- /dev/null
+++ b/tests/gentest/undivert.3.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# gentest/undivert.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2681
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`bar', `BAR')
+undivert(`foo')
+include(`foo')
+EOF
+
+cat <<\EOF >ok
+
+bar
+
+BAR
+
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/get-them b/tests/get-them
new file mode 100755
index 00000000..ca42991a
--- /dev/null
+++ b/tests/get-them
@@ -0,0 +1,112 @@
+#!/bin/sh
+# Extract all examples from the manual source.
+# Copyright (C) 1992 Free Software Foundation, Inc.
+
+# This script is for use with GNU awk.
+
+FILE=${1-/dev/null}
+
+${AWK-gawk} '
+
+BEGIN {
+ node = "";
+ seq = -1;
+ count = 0;
+ file = "NONE";
+}
+
+/^@node / {
+ if (seq > 0)
+ printf(" -- %d test%s", seq, seq == 1 ? "" : "s");
+ if (seq >= 0)
+ printf("\n");
+
+ split($0, tmp, ",");
+ Node = substr(tmp[1], 7);
+ node = tolower(Node);
+ gsub(" ", "", node);
+ if (length(node) > 8)
+ printf("Node: %s - truncated", node);
+ else
+ printf("Node: %s ", node);
+ node = substr(node, 1, 8);
+ seq = 0;
+}
+
+/^@comment ignore$/ {
+ getline;
+ next;
+}
+
+/^@example$/, /^@end example$/ {
+ if (seq < 0)
+ next;
+ if ($0 ~ /^@example$/) {
+ if (count > 0)
+ close (file);
+ seq++;
+ count++;
+ o = 0;
+ e = 0;
+ error_flag = 0;
+ i = 0;
+ include_flag = 0;
+ file = sprintf("%s.%d.test", node, seq);
+ printf ("#!/bin/sh\n\n") > file;
+ printf ("# %s is part of the GNU m4 testsuite\n", file) >> file;
+ printf ("# generated from example in %s line %d\n\n", FILENAME, NR) >>file;
+ printf (". ${srcdir}/defs\n") >> file;
+ next;
+ }
+ if ($0 ~ /^@end example$/) {
+ printthem(input, i, "in");
+ printthem(output, o, "ok");
+ printthem(error, e, "okerr");
+ printf ("\n") >> file;
+ if (include_flag == 1) printf ("M4PATH=$srcdir ") >> file;
+ printf ("$M4 -d in >out") >> file;
+ if (error_flag == 1) printf (" 2>err") >> file;
+ if (error_flag == 1) printf ("\nsed -e \"s, ../../src/m4:, m4:,\" err >sederr && mv sederr err") >> file;
+ printf ("\n\n$CMP -s out ok") >> file;
+ if (error_flag == 1) printf (" && $CMP -s err okerr") >> file;
+ printf ("\n\n") >> file;
+ next;
+ }
+ if ($0 ~ /^\^D$/)
+ next;
+ if ($0 ~ /^@result\{\}/) {
+ gsub(/^@result\{\}/, "", $0);
+ output[o++] = $0;
+ }
+ else if ($0 ~ /^@error\{\}/) {
+ gsub(/^@error\{\}/, "", $0);
+ error[e++] = $0;
+ error_flag = 1;
+ }
+ else {
+ input[i++] = $0;
+ if ($0 ~ /s*include\(/) include_flag = 1;
+ }
+}
+
+END {
+ printf("\n");
+}
+
+function printthem(thearray, thecounter, thefile) {
+ if ((thecounter>0) || (thefile=="ok")) {
+ printf ("\ncat <<\\EOF >%s\n", thefile) >> file;
+ for (j=0; j<thecounter; j++) {
+ gsub("@{", "{", thearray[j]);
+ gsub("@}", "}", thearray[j]);
+ gsub("@@", "@", thearray[j]);
+ gsub("@comment.*", "", thearray[j]);
+ printf ("%s\n", thearray[j]) >> file;
+ }
+ printf ("EOF\n") >> file;
+ }
+}
+
+' $FILE >/dev/null
+
+chmod +x *.[0-9].test
diff --git a/tests/ifdef.1.test b/tests/ifdef.1.test
new file mode 100755
index 00000000..9cb0935b
--- /dev/null
+++ b/tests/ifdef.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# ifdef.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1441
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+define(`foo', `')
+ifdef(`foo', ``foo' is defined', ``foo' is not defined')
+EOF
+
+cat <<\EOF >ok
+foo is not defined
+
+foo is defined
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/ifelse.1.test b/tests/ifelse.1.test
new file mode 100755
index 00000000..7942a0c2
--- /dev/null
+++ b/tests/ifelse.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# ifelse.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1479
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifelse(`foo', `bar', `true')
+ifelse(`foo', `foo', `true')
+ifelse(`foo', `bar', `true', `false')
+ifelse(`foo', `foo', `true', `false')
+EOF
+
+cat <<\EOF >ok
+
+true
+false
+true
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/ifelse.2.test b/tests/ifelse.2.test
new file mode 100755
index 00000000..d2049f5d
--- /dev/null
+++ b/tests/ifelse.2.test
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# ifelse.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1498
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+ifelse(foo, bar, `third', gnu, gnats, `sixth', `seventh')
+EOF
+
+cat <<\EOF >ok
+seventh
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/incl.m4 b/tests/incl.m4
new file mode 100644
index 00000000..ab9572eb
--- /dev/null
+++ b/tests/incl.m4
@@ -0,0 +1,3 @@
+Include file start
+foo
+Include file end
diff --git a/tests/include.1.test b/tests/include.1.test
new file mode 100755
index 00000000..535a1292
--- /dev/null
+++ b/tests/include.1.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# include.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2455
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+include(`no-such-file')
+sinclude(`no-such-file')
+EOF
+
+cat <<\EOF >ok
+
+
+EOF
+
+cat <<\EOF >okerr
+in:1: m4: Cannot open no-such-file: No such file or directory
+EOF
+
+M4PATH=$srcdir $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/include.2.test b/tests/include.2.test
new file mode 100755
index 00000000..1e0c428f
--- /dev/null
+++ b/tests/include.2.test
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# include.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2475
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `FOO')
+include(`incl.m4')
+EOF
+
+cat <<\EOF >ok
+
+Include file start
+FOO
+Include file end
+
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/include.3.test b/tests/include.3.test
new file mode 100755
index 00000000..edf228d0
--- /dev/null
+++ b/tests/include.3.test
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+# include.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2490
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`bar', include(`incl.m4'))
+This is `bar': >>>bar<<<
+EOF
+
+cat <<\EOF >ok
+
+This is bar: >>>Include file start
+foo
+Include file end
+<<<
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/incr.1.test b/tests/incr.1.test
new file mode 100755
index 00000000..d20be4df
--- /dev/null
+++ b/tests/incr.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# incr.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3106
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+incr(4)
+decr(7)
+EOF
+
+cat <<\EOF >ok
+5
+6
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/index.1.test b/tests/index.1.test
new file mode 100755
index 00000000..1cee65fa
--- /dev/null
+++ b/tests/index.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# index.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2822
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+index(`gnus, gnats, and armadillos', `nat')
+index(`gnus, gnats, and armadillos', `dag')
+EOF
+
+cat <<\EOF >ok
+7
+-1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/indir.1.test b/tests/indir.1.test
new file mode 100755
index 00000000..3cbc0511
--- /dev/null
+++ b/tests/indir.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# indir.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1370
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`$$internal$macro', `Internal macro (name `$0')')
+$$internal$macro
+indir(`$$internal$macro')
+EOF
+
+cat <<\EOF >ok
+
+$$internal$macro
+Internal macro (name $$internal$macro)
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/len.1.test b/tests/len.1.test
new file mode 100755
index 00000000..a60bb1b0
--- /dev/null
+++ b/tests/len.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# len.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2796
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+len()
+len(`abcdef')
+EOF
+
+cat <<\EOF >ok
+0
+6
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/loops.1.test b/tests/loops.1.test
new file mode 100755
index 00000000..3a872fc9
--- /dev/null
+++ b/tests/loops.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# loops.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1535
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+shift
+shift(bar)
+shift(foo, bar, baz)
+EOF
+
+cat <<\EOF >ok
+
+
+bar,baz
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/loops.2.test b/tests/loops.2.test
new file mode 100755
index 00000000..35e4db17
--- /dev/null
+++ b/tests/loops.2.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# loops.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1547
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`reverse', `ifelse($#, 0, , $#, 1, ``$1'',
+ `reverse(shift($@)), `$1'')')
+reverse
+reverse(foo)
+reverse(foo, bar, gnats, and gnus)
+EOF
+
+cat <<\EOF >ok
+
+
+foo
+and gnus, gnats, bar, foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/m4exit.1.test b/tests/m4exit.1.test
new file mode 100755
index 00000000..c721d434
--- /dev/null
+++ b/tests/m4exit.1.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+# m4exit.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3475
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`fatal_error', `errprint(`m4: '__file__: __line__`: fatal error: $*
+')m4exit(1)')
+fatal_error(`This is a BAD one, buster')
+EOF
+
+cat <<\EOF >ok
+
+EOF
+
+cat <<\EOF >okerr
+m4: in: 3: fatal error: This is a BAD one, buster
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/m4wrap.1.test b/tests/m4wrap.1.test
new file mode 100755
index 00000000..1a27ac3c
--- /dev/null
+++ b/tests/m4wrap.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# m4wrap.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2396
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`cleanup', `This is the `cleanup' actions.
+')
+m4wrap(`cleanup')
+This is the first and last normal input line.
+EOF
+
+cat <<\EOF >ok
+
+
+This is the first and last normal input line.
+This is the cleanup actions.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/mkconfig.sh b/tests/mkconfig.sh
new file mode 100644
index 00000000..f2ebc782
--- /dev/null
+++ b/tests/mkconfig.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+env >/tmp/env
+sed -n -e '/^#define \(\(WITH\|ENABLE\)_.*\) \(.*\)$/s//define(\1, \3)dnl/p' config.h > tests/config.m4
+sed -n -e '/^#define \(\(WITH\|ENABLE\)_.*\) \(.*\)$/s//\1=\3/p' config.h > tests/config.sh
diff --git a/tests/other-tests/discard-comments.m4 b/tests/other-tests/discard-comments.m4
new file mode 100644
index 00000000..95aebd27
--- /dev/null
+++ b/tests/other-tests/discard-comments.m4
@@ -0,0 +1,7 @@
+This is not a comment # but this is.
+# This line should dissappear completely.
+This should not disappear.
+changecom(`<!--', `-->')
+html <!--
+comment
+ --> ends.
diff --git a/tests/other-tests/discard-comments.test b/tests/other-tests/discard-comments.test
new file mode 100755
index 00000000..2f6a4599
--- /dev/null
+++ b/tests/other-tests/discard-comments.test
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# discard-comments.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/other-tests/discard-comments.m4 >in
+
+cat <<\EOF >ok
+This is not a comment This should not disappear.
+
+html ends.
+EOF
+
+M4PATH=$srcdir:$srcdir/other-tests $M4 -c -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/tests/other-tests/gmp.m4 b/tests/other-tests/gmp.m4
new file mode 100644
index 00000000..b916ff69
--- /dev/null
+++ b/tests/other-tests/gmp.m4
@@ -0,0 +1,10 @@
+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 = eval(2**x)
+')
diff --git a/tests/other-tests/gmp.test b/tests/other-tests/gmp.test
new file mode 100755
index 00000000..9382832a
--- /dev/null
+++ b/tests/other-tests/gmp.test
@@ -0,0 +1,120 @@
+#!/bin/sh
+
+# gmp.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+. ${srcdir}/config.sh
+
+# cannot perform test without --with-gmp
+test -z "$WITH_GMP" && exit 77
+
+cat ${srcdir}/other-tests/gmp.m4 >in
+
+cat <<\EOF >ok
+
+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
+
+EOF
+
+M4PATH=$srcdir:$srcdir/../tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/tests/other-tests/import-environment.m4 b/tests/other-tests/import-environment.m4
new file mode 100644
index 00000000..f537df66
--- /dev/null
+++ b/tests/other-tests/import-environment.m4
@@ -0,0 +1,4 @@
+`TEST'=TEST
+`LANGUAGE'=LANGUAGE
+`ZAPPED'=ZAPPED
+`OVERRIDE'=OVERRIDE
diff --git a/tests/other-tests/import-environment.test b/tests/other-tests/import-environment.test
new file mode 100755
index 00000000..195434b5
--- /dev/null
+++ b/tests/other-tests/import-environment.test
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+# import-environment.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+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
+
+cat ${srcdir}/other-tests/import-environment.m4 >in
+
+cat <<\EOF >ok
+TEST=This is an environment variable
+LANGUAGE=C
+ZAPPED=ZAPPED
+OVERRIDE=It is changed.
+EOF
+
+M4PATH=$srcdir:$srcdir/other-tests \
+$M4 --import-environment -UZAPPED -DOVERRIDE='It is changed.' -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/tests/other-tests/iso8859.m4 b/tests/other-tests/iso8859.m4
new file mode 100644
index 00000000..4ac1d196
--- /dev/null
+++ b/tests/other-tests/iso8859.m4
Binary files differ
diff --git a/tests/other-tests/iso8859.test b/tests/other-tests/iso8859.test
new file mode 100755
index 00000000..f77dbb27
--- /dev/null
+++ b/tests/other-tests/iso8859.test
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+# iso8859.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/other-tests/iso8859.m4 > in
+
+cat <<\EOF >ok
+# Texting quotes
+DEFINE
+CHANGEQUOTE(«,»)
+0 TEST # TEST
+1 test # test
+2 «test» # «test»
+3 ««test»» # ««test»»
+CHANGEQUOTE(«««,»»»)
+0 TEST # TEST
+1 «TEST» # «TEST»
+2 ««TEST»» # ««TEST»»
+3 test # test
+# Test use of all iso8859 characters except NUL ` '
+Length of string is: 253
+Comparing strings: MATCH
+# NUL does not pass through
+This will be seen.
+EOF
+
+M4PATH=$srcdir:$srcdir/other-tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/tests/other-tests/stackovf.test b/tests/other-tests/stackovf.test
new file mode 100755
index 00000000..699c5bef
--- /dev/null
+++ b/tests/other-tests/stackovf.test
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+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=/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
+)
+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/other-tests/sync-lines.m4 b/tests/other-tests/sync-lines.m4
new file mode 100644
index 00000000..7cad389d
--- /dev/null
+++ b/tests/other-tests/sync-lines.m4
@@ -0,0 +1,12 @@
+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
diff --git a/tests/other-tests/sync-lines.test b/tests/other-tests/sync-lines.test
new file mode 100755
index 00000000..c151f669
--- /dev/null
+++ b/tests/other-tests/sync-lines.test
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+# sync-lines.test is part of the GNU m4 testsuite
+
+. ${srcdir}/defs
+
+cat ${srcdir}/other-tests/sync-lines.m4 >in
+
+cat <<\EOF >ok
+#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.
+EOF
+
+M4PATH=$srcdir:$srcdir/other-tests $M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+$CMP -s out ok
diff --git a/tests/patsubst.1.test b/tests/patsubst.1.test
new file mode 100755
index 00000000..152d961d
--- /dev/null
+++ b/tests/patsubst.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# patsubst.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2984
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+patsubst(`GNUs not Unix', `^', `OBS: ')
+patsubst(`GNUs not Unix', `\<', `OBS: ')
+patsubst(`GNUs not Unix', `\w*', `(\&)')
+patsubst(`GNUs not Unix', `\w+', `(\&)')
+patsubst(`GNUs not Unix', `[A-Z][a-z]+')
+EOF
+
+cat <<\EOF >ok
+OBS: GNUs not Unix
+OBS: GNUs OBS: not OBS: Unix
+(GNUs)() (not)() (Unix)
+(GNUs) (not) (Unix)
+GN not
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/patsubst.2.test b/tests/patsubst.2.test
new file mode 100755
index 00000000..47ce0b77
--- /dev/null
+++ b/tests/patsubst.2.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# patsubst.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3001
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`upcase', `translit(`$*', `a-z', `A-Z')')dnl
+define(`downcase', `translit(`$*', `A-Z', `a-z')')dnl
+define(`capitalize1',
+ `regexp(`$1', `^\(\w\)\(\w*\)', `upcase(`\1')`'downcase(`\2')')')dnl
+define(`capitalize',
+ `patsubst(`$1', `\w+', `capitalize1(`\&')')')dnl
+capitalize(`GNUs not Unix')
+EOF
+
+cat <<\EOF >ok
+Gnus Not Unix
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/pseudoar.1.test b/tests/pseudoar.1.test
new file mode 100755
index 00000000..060af181
--- /dev/null
+++ b/tests/pseudoar.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# pseudoar.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1101
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`nargs', `$#')
+nargs
+nargs()
+nargs(arg1, arg2, arg3)
+EOF
+
+cat <<\EOF >ok
+
+0
+1
+3
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/pseudoar.2.test b/tests/pseudoar.2.test
new file mode 100755
index 00000000..765e73b2
--- /dev/null
+++ b/tests/pseudoar.2.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# pseudoar.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1115
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo', `$*')
+echo(arg1, arg2, arg3 , arg4)
+EOF
+
+cat <<\EOF >ok
+
+arg1,arg2,arg3 ,arg4
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/pseudoar.3.test b/tests/pseudoar.3.test
new file mode 100755
index 00000000..ef7bae06
--- /dev/null
+++ b/tests/pseudoar.3.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# pseudoar.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1126
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo', `$@')
+echo(arg1, arg2, arg3 , arg4)
+EOF
+
+cat <<\EOF >ok
+
+arg1,arg2,arg3 ,arg4
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/pseudoar.4.test b/tests/pseudoar.4.test
new file mode 100755
index 00000000..b95fade9
--- /dev/null
+++ b/tests/pseudoar.4.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# pseudoar.4.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1136
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`echo1', `$*')
+define(`echo2', `$@')
+define(`foo', `This is macro `foo'.')
+echo1(foo)
+echo2(foo)
+EOF
+
+cat <<\EOF >ok
+
+
+
+This is macro This is macro foo..
+This is macro foo.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/pseudoar.5.test b/tests/pseudoar.5.test
new file mode 100755
index 00000000..c739ef51
--- /dev/null
+++ b/tests/pseudoar.5.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# pseudoar.5.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1156
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `$$$ hello $$$')
+foo
+EOF
+
+cat <<\EOF >ok
+
+$$$ hello $$$
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/pushdef.1.test b/tests/pushdef.1.test
new file mode 100755
index 00000000..fecfa31a
--- /dev/null
+++ b/tests/pushdef.1.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# pushdef.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1295
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Expansion one.')
+foo
+pushdef(`foo', `Expansion two.')
+foo
+popdef(`foo')
+foo
+popdef(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Expansion one.
+
+Expansion two.
+
+Expansion one.
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/pushdef.2.test b/tests/pushdef.2.test
new file mode 100755
index 00000000..d391e5da
--- /dev/null
+++ b/tests/pushdef.2.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# pushdef.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1319
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Expansion one.')
+foo
+pushdef(`foo', `Expansion two.')
+foo
+define(`foo', `Second expansion two.')
+foo
+undefine(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+
+Expansion one.
+
+Expansion two.
+
+Second expansion two.
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/regexp.1.test b/tests/regexp.1.test
new file mode 100755
index 00000000..a83a2228
--- /dev/null
+++ b/tests/regexp.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# regexp.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2854
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+regexp(`GNUs not Unix', `\<[a-z]\w+')
+regexp(`GNUs not Unix', `\<Q\w*')
+EOF
+
+cat <<\EOF >ok
+5
+-1
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/regexp.2.test b/tests/regexp.2.test
new file mode 100755
index 00000000..6ed53dd8
--- /dev/null
+++ b/tests/regexp.2.test
@@ -0,0 +1,19 @@
+#!/bin/sh
+
+# regexp.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2866
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+regexp(`GNUs not Unix', `\w\(\w+\)$', `*** \& *** \1 ***')
+EOF
+
+cat <<\EOF >ok
+*** Unix *** nix ***
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/run-test b/tests/run-test
new file mode 100755
index 00000000..c5223163
--- /dev/null
+++ b/tests/run-test
@@ -0,0 +1,29 @@
+#!/bin/sh
+# Run a test manually
+# Copyright (C) 1998 Free Software Foundation, Inc.
+
+srcdir=.
+export srcdir
+
+if sh "$@"; then
+ echo "Test succeeded"
+else
+ echo "TEST FAILED"
+
+ if cmp testSubDir/ok testSubDir/out 2>/dev/null; then
+ :
+ else
+ echo "stdout mosmatch"
+ diff -c testSubDir/ok testSubDir/out
+ fi
+
+ msgerr=""
+ if test -e testSubDir/err; then
+ if cmp testSubDir/okerr testSubDir/err 2>/dev/null; then
+ :
+ else
+ echo "stderr mismatch"
+ diff -c testSubDir/okerr testSubDir/err
+ fi
+ fi
+fi
diff --git a/tests/stamp-TESTS b/tests/stamp-TESTS
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/tests/stamp-TESTS
diff --git a/tests/substr.1.test b/tests/substr.1.test
new file mode 100755
index 00000000..ebfc000f
--- /dev/null
+++ b/tests/substr.1.test
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+# substr.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2892
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+substr(`gnus, gnats, and armadillos', 6)
+substr(`gnus, gnats, and armadillos', 6, 5)
+EOF
+
+cat <<\EOF >ok
+gnats, and armadillos
+gnats
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/sysval.1.test b/tests/sysval.1.test
new file mode 100755
index 00000000..e79a0ef5
--- /dev/null
+++ b/tests/sysval.1.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# sysval.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 3347
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+syscmd(`false')
+ifelse(sysval, 0, zero, non-zero)
+syscmd(`true')
+sysval
+EOF
+
+cat <<\EOF >ok
+
+non-zero
+
+0
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/trace.1.test b/tests/trace.1.test
new file mode 100755
index 00000000..7d103f7f
--- /dev/null
+++ b/tests/trace.1.test
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+# trace.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1706
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`foo', `Hello World.')
+define(`echo', `$@')
+traceon(`foo', `echo')
+foo
+echo(gnus, and gnats)
+EOF
+
+cat <<\EOF >ok
+
+
+
+Hello World.
+gnus,and gnats
+EOF
+
+cat <<\EOF >okerr
+m4trace: -1- foo -> `Hello World.'
+m4trace: -1- echo(`gnus', `and gnats') -> ``gnus',`and gnats''
+EOF
+
+$M4 -d in >out 2>err
+sed -e "s, ../../src/m4:, m4:," err >sederr && mv sederr err
+
+$CMP -s out ok && $CMP -s err okerr
+
diff --git a/tests/translit.1.test b/tests/translit.1.test
new file mode 100755
index 00000000..51a4396a
--- /dev/null
+++ b/tests/translit.1.test
@@ -0,0 +1,23 @@
+#!/bin/sh
+
+# translit.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2933
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+translit(`GNUs not Unix', `A-Z')
+translit(`GNUs not Unix', `a-z', `A-Z')
+translit(`GNUs not Unix', `A-Z', `z-a')
+EOF
+
+cat <<\EOF >ok
+s not nix
+GNUS NOT UNIX
+tmfs not fnix
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/undefine.1.test b/tests/undefine.1.test
new file mode 100755
index 00000000..e2450f79
--- /dev/null
+++ b/tests/undefine.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# undefine.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 1187
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+foo
+define(`foo', `expansion text')
+foo
+undefine(`foo')
+foo
+EOF
+
+cat <<\EOF >ok
+foo
+
+expansion text
+
+foo
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/undivert.1.test b/tests/undivert.1.test
new file mode 100755
index 00000000..10c6625e
--- /dev/null
+++ b/tests/undivert.1.test
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+# undivert.1.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2632
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted.
+divert
+This text is not diverted.
+undivert(1)
+EOF
+
+cat <<\EOF >ok
+
+This text is not diverted.
+
+This text is diverted.
+
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/undivert.2.test b/tests/undivert.2.test
new file mode 100755
index 00000000..d49f7fc4
--- /dev/null
+++ b/tests/undivert.2.test
@@ -0,0 +1,29 @@
+#!/bin/sh
+
+# undivert.2.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2656
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+divert(1)
+This text is diverted first.
+divert(0)undivert(1)dnl
+undivert(1)
+divert(1)
+This text is also diverted but not appended.
+divert(0)undivert(1)dnl
+EOF
+
+cat <<\EOF >ok
+
+This text is diverted first.
+
+
+This text is also diverted but not appended.
+EOF
+
+$M4 -d in >out
+
+$CMP -s out ok
+
diff --git a/tests/undivert.3.test b/tests/undivert.3.test
new file mode 100755
index 00000000..146374d9
--- /dev/null
+++ b/tests/undivert.3.test
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# undivert.3.test is part of the GNU m4 testsuite
+# generated from example in ../doc/m4.texinfo line 2682
+
+. ${srcdir}/defs
+
+cat <<\EOF >in
+define(`bar', `BAR')
+undivert(`foo')
+include(`foo')
+EOF
+
+cat <<\EOF >ok
+
+bar
+
+BAR
+
+EOF
+
+M4PATH=$srcdir $M4 -d in >out
+
+$CMP -s out ok
+